Go Down

Topic: Direct port manipulation using TIMER1 (Read 1 time) previous topic - next topic

soulid

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
Code: [Select]
#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;
  }
}

AWOL

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

The Mega has twelve PWM outputs.
What's the problem?
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

soulid

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

soulid

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

PeterH


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



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).
I only provide help via the forum - please do not contact me for private consultancy.

dhenry

Quote
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.

dhenry

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

soulid

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.

Go Up