Bien Holmes
Bien Holmes

Reputation: 3

blinking led continuously with 1 second in C language(atmega328p)

I am using AVR Studio5 to program the arduino uno rev3 with atmel atmega328p.Now , I am trying blink a led continuously within 1 second . The code is :

    PORTD = 0b10001010;
    TCNT1H = 0xBB;
    TCNT1L = 0xBB;
    TCCR1A = 0;
    TCCR1B = 5; // prescaler is 1024
    while((TIFR1 & (1<<TOV1)) == 0)
    {
        temp = TCNT1H; 
        while ((TCNT1H - temp) >= 11);
        PORTD  ^= 1<<7; // blinking as expected
    }
    TIFR1 = 1<<TOV1;
    TCCR1A = 0;
    TCCR1B = 0;     

The above code shows that I use a timer1 lasting for 1 second in which I attempt to blink the PORTD.7 led for each 0.032768s. But , now , the problem is that the timer works for delaying 1 second but the led keep lighting without blinking . Please help . ( P.S the circuit works fine )

Complement : If I use the following code , it shows the led blinking.

for ( a = 0;a<2;a++)
{
  PORTD = 0b00001010;
    TCNT1H = 0xEE;
    TCNT1L = 0xEE;
    TCCR1A = 0;
    TCCR1B = 5; // prescaler is 1024
    while((TIFR1 & (1<<TOV1)) == 0);
    TIFR1 = 1<<TOV1;
    TCCR1A = 0;
    TCCR1B = 0;

    PORTD = 0b10001010;
    TCNT1H = 0xEE;
    TCNT1L = 0xEE;
    TCCR1A = 0;
    TCCR1B = 5; // prescaler is 1024
    while((TIFR1 & (1<<TOV1)) == 0);
    TIFR1 = 1<<TOV1;
    TCCR1A = 0;
    TCCR1B = 0;
}

But , for the simplicity , I prefer the most top method if working .

Upvotes: 0

Views: 3790

Answers (2)

Dark.Rider
Dark.Rider

Reputation: 391

This is something that should be done with an interrupt.

void TMR_init(void)
{
    DDRD|=_BV(PD7); //bit 7 of port D to output
    TCNT1=0; //reset the timer counter
    OCR1AL=0xC6; //depends on your osc. This values are for 12MHz
    OCR1AH=0x2D; //with 12 000 000Hz / 1024 it takes 11718 ticks for 1 sec->0x2D C6
    TIMSK1|=_BV(OCIE1A); //enable interrupt on output compare A (when timer value == value in the OCR1AL/H-registers)
    TCCR1A=0; //normal operation
    TCCR1B=_BV(CS12) | _BV(CS10); //prescaler 1024 and starts the timer

    sei(); //enable interrupts
}

//isr
SIGNAL(TIMER1_COMPA_vect)
{
    PORTD^=_BV(PD7); //toggle    
}

This code should work but is untested. Don't forget to include avr/interrupt.h. Some macros may differ due to version differences of the compiler.

Upvotes: 0

ouah
ouah

Reputation: 145899

    while ((TCNT1H - temp) >= 10)
    {
        PORTD  ^= 1<<7; // blinking as expected
    }

You are blinking too fast, so fast that actually what are you are seeing is a LED with half the luminosity. You need to add some delay between two invocations of PORTD ^= 1<<7.

Upvotes: 2

Related Questions