![]() | ![]() | ![]() |
| |||||||
| Micro Controllers Discuss all aspects of micro controllers - building them, coding them, etc. All controllers are welcome - PIC, BASIC, Z8 Encore!, etc. |
![]() |
| | Tools |
| | #1 |
|
I am using 18F452 I tried to experiment with timer0... I set a prescale factor and was generating interrupts. For each interrupt, I was incrementing a variable whih was in the watch. However when I set precale 1:2 and prescale 1:4, the simulator did not generate any interrupts... I looked for all possible typo errors etc.. But It just does not make sense. If I just change one bit in the T0CON, >>TOPS0,TOPS1,TOPS2, The programme works... Has anyone ever faced such a problem... Please help me out... MACRO.INC Code: timer0.enable MACRO bsf T0CON,TMR0ON ;Sets bit7 of the T0CON register ENDM timer0.disable MACRO bcf T0CON,TMR0ON ;Clears bit7 of the T0CON register ENDM ;Macro to set timer0 to 8bit / 16bits. timer0.8Bits MACRO bsf T0CON,T08BIT ;Sets bit6 of the T0CON register ENDM timer0.16Bits MACRO bcf T0CON,T08BIT ;Clears bit6 of the T0CON register ENDM ;Macro to select the timer0 clock source timer0.counter MACRO bsf T0CON,T0CS ;Sets the bit5 of the T0CON register ENDM timer0.timer MACRO bcf T0CON,T0CS ;Clears the bit5 of the T0CON register ENDM ;Macro to select the timer0 Clock edge timer0.pTriggered MACRO bsf T0CON,T0SE ;Sets the bit4 of the T0CON register ENDM timer0.nTriggered MACRO bcf T0CON,T0SE ;Clears the bit4 of the T0CON register ENDM ;Macro to set the timer0 prescalers timer0.prescale1 MACRO bsf T0CON,PSA ;Sets the bit3 of the T0CON register ENDM timer0.prescale2 MACRO ;Prescale 1:2 bcf T0CON,PSA ;Sets the bit3 of the T0CON register bsf T0CON,T0PS0 bsf T0CON,T0PS1 bcf T0CON,T0PS2 ENDM timer0.prescale4 MACRO ;Prescale 1:4 bcf T0CON,PSA ;Sets the bit3 of the T0CON register bsf T0CON,T0PS0 bcf T0CON,T0PS1 bcf T0CON,T0PS2 ENDM timer0.prescale8 MACRO ;Prescale 1:8 bcf T0CON,PSA ;Sets the bit3 of the T0CON register bcf T0CON,T0PS0 bsf T0CON,T0PS1 bcf T0CON,T0PS2 ENDM timer0.prescale16 MACRO ;Prescale 1:16 bcf T0CON,PSA ;Sets the bit3 of the T0CON register bsf T0CON,T0PS0 bsf T0CON,T0PS1 bcf T0CON,T0PS2 ENDM timer0.prescale32 MACRO ;Prescale 1:32 bcf T0CON,PSA ;Sets the bit3 of the T0CON register bcf T0CON,T0PS0 bcf T0CON,T0PS1 bsf T0CON,T0PS2 ENDM timer0.prescale64 MACRO ;Prescale 1:64 bcf T0CON,PSA ;Sets the bit3 of the T0CON register bsf T0CON,T0PS0 bcf T0CON,T0PS1 bsf T0CON,T0PS2 ENDM timer0.prescale128 MACRO ;Prescale 1:128 bcf T0CON,PSA ;Sets the bit3 of the T0CON register bcf T0CON,T0PS0 bsf T0CON,T0PS1 bsf T0CON,T0PS2 ENDM timer0.prescale256 MACRO ;Prescale 1:256 bcf T0CON,PSA ;Sets the bit3 of the T0CON register bsf T0CON,T0PS0 bsf T0CON,T0PS1 bsf T0CON,T0PS2 ENDM ;Macros to configure interrupts timer0.highPriority MACRO ;Set timer0 interrupt priority high bsf INTCON2,TMR0IP ENDM timer0.lowPriority MACRO ;Set timer0 interrupt priority low bcf INTCON2,TMR0IP ENDM timer0.interruptEnable MACRO bsf INTCON,TMR0IE ;Enables the timer0 interrupt. ENDM timer0.interruptDisable MACRO bcf INTCON,TMR0IE ;Disables the timer0 interrupt. ENDM timer0.clearInterruptFlag MACRO ;clears the timer0 interrupt flag bcf INTCON,TMR0IF ENDM ;Macro to check if interrupt has occured. timer0.ifInterrupt MACRO tmrservice ;Check Timer0 overflow btfsc INTCON,TMR0IF goto tmrservice ENDM MAIN.ASM Code: #include "p18f452.inc" #include "defs.inc" #include "macros.inc" ;Define Xtal Xtal EQU 8000000 PLL=FALSE ;Compute the clock time period IF PLL @clock_period SET 1/Xtal ELSE clock_period SET 4/Xtal ENDIF ;Declare Global Variables global terminate,test1,test2,test ;Get external labels extern delay, highPriorityInterrupt, lowPriorityInterrupt ;Allocate memory to variables mainData udata var1 res 1 tempData udata_ovr w_shadow res 1 test1 res 1 test2 res 1 test res 1 ;Interrupt Vectors resetV CODE 0X0000 ;Interrupt Vector goto main ;Goto mainroutine highInterV CODE 0x0008 ;High Priority Interrupt Vector goto highPriorityInterrupt lowInterV CODE 0x0018 ;Low Priority Interrupt Vector goto lowPriorityInterrupt ;Main routine mainCode CODE ;The main code. main: ;Initialize Interrupts interrupts.globalEnable interrupts.priorityEnable interrupts.peripheralEnable timer0.interruptEnable timer0.highPriority timer1.interruptEnable timer1.highPriority ;Initialize Timers timer0.timer timer0.8Bits timer0.prescale4 timer0.enable ;timer1.timer ;timer1.8Bits ;timer1.prescale8 ;timer1.disable movlw 0x01 movwf test1 movwf test2 movwf test terminate: bra terminate END Code: #include "p18f452.inc" #include "macros.inc" ;Declare labels global global delay, highPriorityInterrupt, lowPriorityInterrupt ;get labels from other files extern terminate,test1,test2,test ;Define Variables subData udata delayCount res 1 pwmDuty res 1 timeTicks res 1 ;Subroutine Code. subroutine CODE ;Interrupt Service Routines highPriorityInterrupt: incf test timer0.ifInterrupt masterTimer ;timer1.ifInterrupt timer1int retfie lowPriorityInterrupt: retfie ;This is a subroutine to create a delay. delay: movwf delayCount delayLoop: decfsz delayCount bra delayLoop return 1 ;Subroutine to handle hardware timer interrupts. hwtimer: return 1 masterTimer: nop timer0.clearInterruptFlag incf test1 retfie timer1int: nop timer1.clearInterruptFlag incf test2 retfie END
__________________ Bharath Bhushan Lohray. M.Sc. Electronics. | |
| |
| | #2 |
|
I am not 100% sure on this, and I havn't looked at the 18F452 datasheet, but setting the prescaler bits one at a time is a highly questionable practice. It puts a sequence of different values into the prrescaler, not all of which may be legal. I think it would better to write T0CON with a constant and save the bit operations for the RUN bit. It might also be a good idea to stop the timer before configuring it. In the PIC 16F series I seem to remeber a specific procedure for switching the prescaler assignment between Timer0 and the Watchdog Timer. Can you find a similar mention in the 18F452 datasheet? Last edited by Papabravo; 16th May 2006 at 04:01 AM. | |
| |
| | #3 |
|
I am enabling the timer only after I have set the prescalar... I I see no reliable way to set the bits of T0CON without doing it a bit at a time... T0CON has other bits used for different putposes... So I will have to read T0CON mask bits that I am not interested in, write bits that I need and write the T0CON back... This shall take far more machine cycles than doing it a bit at a time... Anyway, how are illegal combinations developed? I do not see such a thing in the watch window. Moreover, I am using the bit names defined in the p18f452.inc file...
__________________ Bharath Bhushan Lohray. M.Sc. Electronics. | |
| |
| | #4 |
|
The basic idea is that you decide the value you want for all of the bits at one time and you write that value. There is no requirement that the bits be set or cleared one at a time, nor is there a requirement that the existing values of the bits be preserved at every stage of the operation. I see nothing unreliable about that process. Your original post said that there was something wrong; I took a guess that maybe the sequence of read-modify-write instructions was causing a problem. If that is not the case then we must look elsewhere. Let me consult the datasheet. Edit: It seems that PSA can be changed on the fly in this series without the precautions required in the 16F series, because the Timer0 prescaler is not associated with the watchdog timer. Edit: I still think that TMR0ON is the only bit that should be manipulated with bsf/bcf instructions. Last edited by Papabravo; 16th May 2006 at 04:16 AM. | |
| |
| | #5 |
|
I rewrote the code for debugging... I stripped down all macros and made a 1 file programme Code: include "p18f452.inc"
maindata udata
test1 res 1
resetV CODE 0X0000 ;Interrupt Vector
goto main ;Goto mainroutine
highInterV CODE 0x0008 ;High Priority Interrupt Vector
goto highPriorityInterrupt
lowInterV CODE 0x0018 ;Low Priority Interrupt Vector
goto lowPriorityInterrupt
;Main routine
mainCode CODE ;The main code.
main: ;Initialize Interrupts
bsf RCON,IPEN ;Interrupt enable bit of Reset Control
bsf INTCON,GIE
bsf INTCON,PEIE
bsf T0CON,T08BIT ;Sets bit6 of the T0CON register
bcf T0CON,T0CS ;Clears the bit5 of the T0CON register
bcf T0CON,PSA ;Sets the bit3 of the T0CON register
bcf T0CON,T0PS0 ;prescale bits.
bcf T0CON,T0PS1
bcf T0CON,T0PS2
bsf INTCON2,TMR0IP
bsf INTCON,TMR0IE ;Enables the timer0 interrupt.
bsf T0CON,TMR0ON ;Sets bit7 of the T0CON register
terminate: goto terminate
highPriorityInterrupt:
btfsc INTCON,TMR0IF
goto tmrservice
retfie
lowPriorityInterrupt:
retfie
tmrservice:
bcf INTCON,TMR0IF
incf test1
retfie
END
And the problem persists...
__________________ Bharath Bhushan Lohray. M.Sc. Electronics. | |
| |
| | #6 |
|
How do you know that interrupts are not occurring? Although the interrupt service is incrementing a counter, I don't see in your code a means to check their value externally. You may be omitting critical code that is causing this bug. BTW, you are not saving/restoring context during interrupt service. This may be a source of your bug. The simplest way to restore context during high priority interrupt service is to use "retfie fast".
__________________ "Having to do with Motion Control" | |
| |
| | #7 |
|
I tried "retfie FAST" it makes no difference. I know that the interrupts are not occuring as I am watching the TMR0 register and there is no count increment when I give prescale 1:2 and 1:4 however there is increment for all other values of prescaling including 1:1 I had to make the update of the watch window realtime in Debugger>Settings...>Real time/Update tab.
__________________ Bharath Bhushan Lohray. M.Sc. Electronics. | |
| |
| | #8 |
|
debug code Code: include "p18f452.inc" maindata udata test1 res 1 resetV CODE 0X0000 ;Interrupt Vector goto main ;Goto mainroutine highInterV CODE 0x0008 ;High Priority Interrupt Vector goto highPriorityInterrupt lowInterV CODE 0x0018 ;Low Priority Interrupt Vector goto lowPriorityInterrupt ;Main routine mainCode CODE ;The main code. main: ;Initialize Interrupts bsf RCON,IPEN ;Interrupt enable bit of Reset Control bsf INTCON,GIE bsf INTCON,PEIE clrf LATE movlw 0x07 movwf ADCON1 movlw b'0000000' movwf TRISE bsf T0CON,T08BIT ;Sets bit6 of the T0CON register bcf T0CON,T0CS ;Clears the bit5 of the T0CON register bcf T0CON,PSA ;Sets the bit3 of the T0CON register bcf T0CON,T0PS0 ;prescaling bits bcf T0CON,T0PS1 ;prescaling bits bcf T0CON,T0PS2 ;prescaling bits bsf INTCON2,TMR0IP bsf INTCON,TMR0IE ;Enables the timer0 interrupt. bsf T0CON,TMR0ON ;Sets bit7 of the T0CON register terminate: goto terminate highPriorityInterrupt: btfsc INTCON,TMR0IF goto tmrservice retfie FAST lowPriorityInterrupt: retfie tmrservice: bcf INTCON,TMR0IF incf test1 movff test1,LATE retfie FAST END Or a mistake made by me? Can anyone help me figure this out?
__________________ Bharath Bhushan Lohray. M.Sc. Electronics. | |
| |
| | #9 |
|
try enabling the IPEN bit in the INTCON register
| |
| |
| | #10 |
| I hope the OP hasn't been waiting 17 months for that pearl!
__________________ We never have time to do it right; but we always have time to do it over. | |
| |
| | #11 |
|
hahaha.. yeh, my bad.. didn't look at the date.. and ja ipen in the rcon.haha short and sweet and so far off!! | |
| |
|
| Tags |
| prescale, timer0 |
| Thread Tools | |
| Display Modes | |
| |