fpeixeiro
- 12th April 2014, 20:58
Hello everybody.
I'm very new to pic, beeing learning for almoast one year on my own.
I've been reading some time for a tachometer, and all i've found is info about tacho's for high speed.
I'm trying to make a tacho for 20 to 60 rpm. I gathered the hardware, it's based on the 16f628a, 4mhz crystal and three 7 seg display common anode.
I'm doing this so i can be shure that a line of 7 conveyors are in sync, at 36 rpm. I need to be shure that the conveyors are running at 36 rpm, not 35,5 or 36,5. So i added three 7seg display to do the decimals.
The rpm are checked by means of an ir emiter/receiver.
I've made a circuit based on a counter from the book "PIC Basic Projects 30 Projects using PIC BASIC and PIC BASIC PRO", "Dual 7-segment LED event counter".
The code is being simulated on proteus and it says that the pic is under excessive load, and it doesn't work.
The code:
' DEFINITIONS
RPM VAR WORD ' RPM is a word variable
Digit VAR Byte ' Digit is a byte variable
Pattern VAR Byte ' Pattern is a byte variable
Digit1 VAR PORTA.1 ' Digit 1 enable bit
Digit2 VAR PORTA.2 ' Digit 2 enable bit
Digit3 VAR PORTA.3 ' Digit 3 enable bit
Counter VAR WORD ' Variable
TMPlowbyte var byte ' TMP word variable for timer1
TMR1Overflow var byte ' TMR1 Overflow counter
i var byte ' Variable
' START OF MAIN PROGRAM
CMCON = 7 ' RA0-RA3 are digital I/O
TRISA = 0 ' Set PORTA as output
TRISB = $80 ' Bit 7 of PORTB input, others outputs
TMR1Overflow = 0 ' Reset TMR1 Overflow counter
RPM = 0 ' Variable reset
i = 0 ' Variable reset
' Enable TMR0 timer interrupts
INTCON = 100000 ' Enable TMR0 interrupts
OPTION_REG = 000111 ' Initialise the prescale
TMR0 = 217 ' Load TMR0 register
' Enable TMR1
T1CON = 111101 ' bit0 = TMR1 on
' bit1 = TMR1CS Internal Clock
' bit2 = T1SYNC = 1
' bit3 = T1OSCEN = 1
' bit4-5 = 11 = 1:8 Prescale value
ON INTERRUPT GOTO ISR
INTCON = 100000 ' Enable Interrupts
MLOOP:
BUTTON PORTA.7, 0, 255,0,i, 0, MLOOP ' Wait until push-button is pressed and debounce switch
TMPlowbyte = TMR1L ' Saves value of TMR1
If PIR1.0 = 1 Then ' Checks TMR1 OIF bit and
TMR1Overflow = TMR1Overflow + 1 ' increments if TMR1 overflows
ENDIF
Counter = TMR1Overflow + TMPLowbyte
RPM = 60 / Counter
GOTO MLOOP
' This is the Interrupt Service Routine (ISR). The program jumps to
' this routine whenever a timer interrupt is generated. Inside this
' routine the value of variable RPM is displayed.
DISABLE ' Disable further interrupts
ISR:
TMR0 = 217
Digit = RPM DIG 2 ' Get 100s digit
LOOKUP Digit, [$3F, $06, $5B, $4F, $66, $6D, $7D, $07, $7F, $6F], Pattern
Pattern = Pattern ^ $FF ' Invert bits of variable Pattern
' Use with Comon Anode Display
Digit3 = 0 ' Disable digit 3
Digit2 = 0 ' Disable digit 2
PORTB = Pattern ' Display 100s digit
Digit1 = 1 ' Enable digit 1
Pause 1 ' Wait 2ms
Digit = RPM DIG 1 ' Get 10s digit
LOOKUP Digit, [$3F, $06, $5B, $4F, $66, $6D, $7D, $07, $7F, $6F], Pattern
Pattern = Pattern ^ $FF ' Invert bits of variable Pattern
Digit3 = 0 ' Disable digit 3
Digit1 = 0 ' Disable digit 1
PORTB = Pattern ' Display 10s digit
Digit2 = 1 ' Enable digit 2
Pause 1 ' Wait 2ms
Digit = RPM DIG 0 ' Get 1s digit
LOOKUP Digit, [$3F, $06, $5B, $4F, $66, $6D, $7D, $07, $7F, $6F], Pattern
Pattern = Pattern ^ $FF ' Invert bits of variable Pattern
Digit1 = 0 ' Disable digit 1
Digit2 = 0 ' Disable digit 2
PORTB = Pattern ' Display 1s digit
Digit3 = 1 ' Enable digit 3
PAUSE 1 ' Wait 2ms
INTCON.2 = 0 ' Re-enable TMR0 interrupts
RESUME ' Return to main program
ENABLE ' Enable interrupts
TMPlowbyte = 0 ' Variable reset
PIR1.0=0 ' Reset TMR1's Interupt Flag
TMR1Overflow = 0 ' Reset TMR1 Overflow counter
END ' End of program
What's wrong?
I know this is very complicated, but any help is very god.
Thanks.
I'm very new to pic, beeing learning for almoast one year on my own.
I've been reading some time for a tachometer, and all i've found is info about tacho's for high speed.
I'm trying to make a tacho for 20 to 60 rpm. I gathered the hardware, it's based on the 16f628a, 4mhz crystal and three 7 seg display common anode.
I'm doing this so i can be shure that a line of 7 conveyors are in sync, at 36 rpm. I need to be shure that the conveyors are running at 36 rpm, not 35,5 or 36,5. So i added three 7seg display to do the decimals.
The rpm are checked by means of an ir emiter/receiver.
I've made a circuit based on a counter from the book "PIC Basic Projects 30 Projects using PIC BASIC and PIC BASIC PRO", "Dual 7-segment LED event counter".
The code is being simulated on proteus and it says that the pic is under excessive load, and it doesn't work.
The code:
' DEFINITIONS
RPM VAR WORD ' RPM is a word variable
Digit VAR Byte ' Digit is a byte variable
Pattern VAR Byte ' Pattern is a byte variable
Digit1 VAR PORTA.1 ' Digit 1 enable bit
Digit2 VAR PORTA.2 ' Digit 2 enable bit
Digit3 VAR PORTA.3 ' Digit 3 enable bit
Counter VAR WORD ' Variable
TMPlowbyte var byte ' TMP word variable for timer1
TMR1Overflow var byte ' TMR1 Overflow counter
i var byte ' Variable
' START OF MAIN PROGRAM
CMCON = 7 ' RA0-RA3 are digital I/O
TRISA = 0 ' Set PORTA as output
TRISB = $80 ' Bit 7 of PORTB input, others outputs
TMR1Overflow = 0 ' Reset TMR1 Overflow counter
RPM = 0 ' Variable reset
i = 0 ' Variable reset
' Enable TMR0 timer interrupts
INTCON = 100000 ' Enable TMR0 interrupts
OPTION_REG = 000111 ' Initialise the prescale
TMR0 = 217 ' Load TMR0 register
' Enable TMR1
T1CON = 111101 ' bit0 = TMR1 on
' bit1 = TMR1CS Internal Clock
' bit2 = T1SYNC = 1
' bit3 = T1OSCEN = 1
' bit4-5 = 11 = 1:8 Prescale value
ON INTERRUPT GOTO ISR
INTCON = 100000 ' Enable Interrupts
MLOOP:
BUTTON PORTA.7, 0, 255,0,i, 0, MLOOP ' Wait until push-button is pressed and debounce switch
TMPlowbyte = TMR1L ' Saves value of TMR1
If PIR1.0 = 1 Then ' Checks TMR1 OIF bit and
TMR1Overflow = TMR1Overflow + 1 ' increments if TMR1 overflows
ENDIF
Counter = TMR1Overflow + TMPLowbyte
RPM = 60 / Counter
GOTO MLOOP
' This is the Interrupt Service Routine (ISR). The program jumps to
' this routine whenever a timer interrupt is generated. Inside this
' routine the value of variable RPM is displayed.
DISABLE ' Disable further interrupts
ISR:
TMR0 = 217
Digit = RPM DIG 2 ' Get 100s digit
LOOKUP Digit, [$3F, $06, $5B, $4F, $66, $6D, $7D, $07, $7F, $6F], Pattern
Pattern = Pattern ^ $FF ' Invert bits of variable Pattern
' Use with Comon Anode Display
Digit3 = 0 ' Disable digit 3
Digit2 = 0 ' Disable digit 2
PORTB = Pattern ' Display 100s digit
Digit1 = 1 ' Enable digit 1
Pause 1 ' Wait 2ms
Digit = RPM DIG 1 ' Get 10s digit
LOOKUP Digit, [$3F, $06, $5B, $4F, $66, $6D, $7D, $07, $7F, $6F], Pattern
Pattern = Pattern ^ $FF ' Invert bits of variable Pattern
Digit3 = 0 ' Disable digit 3
Digit1 = 0 ' Disable digit 1
PORTB = Pattern ' Display 10s digit
Digit2 = 1 ' Enable digit 2
Pause 1 ' Wait 2ms
Digit = RPM DIG 0 ' Get 1s digit
LOOKUP Digit, [$3F, $06, $5B, $4F, $66, $6D, $7D, $07, $7F, $6F], Pattern
Pattern = Pattern ^ $FF ' Invert bits of variable Pattern
Digit1 = 0 ' Disable digit 1
Digit2 = 0 ' Disable digit 2
PORTB = Pattern ' Display 1s digit
Digit3 = 1 ' Enable digit 3
PAUSE 1 ' Wait 2ms
INTCON.2 = 0 ' Re-enable TMR0 interrupts
RESUME ' Return to main program
ENABLE ' Enable interrupts
TMPlowbyte = 0 ' Variable reset
PIR1.0=0 ' Reset TMR1's Interupt Flag
TMR1Overflow = 0 ' Reset TMR1 Overflow counter
END ' End of program
What's wrong?
I know this is very complicated, but any help is very god.
Thanks.