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.
Bookmarks