PWM on OC0B in Timer0 CTC Mode

Go To Last Post
4 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In below code, I am trying to generate PWM on OC0B pin (PD5) in timer0 CTC mode. I am getting only high output. Unable to makeout the problem. I am using COMP_A ISR to clear the OC0B bit and OC0B pin is set on compare match. So OCR0B is basically used to vary duty cycle and OCR0A to set the period. I am using Atmega328P.

void timer0_CTC_Mode_PWM_on_OC0B(void)
{
	DDRD|= (1<<PD5);

	//16 MHz:  0.0626 usec * 1024 = 0.064 msec ---> 0.064*156 = 10 msec
	// @16 MHz OCR0A of 15 -->  1 msec pulse
    OCR0A = 156;          // set for 1 msec.
	OCR0B=100;
	
	TIMSK0 |= 1<<(OCIE0A);  // Output Compare Interrupt Enable for TimerCounter0 Compare Match A
	//TIMSK0 |= 1<<(OCIE0B);  // Output Compare Interrupt Enable for TimerCounter0 Compare Match B
	TCCR0A |= 1<<(WGM01);  // Mode = CTC: WGM01=1, WGM00=0 in TCCR0A and  WGM02=0 in TCCR0B
    TCCR0A |= (1 << COM0B1)|(1 << COM0B0);   // Set OC0B pin on compare match

	// Timer is activated as soon as the clock source is selected
	TCCR0B = (1<<CS02)|(1<<CS00);   // Timer Prescaler Clock/1024, TCCR0B: CS00 - 1, CS01 - 0, CS02 - 1
}

// ISR
ISR(TIMER0_COMPA_vect)
{
    PORTD &= ~(1<<PD5);
}

int main (void)
{
     //initialize the timer
     timer0_CTC_Mode_PWM_on_OC0B();
     sei();  // Enable interrupt globally
     
     while(1)
     {
     
         
     }
     
}

 

This topic has a solution.

Last Edited: Mon. Sep 25, 2017 - 03:57 PM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Are you trying to have the timer do PWM, or are you trying to do it "manually"?

 

If you want the timer to do PWM, then why are you trying to do it manually?

 

Are you trying to do PWM, or CTC?

 

Too many |= for my taste.  If you are setting up the few registers for a timer, then do the few direct assignments.

 

PD5 is indeed OC0B for that AVR family, according to my datasheet.

 

Once you set the COM bits, then the timer "has" the pin. 

If one or both of the COM0B1:0 bits are set, the
OC0B output overrides the normal port functionality of the I/O pin it is connected to.
 

And you told it to Set on Compare Match.  So, yes, except for the first 100 timer counts the pin will be set high, and set high, and set high, ...

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you for the quick response. Got the issue. Since normal port operation is disabled when COM0Bx is set, I cannot clear PD5 in COMPA vector as I was doing.

 

I was only trying something (and that is why you will also see too many |=) and not for actually using it as PWM. I will use Mode 7 for PWM.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

joneewheelock wrote:
I was only trying something

Well, what are you trying to do?  As you programmed it, the AVR reacted exactly how it is specified in the Timer0 chapter of the datasheet.  What did you expect differently, as you took the time to post?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.