NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Microcontroller Programming » RGB PWM. Cannot get led to completely turn off.

July 02, 2011
by uml_12
uml_12's Avatar

Hey,

I am experimenting with timer 0 and timer 2. I am using OCR0A/B and OCR2B set for 8bit fast PWM:

COM1A1/A0 = 11 = clear OC1A/B on compare match. output low. COM1B1/B0 = 10 = set OC1A/B at bot (non inverting) WGM13/12/11/10 = 0101 = fast PWM 8-bit CS12/11/10 = fclk/ 256 FOC1A/B = 00 = no force output (non PWM mode)

COM2A1/A0 = 10 = Clear OC2A on compare match, set OC2A at bottom COM2B1/B0 = 10 = clear OC2B on compare match, set OC2B at bottom WGM2/1/0 = 011 = fast PWM CS22/21/20 = 110 = fclk / 256 prescaler

My goal is to basically set up all the registers and what not for PWM and use a for loop to fade the led in white, back out, wait and repeat.

Theoretically, in my mind at least, the led (common cathode. each anode connected to a 470ohm resistor and then to the respective pin) should start totally void of color. Gradually it will fade in white and fade back out. But what is actually happening is that when I connect power to my 168 instantly it illuminates blue. And the blue never really goes away.

I have similar code in another file im trying to run that cycles through many other colors besides white. And while I get most of those other colors, blue always dominates the output. Any clues ?

The code: / PD3 = Green (OC2B) PD6 = Red (OC0A) PD5 = Blue (OC0B) /

define F_CPU 14745600

include <stdio.h>

include <avr/io.h>

include "../libnerdkits/delay.h"

int main(){

    unsigned char duty_cyc_red,duty_cyc_blu,duty_cyc_grn;

    //Initialize Timer0 Fast PWM
    TCCR0A = 0b10110011;
    TCCR0B = 0b00000100;

    /* Disregard for Nerd kits forum post * 
    TCCR1A = 0b11100001;
    TCCR1B = 0b00001100;
    TCCR1C = 0b00000000;
    */

    TCCR2A = 0b10100011;
    TCCR2B = 0b00000110;

    OCR0A = 0;              //Starting value for output compare registers
    OCR0B = 0;
    OCR2B = 0;

    TCNT0 = 0;              // Reset Timers
    TCNT2 = 0;

    //Initialize PORTD to output. All pins Low 
    DDRD = 0b11111111;
    PORTD = 0b00000000;

    duty_cyc_red = 0; 
    duty_cyc_blu = 0;
    duty_cyc_grn = 0;

    for(;;){

        //Fade IN White 
        while(duty_cyc_grn < 255){
        OCR0A = duty_cyc_red++;
        OCR0B = duty_cyc_blu++;
        OCR2B = duty_cyc_grn++;
        delay_ms(10);
        }

    // Fade Out White
        while(duty_cyc_grn > 0) {
        OCR0A = duty_cyc_red--;
        OCR0B = duty_cyc_blu--;
        OCR2B = duty_cyc_grn--;
        delay_ms(10);
        }

        delay_ms(1000);

        }

return 0; 
}
July 02, 2011
by uml_12
uml_12's Avatar

*correction ..

change this: COM1B1/B0 = 10 = set OC1A/B at bot (non inverting)

to this: COM1B1/B0 = 10 = set OC1A/B at BOTTOM (non inverting)

July 04, 2011
by uml_12
uml_12's Avatar

apparently the easiest thing to do is turn off the problematic pin when the corresponding compare register reaches zero and then turn it back on when the register increases again. I can't figure out why this is an issue .. owell.

Post a Reply

Please log in to post a reply.

Did you know that you can read diagnostic data from some cars with a NerdKit? Learn more...