PWM Timer3 at 6-bit, 7-bit, 8-bit and 9-bit.


I have advanced with the help of this forum.

Particularly valerio_sperati illustrated the Prescaler.


(I using Mega2560 and Timer3)

int myEraser = 7; // this is 111 in binary and is used as an eraser TCCR3B &= ~myEraser; // this operation (AND plus NOT), set the three bits in TCCR3B to 0

now that CS02, CS01, CS00 are clear, we write on them a new value:

int myPrescaler = 1; // this could be a number in [1 , 6]. In this case, 1 corresponds in binary to 001. TCCR3B |= myPrescaler; //this operation (OR), replaces the last three bits in TCCR3B with our new value 001

now we have a new PWM frequency at 1/16000000 = 62.5ns this is great and very clear for me. Thank you very much valerio_sperati.

But I have not finished my project, and this big step, is not enough.

I need to control the width of the period. (realtime)

The above example works only 8 bits. 1/16000000*(2^8)= 0.000016 seconds (width of the period at 8-bits) = 1/0.000016 = 62500 Hz. I repeat, It's great.

But I also need:

1/16000000*(2^6)= 0.000004 seconds (width of the period at 6-bits) = 1/0.000004 = 250000 Hz. 1/16000000*(2^7)= 0.000008 seconds (width of the period at 7-bits) = 1/0.000008 = 125000 Hz. 1/16000000*(2^9)= 0.000032 seconds (width of the period at 9-bits) = 1/0.000032 = 31250 Hz.

I have no clear definitions of timer modes. I'm lost between the 15 modes of the timers.

I want to swing between 6-bit and 9-bit.

These are the questions:

1.- What are all the mode-timer in to do this?

2.- The main thing: How to do it?

My progress:

as far as I understand (with doc2549.pdf). Mode 8 PWM, Phase and Frequency Correct, seems best for this.

TCCR3A=B00000000; // TCCR3B=B00010001; // The first three bits (from right to left!) are Prescaler =00 1 equal time= (1/16000000 = 62.5 nS) // The other (bit 4) is WGM33=1 to set Mode 8 PWM, Phase and Frequency Correct.

// as ICR3 can set the top (2^bits / 2)-1

ICR3=65535; // (the maximum) ICR3=3; // (the minimum)

OCR3A= 0; // The duty is ON (100% pwm) OCR3A= ICR3A; // The duty cicle is OFF 0(0% pwm)

// Then can work two variables register

cli(); // Disable interrupts for 16 bit register access ICR3 = (2^bits / 2)-1; // ICR1 is TOP in p & f correct pwm mode OCR3A = someduty; sei(); // Enable interrupts for 16 bit register access

if this works properly, I can do a lot.

I have no oscilloscope to check, so again I ask your comment.

I appreciate your time and attention.

I wonder if you are making a fundamental mistake with binary numbers. They are all 8 bits wide. So decimal 7 is B00000111 and decimal 1 is B00000001.

I'm not sure what &= 7 does. Will it add B00000111 to the existing value?

You need to use & B11111000 if you want to clear the three low bits to 0 without affecting the other bits (& is binary AND)

and | B00000111 if you want to set the three low bits to 1 (| is binary OR)


I appreciate your response. I usually:

that part of code cited from

TCCR3A=0; // To clear registry, this not need further explanation. TCCR3B=0;

I think it would be more useful if you described what your project is trying to do and better still if you can post a complete sketch that illustrates the part you don't understand.


Yes, I do not have a complete sketch . I need knowledge to build a complete sketch that illustrates the part I'm don't understand.

Now I'm looking for tutorials (16 bit timer related)

When finished acquire the knowledge, then I do not need to acquire that knowledge.

I can understand if you don't yet have enough knowledge to write a sketch.

But you must have a description of what you are trying to do - so how about sharing that with us?

There are many many cases here where newcomers have a particular solution in mind that is unnecessary when more experienced minds (no necessarily mine) get a chance to see the bigger picture.


You haven't explained exactly what you want to achieve but if I understood correctly you want to achieve PWM output with frequencies of 31250 Hz, 62500 Hz, 125000 Hz, 250000 Hz and variable duty cycles with whatever resolution is available at those frequencies (the resolution will reduce at the higher frequencies).

This is the most comprehensive description I know of about how the timers work:

I think that article gives you enough information to understand what is possible to achieve with the timers and how to configure them to achieve that. If it doesn't then you'd better hope that somebody used to dealing with the timer hardware takes an interest in your question - that's not me. Your first post suggested that you had got quite a long way through this understanding and gave me the impression that you had already got an understanding of how to configure the timer to achieve what you want.

If you know how you want to configure the timer and want somebody to write the code for you to do it, you should post in the Gigs & Collaborations section.

That is probably also the best place to ask if you have written the code for yourself but want somebody with test equipment to test it for you.