Yet another 25KHz PWM question

Hi all,
I'm working on a 25KHz PWM to fun a fan.

I'm using timer1 with IRC1 as my top and OCR1s A, B as outputs. My prescaler is currently 64.

My question is how do I determine what ICR1 and the OCR1s should be? I understand that OCR1s set the duty cycle, but all the tutorials I have found use timer2 OR if they use timer 1, ICR1 is at 320 with random values for OCR1s and no explanation of how they arrived at those values.

My current thoughts have come from the data sheet:

f_pwm=f_clock/(N*(1+TOP)) where N is the prescaler value and TOP is the count-up value.

I know I want my frequency to be 25K and if my prescaler is at 64, then TOP is 9.

I found some information that sets the OCR1s to be x/255, where 255/x gives duty cycle. So for example, if I want half duty cycle, I would do 255/2 for 50%, so my code would set OCR1 to 127.

Am I right? I hooked my PWM fan up but am unable to change the speeds. I wanted to check to see if my parameters were correct first. I'm running the fan off an external 12V power supply and have the fan ground also connected

I'm working on a 25KHz PWM
I'm using timer1 with IRC1 as my top and OCR1s A, B as outputs. My prescaler is currently 64.

Why are you using such a large prescaler. You have seen that you get a top value of 9 with that setting and fast pwm to ICR1 mode. The output compare values for the duty cycle have to be within the range of the top value. The resolution on your duty cycle will be quite coarse.

Based on your frequency equation (f_pwm=f_clock/(N*(1+TOP)) you have also chosen to use FastPWM to ICR1 mode. With no prescaler(N = 1), you want Top = 639 for 640 total counts.

if they use timer 1, ICR1 is at 320

The 320 value comes from no prescaler, and a dual sloped pwm mode which counts up and down for the 640 total counts. The OCR1A and OCR1B duty cycle values depend upon how the output pins are set to work on a compare match.

If you want to write this 25KHz pwm code using the Timer register values, you will need to spend more time with the data sheet to understand.

Otherwise, if you are just trying to get your fan to run, you can use a library like TimerOne which is available through the library manager and which has an example for 25KHz pwm. There are certainly several other pwm libraries available to use.

I've been reading all the information I can get on this, including the data sheet for about a week. I chose FastPWM because I thought it provided more flexibility with the output frequency, as it only has the upslope so the frequency can be twice as high. I was using that prescaler because it was the value used in the 'secrets of arduino PWM guide" and I haven't found anything that would tell me why I'd want to use a different prescaler.

Here were my thoughts:
I am currently only running one fan so I wasn't using OCR1B. I want to attach another fan at some point which is why I'm using ICR1.
So, the prescaler divides the clock frequency, right? And then IRC1 holds a value that TCNT1 counts up to and triggers an output on OC1A, whose duration of output (the duty cycle) is controlled by OCR1A, right? So my thought was to manipulate the equation to get as close to 25 KHz as I could and setting the size of OCR1A to determine the duty cycle.

But:
I'm confused on how OCR1A works with the other registers to get a duty cycle. I understand that given non-inverting output, OC1A will be low while ICR1=/=TCNT1. Once the match happens, OC1A is triggered high and TCNT1 holds its value for 1 clock cycle then set low. Where does OCR1A come into play? I've looked over the timing diagrams on the data sheet and they feature either ICR1 or OCR1A as examples, but not both and I don't understand how they work together.

Your response was very helpful. It's helped me understand some of the posts I've been reading. I now see where IRC1=639 would come from though I don't know why.

I do overthink things so it's likely that I'm doing that again.

I now see where IRC1=639 would come from though I don't know why.

Sometimes it helps to think in terms of clock "ticks". With no prescaler at 16 MHz, a clock tick is .0625 microseconds. With a prescaler of 8 its .5us, and with prescaler 64 a tick takes 4 microseconds.

You want a frequency of 25KHz which is a period of 40 microseconds. How many ticks are there in 40 microseconds. With prescaler 1 40/.0625 = 640. With prescaler 64 40/4 = 10.

The timer top value sets the number of ticks before the timer rolls over. With your mode ICR1 as top sets the number of ticks before the timer rolls. The timer counts are 0 indexed, so you have a top value of 639 for 640 ticks, or 9 for 10 ticks.

And then IRC1 holds a value that TCNT1 counts up to and triggers an output on OC1A, whose duration of output (the duty cycle) is controlled by OCR1A, right?

Correct.

Once the match happens, OC1A is triggered high and TCNT1 holds its value for 1 clock cycle then set low.

Not correct. With a single slope timer mode, TCNT1 keeps running until timer top, and then resets to 0. With a dual sloped mode TCNT1 keeps runs up to the top value and then starts counting down to 0. The compare match values for output need to be within the range of the timer cycle. That is, with top determined by ICR1, OCR1A and OCR1B need to be equal or less than ICR1.

Dkraemer:
I'm working on a 25KHz PWM to fun a fan.

I'm using timer1 with IRC1 as my top and OCR1s A, B as outputs. My prescaler is currently 64.

My question is how do I determine what ICR1 and the OCR1s should be? I understand that OCR1s set the duty cycle, but all the tutorials I have found use timer2 OR if they use timer 1, ICR1 is at 320 with random values for OCR1s and no explanation of how they arrived at those values.

Few guys at the Atmel Lab chalked out on paper that they wanted to generate a PWM signal at DPin-9 (Pin-15 of MCU), which would comply with the following principles:

1. The ON-period (the duty cycle) of the PWM signal will change as the content of OCR1A Register changes (Fig-1).

2. The frequency of the PWM signal will change as the content of ICR1 Register change (Fig-1).

3. As the frequency and the duty cycle are essentially counts in the time axis, let there be a counter and is the TCNT1 Register.

4. Then they drew the following diagrams to visualize the tricks to be applied to realize the PWM signal by integrating together the roles of these 3 registers: ICR1, OCR1, and TCNT1.
pwmMode10.png
Figure-1:

pwmTC1x.png
Figure-2:

Please, read the attached pdf file to see my style of description on the working principles of Fig-1, 2.

pwmMode10.png

pwm.pdf (349 KB)

pwmTC1x.png

cattledog:
Sometimes it helps to think in terms of clock "ticks". With no prescaler at 16 MHz, a clock tick is .065 microseconds. With a prescaler of 8 its .5us, and with prescaler 64 a tick takes 4 microseconds.

You want a frequency of 25KHz which is a period of 40 microseconds. How many ticks are there in 40 microseconds. With prescaler 1 40/.065 = 640. With prescaler 64 40/4 = 10.

The timer top value sets the number of ticks before the timer rolls over. With your mode ICR1 as top sets the number of ticks before the timer rolls. The timer counts are 0 indexed, so you have a top value of 639 for 640 ticks, or 9 for 10 ticks.

So given that my prescaler math was correct, why did you ask why my duty cycle was so high? Is it because OCR1n has to be lower than ICR1 and because my numbers were so low it would result in poor resolution? I'll probably experiment with this. I don't need precision, just looking for a low, medium and high speed for my fan.

cattledog:
Not correct. With a single slope timer mode, TCNT1 keeps running until timer top, and then resets to 0. With a dual sloped mode TCNT1 keeps runs up to the top value and then starts counting down to 0. The compare match values for output need to be within the range of the timer cycle. That is, with top determined by ICR1, OCR1A and OCR1B need to be equal or less than ICR1.

I read in the data sheet that TCNT1 is held high for one clock cycle but maybe that has nothing to do with what I was asking.

I realized that my code would not do what I actually wanted it to do. Initially I thought ICR1 would work because the values weren't changing in real time, like they would with a potentiometer, but I realized I was wrong. Because I wanted to test everything in a loop to make sure the low, med and high modes would work, it dawned on me that I'm actually using them in a dynamic way. This matches with my goal of being able to change the fan speed manually in response to a temperature reading (I don't want automatic temp control) and I see now that that process is dynamic, not static. Phase and Frequency Correct PWM is what I need.

I got it working using non-inverting WGM Mode 9 with prescaler set to 1. OCR1A is 320 (which will double for the mode given because TCNT1 counts up and then down) and modified OCR1B by dividing ORC1A as needed. It all works now! I'm so happy.

Thank you for helping me understand! :slight_smile: I was very confused. The data sheet is dense!

GolamMostafa:
4. Then they drew the following diagrams to visualize the tricks to be applied to realize the PWM signal by integrating together the roles of these 3 registers: ICR1, OCR1, and TCNT1.
pwmMode10.png
Figure-1:

Please, read the attached pdf file to see my style of description on the working principles of Fig-1, 2.

This is very helpful, thank you!

So given that my prescaler math was correct, why did you ask why my duty cycle prescaler was so high? Is it because OCR1n has to be lower than ICR1 and because my numbers were so low it would result in poor resolution?

Correct.