SpenceKonde / ATTinyCore

Arduino core for ATtiny 1634, 828, x313, x4, x41, x5, x61, x7 and x8
Other
1.53k stars 302 forks source link

PWM frequency ATtiny84 (ATtinyx4) #762

Closed ltwin8 closed 10 months ago

ltwin8 commented 1 year ago

hi, i would like to drive 4 PWM led drivers with an attiny 84 MCU, i noticed i can not get all channels to output at same frequency, the datasheet suggest a prescaler of zero can be applied to both timers from same source, however i can not get it to work.

i would like to achieve a PWM of around 500Hz to avoid visible flicker even on reasonable movements. i like to stay below 1kHz because of vibrations.

TCCR0B = _BV(CS00); //should yielld prescaler = 1 from CLK-i/o TCCR1B = _BV(CS10); //should yielld prescaler = 1 from CLK-i/o

TCCR0B = TCCR0B | 0b00000001; TCCR1B = TCCR1B | 0b00000001; also does not work...

can anyone help me?

SpenceKonde commented 1 year ago

Prescale = 1 would result in Fpwm = F_CPU/(TOP+1) = F_CPU/256 = 31250 Hz.

You can get close to 500 with full 8-bit resolution at 488 Hz (with /64 prescale). In fact, we configure it for 64 prescale by default (we try to stay between 500 and 1500 Hz - much lower than 500 and there's flicker, and above 1500 Hz, even at 5v, you start struggling to drive MOSFETs all the way to on or off fast enough, they spend too long switching, switching losses are high, and gate drivers are needed when you really oughtn't need them - hence that target range). So just doing analogWrite should get you 488 Hz out of one of the two timers (timer0 - we can't use phase correct mode there anyway because we use it for millis, and how to you know if it's going up or down?). You might end up getting half that out of the other timer. That is because it is in phase correct PWM mode, instead of fast PWM mode. (We do the same thing as the official core there, don't look at me!) Hence you must change the waveform generation mode (WGM) IIRC the core sets it to 0b0001 (8 bit phase correct) on the non-millis timers, to 0b0101 (8-bit fast PWM).

I think leaving timer0 as is will give you 488 Hz pwm. Timer 1 will give half that in stock configuration, and getting the same frequency will meanchanging WGM from 0001 to 0101. Conveniently only one bit needs to change, namely bit 3 of TCCR1B

So TCCR1B |= 1<<3; I think should be all you'd need for analog write to get you 488 Hz PWM...

ltwin8 commented 1 year ago

Hello, thank you. I do not drive a get directly but low capacitance dimming Input of few pF, faster freq should work also but the resonance of the PCB is around 1-2k (Design constrained)Thanks for your answer, I will give it a tryVon meinem iPhone gesendetAm 01.05.2023 um 18:15 schrieb Spence Konde (aka Dr. Azzy) @.***>: Prescale = 1 would result in Fpwm = F_CPU/(TOP+1) = F_CPU/256 = 31250 Hz. You can get close to 500 with full 8-bit resolution at 488 Hz (with /64 prescale). In fact, we configure it for 64 prescale by default (we try to stay between 500 and 1500 Hz - much lower than 500 and there's flicker, and above 1500 Hz, even at 5v, you start struggling to drive MOSFETs all the way to on or off fast enough, they spend too long switching, switching losses are high, and gate drivers are needed when you really oughtn't need them - hence that target range). So just doing analogWrite should get you 488 Hz out of one of the two timers (timer0 - we can't use phase correct mode there anyway because we use it for millis, and how to you know if it's going up or down?). You might end up getting half that out of the other timer. That is because it is in phase correct PWM mode, instead of fast PWM mode. (We do the same thing as the official core there, don't look at me!) Hence you must change the waveform generation mode (WGM) IIRC the core sets it to 0b0001 (8 bit phase correct) on the non-millis timers, to 0b0101 (8-bit fast PWM). I think leaving timer0 as is will give you 488 Hz pwm. Timer 1 will give half that in stock configuration, and getting the same frequency will meanchanging WGM from 0001 to 0101. Conveniently only one bit needs to change, namely bit 3 of TCCR1B So TCCR1B |= 1<<3; I think should be all you'd need for analog write to get you 488 Hz PWM...

—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you authored the thread.Message ID: @.***>

ltwin8 commented 1 year ago

@SpenceKonde just wondering, how can i achieve PWM of similar frequency on attiny 85 pins PB0 and PB1?

i drive a WW/CW LED (CCT light) and use this driver https://www.mouser.de/datasheet/2/277/MP3362GJ-2497282.pdf

i would like to try analog dimming on it but there i have the same problem with the different frequency... can i apply the same rule to attinyX5? the actual mcu silicon is quite similar i think. only dont know if that would mess up something other.... i do not use millis or delay

thanks for the help

SpenceKonde commented 1 year ago

Oh the tiny85 is a whole other can of worms. The timer1 there is WHACK, It's a high speed timer and it is async. Can be run at 32 or 64 MHz from the PLL. If you just need to duplicate the pwm frequencies though between the two timers, you;re off by a factor of 2,so just nudge the prescaler by 1 - Timer1 gets EVERY POWER OF TWO PRESCALER!

The 85's timer 1 is unique to the x5, though similar to x61 (which is also unique, also high speed, and also has every-power-of-2 prescaler - nothing else I know of does at least), but it's got 10 bits. In fact, on classic tinyAVRs, the timers were very often unique. x7's timer1 has the wierd output thing, x41 and 828 have a more sophisticated remapping remapping.... 43U has a copy of timer 0 instead of the usual for timer1. Oh, and the x61's timer 0 is wacky too 8 or 16 bits of resolution, and two compare channels that can only trigger a software interrupt.

Know how many kinds of timers there are across the whole modern AVR range? TCB 1.0 (pre Dx), TCB 1.1 (adds cascade feature, a separate overflow flag, and ability to clock from events), TCA 1.0 (Pre Dx), TCA 1.1 (adds second event input), otherwise unchanged, TCA 1.1.1 (DD-series - and may be backported to DA/DB if we ever get a die rev - only difference is that it overrides port direction so you don't have to set pins output. these version bumps are my nomenclature) TCD comes in v 1.0.0 and v 1.0.1 on the DD (same deal as TCA) and an RTC 0.9.9 (would be 1.0, but the errata is so nasty on 0/1-series tinies with under 32k of flash I can't keep a straight face and say that they're the same), and RTC 1.0.1 (only difference is the event system config registers - Dx and earlier had event generators for specific pins selected with in EVSYS, and didthe same with RTC prescaling options. That meant that not all event channelswere equal because they were limited to 2 ports per channel, and only half the RTC options. On Ex. all ports can have 2 event generator pins, and the RTC PIT can have two event outputs, and those get set with an EVGENCTRL. but those peripherals are otherwise identical

So that gives 4 types of timer, having 3, 2, 2, and 3 versions respectively, but they're use is so similar. Only the TCB 1.0 vs 1.1 and TCA 1.0 vs 1.1 have substantial differences (but these are differences that you can ignore for the most part - I did have to create compatibility defines for 1 register on one, and for 1 3-bit bitfield on one (it was a 2-bit bitfield before - they added some clocking options), and you can do a few more things on the newer version, but like, I don't even have to bother looking at the datasheet for the part I'm using in modern AVR land - any datasheet that happens to be open will probably have what I need for using the timers.

Classic AVR had... t85, tx61*2 , t26, tx7, t43, the no-PWM 8-bit Timer0, then the normal timer0, the normal timer1, the async 8-bit timer2, and the enhanced timer1-style timers of the m2560. Oh and the 10-bit high speed timer4 on the 32u4.... That's like 10 if we don't count the enhanced timer1's (identical to normal ones except 3 channels instead of 2) Nine of those are present on the tinyAVR classics, and you'd need 7 datasheets open to have information about all of them. So I hope you can understand why maintaining these is so difficult. Many parts are effectively unique, complete oddballs which require their own implementations of the timer related functions.

SpenceKonde commented 10 months ago

This should be solved now. We have a table in each parts part specific documentation that lists the default frequency of PWM at all speeds, I've fixed the prescaler calculations to keep the speeds much more consistent as the clock speed changes when we are able to do that (like, it now switches between phase correct and fast PWM based on F_CPU), since few people care which one it is using (and those that do are taking over the timers anyway)... and links to a document talking about how to change the frequency by adjusting the prescaler while still using analogWrite.