2017-02-16 1 views
0

ATMega164PA의 Timer0에서 PWM을 사용하여 LED의 밝기를 높이려고합니다. 아래 코드를 실행 한 후에는 LED가 켜져 있고 밝기는 변하지 않습니다. ATMega164PA를 사용하는 PWM

은 내 코드를 살펴보고 말해 나를 내가 잘못하고있는 중이 야 뭔가가있는 경우하십시오 :

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

int dutycycle = 0; // Variable for dutycycle 

/********************************************** MAIN ****************************************************/ 
int main(void) 
{ 
    DDRB |= (1 << PB3); // Make pins output and OC0A pin for PWM 

    TCCR0A |= (1 << COM0A1) | (1<<WGM01) | (1<<WGM00); // Clear OC0A on comare match and set OC0A at BOTTOM 

    TIMSK0 |= (1<<TOIE0); // Overflow Interrupt Enabled 

    TCNT0 = 0; // Set Counter Value Register for comparison with OCR0A 

    OCR0A = (dutycycle/100) * 255; // Set duty cycle ON period 

    sei();  // Enable global interrupts 

    TCCR0B |= (1 << CS00); // Prescale of 1 - start timer 

    while (1) 
    { 
     _delay_ms(500); 

     dutycycle += 10;  // increase duty cycle by 10% every 500ms 

     if (dutycycle > 100) // if duty cycle is greater than 100% set to 0 
     { 
      dutycycle = 0; 
     } 
    } 
} 

ISR(TIMER0_OVF_vect) 
{ 
    OCR0A = (dutycycle/100) * 255; // Set duty cycle ON period 
} 

답변

3

나는 당신의 접근 방식의 논리 모르겠지만, 분명한 문제를 볼 수 있습니다 너를 괴롭 히고있다.

정수 부분은 소수를 생성하지 않습니다. 대신 결과를 가장 가까운 정수로 반올림합니다. 즉, dutycycle <= 100을 보장하므로 dutycycle/100은 거의 항상 0이됩니다. 그래서 OCR0Adutycycle 정확히이 대신 OCR0A = dutycycle * 255/100;을 사용하는 것입니다 주위에 OCR0A

한 255 방법을 설정 100 일 때 한 가지 예외는 거의 항상 0입니다. 이것이 모든 문제를 해결할 수 있는지, 나는 단지 처음 보는 것을 나는 모른다.

+0

100 %에 도달 할 때까지 듀티 사이클을 10 % 씩 늘리려고합니다. 이 경우 듀티 사이클 값을 다시 0으로 재설정하고 반복합니다. 코드 상단의 정수 값을 변경할 때만 출력을 얻습니다. 주 내부의 계산이 무시되고 OCR0A가 듀티 사이클 정수에 할당되는 것 같습니다. 내가 제안한 변화를 만들었지 만 여전히 운이 없다. – LoneCoder