billcat:
Hi, thanks for the info. It is honestly more than I can comprehend. For me to try and understand any part of the datasheet, would be equivalent to opening a book written in a foreign language and expect to be able to read it. I say this because I have looked at it before. I am not afraid or unwilling to learn something, quite the contrary. I am just realistic about my background level regarding these things. I cannot ask the datasheet to explain itself!
So any chance this can be "dumbed" down even more, I know it is asking a lot? Otherwise, I do indeed appreciate your efforts nonetheless!
cheers,
don't sell yourself short, it's really easier than it looks. I started in the same situation you are.
just think of it this way.
you start with a 16mhz clock.
you have a timer (8 or 16 bit). which will increment once per clock cycle.
so say you want 16000 hz, that is 1/16= 0.0625ms or 62.5us.
one cycle of the pwm is when counter starts from 0, counts to top (255 for 8 bit, 65536 for 16 bit, or can be user specified), then back down to 0.
so you need to divide 62.5us by either 512 (2562 due to upcount then downcount), 655362, or a custom value.
62.5/512=0.122us. per timer increment using 8 bit.
now the arduino clock of 16mhz can be divided by 1,8,64,256,1024.
if we use divided by 1, 1/16 = 0.0625us, which is too fast to get 16khz
if divided by 8. 16mhz/8=2mhz, 1/2 = 0.5us per timer increment.
we cannot get the exact 16khz freq using the standard 8bit or 16bit top, so we must use a custom counter top (top is the number where the timer switch direction and counts downwards)
lets use the divided by 1 value of 0.0625us per count.
so we divide 62.5/0.0625 =1000
this means if timer increments once every 0.0625us, after 1000 increments/decrements, 62.5us has elapsed, exactly the time period for 16khz! Since we need 1000 count, 8 bit timers are out.
since the counter counts up then down, divided 1000 by2 to get the 500 for TOP.
Now you got all the values, just figure where in the timer registers to set these.
TCCR1A, TCCR1B for setting the clock divider, wave generation mode
ICR1 for the TOP
OCR1A for the duty cycle.
wave generation mode 10 is whats needed here. it clears the pin low on match to OCR1A value on counting up, and sets the pin high on OCR1A match on the way down.
say you set OCR1A to 125.
counter start from 0, count to 500, back down to 0.
lets start from the top, from 500, the pin is low. when it decrements down to 125, it will set the pin high, once it hits 0, it start incrementing, and when it reaches 125, it set the pin low.
so the pin is high from 125 to 0 to 125 for a total of 250 clock cycles out of 1000 or exactly 25% duty cycle.
all these info can be found in atmega328 datasheet chapter 15. study section 15.11 carefully for the register description. and you can see in my code how I arrived at the values to set the registers to.
you can use that pwm library, but it won't hurt to understand how this works.