Direct port manipulation using TIMER1

Hi,
I need to create 10 different PWM duyt cycle with a MEGA board. As the controller doesn't have so many different PWM duyt cycles I tried to do that by reading the TIMER1 register. I used the onboard LED so everyone reading this topic can try it easily.

I got avery uneven response and the LED is not having a conxtant PWM but having some light flickerings visible... :~ That shouldn't happen, right?

Here is my code

#include <avr/io.h> 
#include <avr/interrupt.h> 

void setup() {                
  // initialize the digital pin as an output.
  DDRB= B11111111; // set PORTB (digital 13-8) to outputs
  cli();          // disable global interrupts 
  TCCR1A = 0;     // set entire TCCR1A register to 0 
  TCCR1B = 0;     // same for TCCR1B 
  TCCR1B |= (1 << CS10);  // Set CS10  bit only for prescaler 1
  sei(); // enable global interrupts: 
}


void loop() {


  if (TCNT1 < 5){ 
    PORTB=B10000000; 
  } 


  if (TCNT1 > 20000){ 
    PORTB=B00000000; 
  } 
}

I need to create 10 different PWM duyt cycle with a MEGA board.

The Mega has twelve PWM outputs.
What's the problem?

Issue is the resolution which is fixed at 8 bit. We need a resolution of more than 10bit...

Has anyone tried this code on his Mega? I am still running out of ideas to get this idea running :disappointed_relieved:

soulid:
I need to create 10 different PWM duyt cycle with a MEGA board.

soulid:
Issue is the resolution which is fixed at 8 bit. We need a resolution of more than 10bit...

These two quotes seem inconsistent. Are you trying to output one of ten different duty cycles (easily done with 8-bit resolution) or a thousand different duty cycles (which would need 10-bit resolution).

That shouldn't happen, right?

That can happen: let's say that your counter overflows at the end of the loop. By the time it is tested for "TCNT1 < 5", however, the timer has advanced beyond 5 and the sentence in the "if" statement (" PORTB=B10000000; ") is never executed -> that cycle is more than 64k ticks -> light stays off twice as long.

You can test this by changing 5 to 50 or 500 (to reduce / eliminate the chance of this happening and your light will never flicker. Alternatively, you can increase the prescaler as well.

I think you will find it a lot easier to code what you want to do through timer interrupts.

Hi dhenry- I am impressed. You got the failure. changeing the value to 50 gives an even result although it is niot accurate enough. I need to think ybout other solutions. This single PWM was intendet to be first out of 10 different PWMs.