PDA

View Full Version : Cannot reset Timer0 properly



Demon
- 15th April 2015, 21:42
I can't figure out what other flag I need to reset to use Timer0 a 2nd time.

7792

Timer0 works for 50mS on the first keypress of the upper left button on the keypad. But it keeps on going on the second keypress.


@ __CONFIG _CONFIG1L, _PLLDIV_5_1L & _CPUDIV_OSC1_PLL2_1L & _USBDIV_2_1L
@ __CONFIG _CONFIG1H, _FOSC_HSPLL_HS_1H
@ __CONFIG _CONFIG2L, _PWRT_OFF_2L & _BOR_ON_2L & _BORV_1_2L & _VREGEN_ON_2L
@ __CONFIG _CONFIG2H, _WDT_OFF_2H
@ __CONFIG _CONFIG3H, _CCP2MX_ON_3H & _PBADEN_OFF_3H & _LPT1OSC_OFF_3H & _MCLRE_ON_3H
@ __CONFIG _CONFIG4L, _STVREN_ON_4L & _LVP_OFF_4L & _ICPRT_OFF_4L & _XINST_OFF_4L

DEFINE OSC 48

ADCON1 = %00001111 ' A/D CONTROL REGISTER 1
' Bit 7-6 Unimplemented: Read as ‘0’
' Bit 5 VCFG1: Voltage Reference Configuration bit (VREF- source)
' 0 = VSS
' 1 = Vref- (AN2)
' Bit 4 VCFG0: Voltage Reference Configuration bit (VREF+ source)
' 0 = VSS
' 1 = Vref+ (AN3)
' Bit 3-0 PCFG3:PCFG0: A/D Port Configuration Control bits:
' 1111 = All digital
' 1110 = All digital, AN0 analog
' 1101 = All digital, AN0 & AN1 analog

INTCON2 = %00000000 ' INTERRUPT CONTROL REGISTER 2
' Bit 7 RBPU: PORTB Pull-up Enable bit
' 1 = All PORTB pull-ups are disabled
' 0 = PORTB pull-ups are enabled provided that the pin is an input
' and the corresponding WPUB bit is set.
' Bit 6 INTEDG0: External Interrupt 0 Edge Select bit
' 1 = Interrupt on rising edge
' 0 = Interrupt on falling edge
' Bit 5 INTEDG1: External Interrupt 1 Edge Select bit
' 1 = Interrupt on rising edge
' 0 = Interrupt on falling edge
' Bit 4 INTEDG2: External Interrupt 2 Edge Select bit
' 1 = Interrupt on rising edge
' 0 = Interrupt on falling edge
' Bit 3 Unimplemented: Read as ‘0’
' Bit 2 TMR0IP: TMR0 Overflow Interrupt Priority bit
' 1 = High priority
' 0 = Low priority
' Bit 1 Unimplemented: Read as ‘0’
' Bit 0 RBIP: RB Port Change Interrupt Priority bit
' 1 = High priority
' 0 = Low priority

T0CON = %10000011 ' TIMER0 CONTROL REGISTER
' Bit 7 TMR0ON: Timer0 On/Off Control bit
' 1 = Enables Timer0
' 0 = Stops Timer0
' Bit 6 T08BIT: Timer0 8-Bit/16-Bit Control bit
' 1 = Timer0 is configured as an 8-bit timer/counter
' 0 = Timer0 is configured as a 16-bit timer/counter
' Bit 5 T0CS: Timer0 Clock Source Select bit
' 1 = Transition on T0CKI pin
' 0 = Internal instruction cycle clock (CLKO)
' Bit 4 T0SE: Timer0 Source Edge Select bit
' 1 = Increment on high-to-low transition on T0CKI pin
' 0 = Increment on low-to-high transition on T0CKI pin
' Bit 3 PSA: Timer0 Prescaler Assignment bit
' 1 = Timer0 prescaler is NOT assigned. Timer0 clock input
' bypasses prescaler.
' 0 = Timer0 prescaler is assigned. Timer0 clock input comes from
' prescaler output.
' Bit 2-0 T0PS2:T0PS0: Timer0 Prescaler Select bits
' 111 = 1:256 Prescale value
' 110 = 1:128 Prescale value
' 101 = 1:64 Prescale value
' 100 = 1:32 Prescale value
' 011 = 1:16 Prescale value
' 010 = 1:8 Prescale value
' 001 = 1:4 Prescale value
' 000 = 1:2 Prescale value

INCLUDE "DT_INTS-18.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP-18.bas" ' Include if using PBP interrupts

ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR0_INT, _EndTimer, PBP, no
endm
INT_CREATE ; Creates the interrupt processor
ENDASM

TRISA = %00000000
TRISB = %11110000 ' Set columns to input, rows to output
TRISC = %00000000
TRISD = %00000000
TRISE = %00000000

TimerLed VAR PORTD.1

LOW TimerLed
GOTO Main

StartTimer:
TMR0H = 109 ' 50 mS Timer
TMR0L = 144
INTCON.2 = 0
HIGH TimerLed
@ INT_ENABLE TMR0_INT ; enable Timer 0 interrupts
RETURN

EndTimer:
LOW TimerLed
RETURN

KeypadInput:
PORTB = %00001110 ' Row 1
IF PORTB.4 = 0 THEN ' Column 1
GOSUB StartTimer
WHILE PORTB.4 = 0: WEND
ENDIF
RETURN

Main:
GOSUB KeypadInput ' Scan 4 x 4 keypad
' Future logic goes here.
GOTO Main
END

(my first attempt at resetting the interrupt flag myself)

Robert

PIC 18F4550
Lab X1 board
PBP v2.60c
MPASM v5.46

HenrikOlsson
- 15th April 2015, 22:01
Hi Robert,
I see two problems.
1) The interrupt service routine ends with a RETURN, it really needs to end with an @ INT_RETURN
2) In the interrupt "declaration" you have the Clear Flag option set to no so DT-INTS will not clear the flag. Are you saying that you want to do it yourself? In that case you need to do it in the interrupt service routine.

/Henrik.

Tabsoft
- 15th April 2015, 23:12
Right on Henrik.

I came up with the same items. Had just converted the code to work on my HW and was testing.
These suggested changes seem to work here on my setup Robert.

Demon
- 16th April 2015, 02:01
I hate outsmarting myself. I intentionally replaced that RETURN, argh...

I had also replaced the YES flag. I should have stepped away and taken a break, to take a different look at my code a few minutes later. I somehow thought more was going on and had to handle the flag myself, I obviously didn't. The interrupt won't take off again unless I call Start.


@ __CONFIG _CONFIG1L, _PLLDIV_5_1L & _CPUDIV_OSC1_PLL2_1L & _USBDIV_2_1L
@ __CONFIG _CONFIG1H, _FOSC_HSPLL_HS_1H
@ __CONFIG _CONFIG2L, _PWRT_OFF_2L & _BOR_ON_2L & _BORV_1_2L & _VREGEN_ON_2L
@ __CONFIG _CONFIG2H, _WDT_OFF_2H
@ __CONFIG _CONFIG3H, _CCP2MX_ON_3H & _PBADEN_OFF_3H & _LPT1OSC_OFF_3H & _MCLRE_ON_3H
@ __CONFIG _CONFIG4L, _STVREN_ON_4L & _LVP_OFF_4L & _ICPRT_OFF_4L & _XINST_OFF_4L

DEFINE OSC 48

ADCON1 = %00001111 ' A/D CONTROL REGISTER 1
' Bit 7-6 Unimplemented: Read as ‘0’
' Bit 5 VCFG1: Voltage Reference Configuration bit (VREF- source)
' 0 = VSS
' 1 = Vref- (AN2)
' Bit 4 VCFG0: Voltage Reference Configuration bit (VREF+ source)
' 0 = VSS
' 1 = Vref+ (AN3)
' Bit 3-0 PCFG3:PCFG0: A/D Port Configuration Control bits:
' 1111 = All digital
' 1110 = All digital, AN0 analog
' 1101 = All digital, AN0 & AN1 analog

INTCON2 = %00000000 ' INTERRUPT CONTROL REGISTER 2
' Bit 7 RBPU: PORTB Pull-up Enable bit
' 1 = All PORTB pull-ups are disabled
' 0 = PORTB pull-ups are enabled provided that the pin is an input
' and the corresponding WPUB bit is set.
' Bit 6 INTEDG0: External Interrupt 0 Edge Select bit
' 1 = Interrupt on rising edge
' 0 = Interrupt on falling edge
' Bit 5 INTEDG1: External Interrupt 1 Edge Select bit
' 1 = Interrupt on rising edge
' 0 = Interrupt on falling edge
' Bit 4 INTEDG2: External Interrupt 2 Edge Select bit
' 1 = Interrupt on rising edge
' 0 = Interrupt on falling edge
' Bit 3 Unimplemented: Read as ‘0’
' Bit 2 TMR0IP: TMR0 Overflow Interrupt Priority bit
' 1 = High priority
' 0 = Low priority
' Bit 1 Unimplemented: Read as ‘0’
' Bit 0 RBIP: RB Port Change Interrupt Priority bit
' 1 = High priority
' 0 = Low priority

T0CON = %10000011 ' TIMER0 CONTROL REGISTER
' Bit 7 TMR0ON: Timer0 On/Off Control bit
' 1 = Enables Timer0
' 0 = Stops Timer0
' Bit 6 T08BIT: Timer0 8-Bit/16-Bit Control bit
' 1 = Timer0 is configured as an 8-bit timer/counter
' 0 = Timer0 is configured as a 16-bit timer/counter
' Bit 5 T0CS: Timer0 Clock Source Select bit
' 1 = Transition on T0CKI pin
' 0 = Internal instruction cycle clock (CLKO)
' Bit 4 T0SE: Timer0 Source Edge Select bit
' 1 = Increment on high-to-low transition on T0CKI pin
' 0 = Increment on low-to-high transition on T0CKI pin
' Bit 3 PSA: Timer0 Prescaler Assignment bit
' 1 = Timer0 prescaler is NOT assigned. Timer0 clock input
' bypasses prescaler.
' 0 = Timer0 prescaler is assigned. Timer0 clock input comes from
' prescaler output.
' Bit 2-0 T0PS2:T0PS0: Timer0 Prescaler Select bits
' 111 = 1:256 Prescale value
' 110 = 1:128 Prescale value
' 101 = 1:64 Prescale value
' 100 = 1:32 Prescale value
' 011 = 1:16 Prescale value
' 010 = 1:8 Prescale value
' 001 = 1:4 Prescale value
' 000 = 1:2 Prescale value

INCLUDE "DT_INTS-18.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP-18.bas" ' Include if using PBP interrupts

ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR0_INT, _EndTimer, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM

TRISA = %00000000
TRISB = %11110000 ' Set columns to input, rows to output
TRISC = %00000000
TRISD = %00000000
TRISE = %00000000

TimerLed VAR PORTD.1

LOW TimerLed
GOTO Main

StartTimer:
TMR0H = 109 ' 50 mS Timer
TMR0L = 144
HIGH TimerLed
@ INT_ENABLE TMR0_INT ; enable Timer 0 interrupts
RETURN

EndTimer:
LOW TimerLed
@ INT_RETURN

KeypadInput:
PORTB = %00001110 ' Row 1
IF PORTB.4 = 0 THEN ' Column 1
GOSUB StartTimer
WHILE PORTB.4 = 0: WEND
ENDIF
RETURN

Main:
GOSUB KeypadInput ' Scan 4 x 4 keypad
' Future logic goes here.
GOTO Main
END

7793

Eeesh, thanks guys! It works perfectly now.

Robert