PDA

View Full Version : Microcode studio - PIC16F877A Interrupts



mcbeasleyjr
- 3rd January 2009, 17:23
Hello. I am trying to learn how to use the timer interrupts on the PIC16F877A. I have never used the timer registers before so I may be doing something wrong. I've searched the internet trying to find examples to go by and I've come up with a small program. It compiles in my software but when it is programmed to the PIC it won't display my variables on the LCD. Here is the code that I have so far:

DEFINE OSC 20 ' Define 20MHz Oscillator
DEFINE LCD_DREG PORTB ' Set LCD Data port
DEFINE LCD_DBIT 4 ' Set starting Data bit (0 or 4) if 4-bit bus
DEFINE LCD_RSREG PORTB ' Set LCD Register Select port
DEFINE LCD_RSBIT 3 ' Set LCD Register Select bit
DEFINE LCD_EREG PORTB ' Set LCD Enable port
DEFINE LCD_EBIT 2 ' Set LCD Enable bit
DEFINE LCD_BITS 4 ' Set LCD bus size (4 or 8 bits)
DEFINE LCD_LINES 4 ' Set number of lines on LCD
DEFINE LCD_COMMANDUS 2000 ' Set command delay time in us
DEFINE LCD_DATAUS 50 ' Set data delay time in us
PAUSE 1000 ' Pause for one second for power stabilization

mS VAR WORD
S VAR WORD
Timer1 VAR WORD

SYMBOL GIE = INTCON.7 'Global Interrupt Enable bit
SYMBOL TMR1_Val = 65535 'Set the initial value of TMR1
SYMBOL TMR1_mS = 1 'Time period of TMR1
SYMBOL TMR1_Enable = PIE1.0 'TMR1 interrup enable
SYMBOL TMR1_Overflow = PIR1.0 'TMR1 overflow flag

ON INTERRUPT GOTO INTERRUPT_HANDLER 'Goto handler on interrupt

DISABLE INTERRUPT
MAIN:
GOTO INITIALIZE
REPEAT
UNTIL S = 60
S = 0
INTCON = $80 'Permanently disables interrupts until called again
GOTO MAIN 'Loop forever
ENABLE INTERRUPT

INITIALIZE:
'TMR1 Interrupt Operation
GIE = 0
TMR1_Enable = 0 'Disables TMR1 Interrupt
INTCON.6 = 1 'Peripheral Interrupts
T1CON.1 = 0 '1 = External clock input from pin RC0
'0 = Internal clock (FOSC/4)
'TRISC.0 = 1 'If external clock, set clock as an input
'HPWM 1, 128, 32000 'Set TMR1's external source
T1CON.2 = 1 '1 = Do not synchronize external clock input
'0 = Synchronize external clock input
T1CON.4 = 0 '11 = 1:8 Prescale value
T1CON.5 = 0 '10 = 1:4 Prescale value
'01 = 1:2 Prescale value
'00 = 1:1 Prescale value
'When T1CON.1 = 0 this bit is ignored.
'TMR1 uses the internal clock when TMR1CS = 0.
Timer1 = TMR1_Val '
TMR1_Enable = 1 '
T1CON.0 = 1 '
RETURN

DISABLE INTERRUPT 'Disables interrupts in handler
INTERRUPT_HANDLER:
GIE = 0 'Disable Global interrupts
IF (TMR1_Overflow = 1 && TMR1_Enable = 1) THEN
TMR1_Enable = 0
Timer1 = Timer1 + TMR1_Val
Timer1.LowByte = TMR1L
Timer1.HighByte = TMR1H
TMR1_Enable = 1
TMR1_Overflow = 0
ms = ms + TMR1_mS
IF (mS >= 1000) THEN
mS = mS - 1000
S = S + 1
ENDIF
ENDIF
LCDOUT $FE, 1 ' Clear display
LCDOUT $FE, 2 ' Return home (beginning of first line)
LCDOUT $FE, $0C ' Cursor Off
LCDOUT " ", DEC S, " S ", DEC mS, " mS" ' display elapsed time
RESUME 'Return to main program
ENABLE INTERRUPT 'Enable interrupts after handler
END

Anyone that could help me out with this I would greatly appreciate it. Thank you all in advance.

Pic2008
- 8th January 2009, 06:10
Your timer interrupt won't work if you disable global interrupt. Try changing to the below code to see if something is displayed first:


DISABLE INTERRUPT
GOTO INITIALIZE
ENABLE INTERRUPT

MAIN:

GOTO MAIN 'Loop forever