PWM in ATtiny 13A doesn't work

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

Short story short I'm trying to setup fast PWM on ATtiny13A and something doesn't exactly go right. I've decided it's my code, so I've downgraded to some basic "dim a diode" kind of code, achieved nothing and grabbed some example from other thread about using PWM in this micro which you can see right here:

 

http://http://www.avrfreaks.net/sites/default/files/LED_FADE.c

 

Which for convenience's sake I'm pasting itt:

 

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include <util/delay.h>

unsigned char toggle = 0;

void io_init()
{
    DDRB     = 0x02;         					//set portB.1 as output

/***************************************************************************
*
*      		configure timer 0 for:
*             fast PWM mode
*             OCR0A = PWM period
*             OCR0B = PWMduty cycle
*
***************************************************************************/
   
    TIFR0 = 0xFF;                		 			// clear interrupt-flags
    TCNT0 = 0;                          			// clear counter register
    OCR0A = 0xf0;   	    		     		  	// PWM period
    OCR0B = 0x7f;  	    	        				// PWM duty cycle
    
	TCCR0A = (1<<COM0B1) |(1<<WGM01) |(1<<WGM00);   // clear OC0B on compare match, set OC0B at top               
    
	//use prescalar & delay function to control delay 
	TCCR0B = (1<<WGM02) | (1<<CS00) | (0<<CS01) | (0<<CS02);  	// prescale = clk/1 

    TIMSK0 = 0;                          			// disable timer0 interrupts

}


int main(void)
{
unsigned char i;
unsigned char j;


       io_init();

       while (1)
       {
	   			i=0x00;    //activate if fade in
				j=0xFF;
                
				
				
				//Optional Fade in, control with delay and clock scalar
				
				
				for (i=0x00; i<0xff; i++)
    			{
     				OCR0A = i;
     				_delay_ms(10);
    			}
				


   	 			// Turn B1 on for 4s   			
    			OCR0A = j;
				_delay_ms(4000);

				//Fade out, control with delay and clock scalar
				for (j=0xFF; j>0x01; j--)
    			{
     				OCR0A = j;
     				_delay_ms(10);
    			}
			//	PORTB = 0x00;
				//_delay_ms(5000);

				 

       }

return(0);
 
}

However, it still doesn't work(in the thread the guy who wrote it said he had some problem, which he'd know about if he read the documentation better, but it generally worked - not for me, it seems). Instead of dimming etc. it lights with the same intensity equal to constant 5V output. While troubleshooting I've tried to measure the voltage on it, the multi meter seemed to short it(which is at least weird). The circuit is nothing to speak of - just a programmer connected to the uC as it is supposed to, a diode and a current limiting resistor grounding it. Tried powering it via external source(as in - by something else than the programmer).

 

Any idea what could go wrong? Oh, I've tested the same code on another ATtiny13A - still didn't work and modified it to work on ATmega8A - on which it did work.

This topic has a solution.
Last Edited: Fri. Sep 15, 2017 - 06:16 AM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

You've selected mode 7, which uses OCR0A as TOP, so you should be using OCR0B as the PWM output.  Looks like that's what you meant to do since you've making PB1 an output.  All the below highlighted lines should be OCR0B:

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include <util/delay.h>

unsigned char toggle = 0;

void io_init()
{
    DDRB     = 0x02;         					//set portB.1 as output

/***************************************************************************
*
*      		configure timer 0 for:
*             fast PWM mode
*             OCR0A = PWM period
*             OCR0B = PWMduty cycle
*
***************************************************************************/
   
    TIFR0 = 0xFF;                		 			// clear interrupt-flags
    TCNT0 = 0;                          			// clear counter register
    OCR0A = 0xf0;   	    		     		  	// PWM period
    OCR0B = 0x7f;  	    	        				// PWM duty cycle
    
	TCCR0A = (1<<COM0B1) |(1<<WGM01) |(1<<WGM00);   // clear OC0B on compare match, set OC0B at top               
    
	//use prescalar & delay function to control delay 
	TCCR0B = (1<<WGM02) | (1<<CS00) | (0<<CS01) | (0<<CS02);  	// prescale = clk/1 

    TIMSK0 = 0;                          			// disable timer0 interrupts

}


int main(void)
{
unsigned char i;
unsigned char j;


       io_init();

       while (1)
       {
	   			i=0x00;    //activate if fade in
				j=0xFF;
                
				
				
				//Optional Fade in, control with delay and clock scalar
				
				
				for (i=0x00; i<0xff; i++)
    			{
     				OCR0A = i;
     				_delay_ms(10);
    			}
				


   	 			// Turn B1 on for 4s   			
    			OCR0A = j;
				_delay_ms(4000);

				//Fade out, control with delay and clock scalar
				for (j=0xFF; j>0x01; j--)
    			{
     				OCR0A = j;
     				_delay_ms(10);
    			}
			//	PORTB = 0x00;
				//_delay_ms(5000);

				 

       }

return(0);
 
}

 

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

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

Yeah, that was the problem in both this and my own program. Thanks.