View previous topic :: View next topic |
Author |
Message |
atmega64
Joined: 23 Feb 2005 Posts: 298 Location: ITALY
|
Posted: Fri Jan 13, 2023 12:46 pm Post subject: Abnormal restart timer |
|
|
Hi,
one thing i don't understand...
I used this code to set two timers:
Code: |
'******* START TIMER PER WAVE1 E WAVE2
Dutycycle = 3
'****************TIMER0 8 bit 3247KHZ out OC0B(pin5) WAVE1
Tccr0a = &B00100011
Tccr0b = &B00001011 'PRESCALER 64
Ocr0a = 76
Pwm0b = 44
Waitus 181 'signal phasing delay
'*****************TIMER2 8 bit 3247KHz out OC2B(pin20)'dutycycle variable WAVE2
Tccr2a = &B00100011
Tccr2b = &B00001011 'PRESCALER 64
Ocr2a = 153
Pwm2b = Dutycycle
|
and this to turn them off:
Code: |
Tccr0a = &B00000000 'STOP TUTTI I TIMER
Tccr0b = &B00000000
Tccr2a = &B00000000
Tccr2b = &B00000000
|
....
I vary the dutycycle using this timer:
Code: |
Const Timer3reload = 50000 '25ms
Config Timer3 = Timer , Prescale = 8
..
..
Timer3_isr:
Load Timer3 , Timer3reload
Pwm2b = Dutycycle
Dutycycle = Dutycycle + 3
If Dutycycle = 45 Then Dutycycle = 3
Return
|
Why, when I restart the timers, do they no longer work correctly?
(BASCOM-AVR version : 2.0.8.5 ) |
|
Back to top |
|
|
atmega64
Joined: 23 Feb 2005 Posts: 298 Location: ITALY
|
Posted: Fri Jan 13, 2023 2:40 pm Post subject: |
|
|
instead, if power supply off and then power supply on,
they work fine until I block them from software... |
|
Back to top |
|
|
atmega64
Joined: 23 Feb 2005 Posts: 298 Location: ITALY
|
Posted: Thu Jan 26, 2023 8:26 am Post subject: |
|
|
any advice please?? |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Thu Jan 26, 2023 10:53 am Post subject: |
|
|
atmega64 wrote: | any advice please?? |
Any minimized compilable sample??
Any meaningful problem description??
You know the rules, and nonetheless you're throwing chunks of code like bones to the dog.
Easy to understand you find no one to help, I thought twice too.
Quote: | when I restart the timers, do they no longer work correctly |
- Define 'restart'
- Define 'correctly'
Just doing some guessing:
Only for the first start the meticulous inserted 181 microseconds phase offset between timer 1 and 2 work and this phase offset gets lost after every restart?
Reason is: The prescalers are counters with preset TOPs like 1, 8, 32, 64,...
These prescaler counters keep their internal value, even you remove the clock and stop the timers.
Restarting the timers, i.e. reconnecting clock to the prescalers makes them resume from the internal value they have stopped.
Solution is to reset the prescalers before restart.
As you even omitted the controller in question, you have to look up the way yourself.
Hint: In ATMega64 it is found in register SFIOR. |
|
Back to top |
|
|
atmega64
Joined: 23 Feb 2005 Posts: 298 Location: ITALY
|
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Thu Jan 26, 2023 2:56 pm Post subject: |
|
|
atmega64 wrote: | I haven't been able to reset the PRESCALER... I can't find:
Quote: | Hint: In ATMega64 it is found in register SFIOR. |
?? |
It would have helped, if at least you would have looked up SFIOR from your name-givers datasheet to learn what I'm writing about and what's the task for you.
If I do a post, then I'm ready to spend some time reading datasheets, and so should you.
Quote: | the microprocessor i'm using is: ATmega1284 |
This is more tricky, you will have fun
Especially as the datasheet omits Timer3 in this matter:
Quote: | Note that Timer/Counter1 and Timer/Counter0 share the same prescaler and a reset of this prescaler will affect both timers. |
I would however assume, that Timer3 shares the same prescaler, as this timer (additional to ATM1284) is mentioned within the datasheet's Timer1-section.
Timer2 however seems to be the only one to run also in asynchronous mode.
This is especially important for the way you distributed the timers in your code.
Because if I assume correctly, then a reset to the commonly used prescaler would also hit Timer3 and therewith the Timer3 ISR.
I'd suggest to use Timer1 instead of Timer2, as they share the same prescaler as Timer0/1, which can be reset with PSRSYNC within register GTCCR.
PSRASY is required to reset Timer2.
As this Timer2 seems to use a different prescaler, it wouldn't be affected by resetting the Timer0/1/3 prescaler, making it better suitable for the ISR.
Looks like you need to do some testing.
A brute force method would be to 'flush' the prescalers.
For example reset Timer0, start, then loop and stop if the timer's value equals one. Same for Timer2.
Depends on the overall timing, whether you can afford these wait periods.
Be sure there will be a few clocks jitter using this method. Also no interrupts allowed.
Btw., what's the project behind this code?
Maybe a different approach would fit better. |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Thu Jan 26, 2023 4:07 pm Post subject: |
|
|
Try it, everything should stay in sync as long neither the count-value of Timer0 nor Timer2 is altered by code.
Order of timer registers as shown in restart() and stop() is important.
Code: | Sub First_Start_T02()
Disable Interrupts
Dutycycle = 3
Tccr0a = &B00100011
Tccr0b = &B00001011
Ocr0a = 76
Pwm0b = 44
Waitus 181
Tccr2a = &B00100011
Tccr2b = &B00001011
Ocr2a = 153
Pwm2b = Dutycycle
Enable Interrupts
End Sub
Sub Re_Start_T02()
Disable Interrupts
Dutycycle = 3
Ocr0a = 76 ' omit if never altered
Pwm0b = 44 ' same
Ocr2a = 153 ' same
Pwm2b = Dutycycle
Tccr0a = &B00100011
Tccr0b = &B00001011
Tccr2a = &B00100011
Tccr2b = &B00001011
Enable Interrupts
End Sub
Sub Stop_T02()
Disable Interrupts
Tccr0a = &B00000000
Tccr0b = &B00000000
Tccr2a = &B00000000
Tccr2b = &B00000000
Enable Interrupts
End Sub |
|
|
Back to top |
|
|
atmega64
Joined: 23 Feb 2005 Posts: 298 Location: ITALY
|
Posted: Mon Jan 30, 2023 12:28 pm Post subject: |
|
|
ok perfect it works!!
thank you. |
|
Back to top |
|
|
|