2014-10-31 10 views
0

나는 AVR Studio5를 사용하여 atmel atmega328p로 arduino uno rev3를 프로그래밍하고 있습니다. 이제 1 초 이내에 계속 깜박입니다. 코드는 다음과 같습니다C 언어 (atmega328p)로 1 초간 연속 깜박임

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;  

위의 코드는 내가 각 0.032768s에 대한 이끄는 PORTD.7을 깜박을 시도하는 1 초 동안 지속되는 타이머 1을 사용하는 것을 알 수있다. 그러나 이제 문제는 타이머가 1 초 지연되지만 LED가 깜박임없이 계속 켜져 있다는 것입니다. 도와주세요 . (P.S 회로가 잘 작동합니다)

보완 코드 : 다음 코드를 사용하면 LED가 깜박입니다.

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; 
} 

그러나 간단히 말해서 나는 작업하는 경우 가장 많이 사용하는 방법을 선호합니다.

+0

usleep 기능을 사용할 수 있습니까? 몇 가지 추가 정보 : http://pubs.opengroup.org/onlinepubs/009695399/functions/usleep.html – MiltoxBeyond

+0

@MiltoxBeyond 나는 그가 OS가 없다고 생각합니다. – RedX

+0

OP가'avr-gcc'를 사용하고 있다면'util/delay.h'의'_delay_ms' 함수로 간단한 지연을 사용할 수 있습니다. – ouah

답변

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

너무 빨리 깜박입니다. 실제로보고있는 것은 밝기의 반이되는 LED입니다. PORTD ^= 1<<7 두 번의 호출 사이에 약간의 지연을 추가해야합니다.

+0

I는 재기록 "동안 ((TCNT1H - 온도)> = 10) { PORTD^= 1 << 7 // 점멸 예상대로}"에서 "동안 ((TCNT1H - 온도)> = 30); \t \t \t PORTD^= 1 << 7; " 더 큰 시간 간격을 만들지 만 도움이되지 않습니다. –

0

이것은 인터럽트로 수행해야하는 작업입니다.

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  
} 

이 코드는 작동하지만 테스트되지 않았습니다. avr/interrupt.h를 포함하는 것을 잊지 마십시오. 일부 매크로는 컴파일러의 버전 차이로 인해 다를 수 있습니다.