2017-04-15 87 views
0

我是AVR C编程新手,我正在用Atmega328p计数器/定时器上的16位定时器测试一个简单的PWM,它可以用作LED的调光器。16位定时器PWM LED调光器

我的代码:

#define F_CPU 16000000UL 

void initTimer(); 

int x = 1; 
int n = 1000; 

int main(void) 
{ 

    initTimer(); 

    DDRB |= (1 << PB1)| (1 << PB2); 

    while(1) 
    { 
     x++; 

     if(x > 65) { 
      x = 1; 
     } 
    } 
} 

void initTimer() { 

    TCCR1A = (1 << COM1A1) | (1 << COM1B1) | (1 << WGM11); 
    TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS11); 
    // used for TOP, makes for 50 Hz PWM 
    ICR1 = 40000; 
    OCR1A = n * x; 

} 

ISR(TIMER1_OVF_vect) 
{ 
    OCR1A = n * x; 
} 

问题是,它不显示变暗效果,LED的亮度保持不变,以任何值I为OCR1A(PB1)的输出引脚初始设定,其假设当中断发生时改变值,但它只是不这样做,这是假设是简单的测试我做错了什么?

更新:

至于建议,我能够使用TIMSK1寄存器和SEI(),但仍是同样的问题,LED的亮度保持恒定的中断来不管这是在指定OCR1A的原始值initTimer()。

int main(void) 
{ 
    initTimer(); 
    DDRB |= (1 << PB1)| (1 << PB2); 

    while(1) 
    { 
     x++; 
     if(x > 65) { 
      x = 1; 
     } 
    } 
} 

void initTimer() { 

    ICR1 = 40000; 
    OCR1A = n * x; 
    TCCR1A = (1 << COM1A1) | (1 << COM1B1) | (1 << WGM11); 
    TIMSK1 |= (1 << ICIE1); 
    TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS11); 
    sei(); 
} 

ISR (TIMER1_COMPA_vect) 
{ 
    OCR1A = n * x; 
} 

虽然我尝试另一种办法,这给了我调光影响:

int main(void) 
{ 

    initTimer(); 

    DDRB |= (1 << PB1)| (1 << PB2); 

    while(1) 
    { 
     _delay_ms(20); 
     OCR1A = n * 4; 
     _delay_ms(20); 
     OCR1A = n * 8; 
     _delay_ms(20); 
     OCR1A = n * 15; 
     _delay_ms(20); 
     OCR1A = n * 25; 
     _delay_ms(20); 
     OCR1A = n * 1; 

    } 
} 

void initTimer() { 

    ICR1 = 40000; 
    OCR1A = n * x; 
    TCCR1A = (1 << COM1A1) | (1 << COM1B1) | (1 << WGM11); 
    TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS11); 

} 

如此看来问题是与中断,因为PWM影响的作品,但它只是没有与中断处理工作。

回答

1

跳出来的第一件事是x和n应该是易变的。您还应该在TIMSK0寄存器中启用中断。通过调用sei启用中断。

如果我是你,我会从一些知道好的示例代码开始。我提到的页面有一个例子,每4ms触发一次中断。采取该代码并打开和关闭LED。

另一个问题是你改变x而不考虑isr是否被调用。所以实际上你每次都会在isr中得到一个随机的x。这段代码很简单,可能会陷入简单模式。而是将x的设置移动到您的isr。

这是一个很好的介绍avr定时器:https://sites.google.com/site/qeewiki/books/avr-guide/timers-on-the-atmega328