View previous topic :: View next topic |
Author |
Message |
Guest
|
Reloading Timer's in a safe mode... |
Posted: Fri Jan 16, 2009 6:04 am |
|
|
Hi
Some Q. about Reloading Timer's.
I use Timer1 connected to a Encoder. The setup is then CLK from External input, and configure as 16 bit!
When reloading the TMR1L & TMT1H I use the command set_timer1(...)
In the interrupt unit it is "safe".
Code: | #INT_Timer1
void Timer1_int(){
set_timer1(0xffff-bitprmm);
Sys.Mesure=1;
Sys.PrintInfo=1;
} |
But if I want to reload the Timer1 set_timer1() outside the interrupt, I remember something about it's not "safe", is it right?
Code: | void ReloadTimer1(){
clear_interrupt(INT_TIMER1);
set_timer1(0xffff-bitprmm);
enable_interrupts(INT_TIMER1);
} |
Ant hints about reloading in safe mode? |
|
|
RLScott
Joined: 10 Jul 2007 Posts: 465
|
Re: Reloading Timer's in a safe mode... |
Posted: Fri Jan 16, 2009 6:47 am |
|
|
The problem is that it takes several instructions to load the timer - it has to be done 8 bits at a time. set_timer1() does this. But if the timer gets an external clock just as you are loading it, the timer might count between the loading of the two bytes. For example, suppose you were trying to load the timer with 0x23FF and you loaded the low byte first:
FF -> TMR1L TIMER1=xxFF
!count! TIMER1 = yy00
23 -> TMR1H TIMER1 = 2300
The final 0x2300 is very far from 0x23FF or 0x2400. I don't know if set_timer1() loads the high byte or the low byte first, but either way, it is possible to get this problem. And disabling interrupts around it does not help at all because the interrupt is not the problem. Clocking the timer is the problem, and that will happen whether the interrupts are enabled or not. One solution is to turn off the timer to prevent clocking during the load, and maybe set_timer1() does this too, I don't know.
The only reason it might be "safer" to load the timer in the Timer 1 interrupt routine is that the interrupt is called right after a Timer 1 clock, so hopefully there will be some time before another clock can come in. _________________ Robert Scott
Real-Time Specialties
Embedded Systems Consulting |
|
|
Guest
|
|
Posted: Fri Jan 16, 2009 7:04 am |
|
|
Hi
Thanks for feedback.
I just face that, and disabling the timer can be the solution.
#bit TMR1ON = 0xFCD.0
TMR1ON=0 -> stop.
I can see the rollover problem at reload will make problem for me:-(
Must make some test... |
|
|
Ken Johnson
Joined: 23 Mar 2006 Posts: 197 Location: Lewisburg, WV
|
|
Posted: Fri Jan 16, 2009 8:56 am |
|
|
Which PIC ?
I just checked the data sheet for the 18F4520 (Sec 12.2: Timer1 16-Bit Read/Write Mode).
On this processor, the hardware takes care of this for you (I didn't look at the CCS code, but surely they use this feature if the timer is set up as 16-bit).
Check it out
Ken |
|
|
Ttelmah Guest
|
|
Posted: Fri Jan 16, 2009 10:45 am |
|
|
Yes. CCS do perform the accesses in 16bit mode.
If you do a search here, you will find a number of people who were trying to access the individual timer registers directly, and then finding they were not getting the expected value. The reason, is because the contents of the second register is only latched, when you access the first, when the timer is operating in 16bit access mode.
Best Wishes |
|
|
RLScott
Joined: 10 Jul 2007 Posts: 465
|
|
Posted: Fri Jan 16, 2009 11:05 am |
|
|
Ttelmah wrote: | ...If you do a search here, you will find a number of people who were trying to access the individual timer registers directly, and then finding they were not getting the expected value. The reason, is because the contents of the second register is only latched, when you access the first, when the timer is operating in 16bit access mode. |
This hardware latching only occurs in the 16-bit cores (PIC18F). In the 14-bit cores, the high and low bytes are both directly accessible. Here is the code from the Midrange Family Reference Manual on how to write to Timer 1 while it is running:
Code: |
; All interrupts are disabled
CLRF TMR1L ; Clear Low byte, Ensures no
; rollover into TMR1H
MOVLW HI_BYTE ; Value to load into TMR1H
MOVWF TMR1H, F ; Write High byte
MOVLW LO_BYTE ; Value to load into TMR1L
MOVWF TMR1H, F ; Write Low byte
; Re-enable the Interrupt (if required)
|
_________________ Robert Scott
Real-Time Specialties
Embedded Systems Consulting |
|
|
Guest
|
|
Posted: Fri Jan 16, 2009 4:16 pm |
|
|
Hi
The PIC I use is 18F2455. And I just use CCS function to access the values from timer1. |
|
|
John P
Joined: 17 Sep 2003 Posts: 331
|
|
Posted: Fri Jan 16, 2009 4:57 pm |
|
|
Code: |
All interrupts are disabled
CLRF TMR1L ; Clear Low byte, Ensures no
; rollover into TMR1H
MOVLW HI_BYTE ; Value to load into TMR1H
MOVWF TMR1H, F ; Write High byte
MOVLW LO_BYTE ; Value to load into TMR1L
MOVWF TMR1H, F ; Write Low byte <-------- Looks like a typo, should be TMR1L
; Re-enable the Interrupt (if required)
|
|
|
|
RLScott
Joined: 10 Jul 2007 Posts: 465
|
|
Posted: Sat Jan 17, 2009 7:05 am |
|
|
John P wrote: | Code: |
MOVLW LO_BYTE ; Value to load into TMR1L
MOVWF TMR1H, F ; Write Low byte <-------- Looks like a typo, should be TMR1L
|
|
By golly, you are right. And I did a copy and paste directly from the Midrange Family Reference Manual from Microchip. _________________ Robert Scott
Real-Time Specialties
Embedded Systems Consulting |
|
|
|