pwm value not changing



我为Atmega128编写了PWM代码。我正在使用比较匹配时使用的快速PWM模式,并使用非转换脉冲,我需要在某些时间更改OCR0值。但是它不会改变。有人知道这里有什么问题?

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

uint8_t tick_1sec;

void timer1_init(void) // 1 second timer
{
    OCR1A = 15624;
    TIMSK |= (1<<OCIE1A);
    TCCR1B = (1<<WGM12);        //CTC mode
    TCCR1B |= (1<<CS12)|(0<<CS11)|(1<<CS10);    
}

ISR(TIMER1_COMPA_vect)  //1 second interrupt
{
    cli();
    tick_1sec = 1;
    sei();          
}

void timer0_init(void) // fast pwm with OC0 non-inverting mode
{
    TCCR0 = (1<<FOC0)|(1<<WGM01)|(1<<WGM00);
    TCCR0 |= (1<<COM01)|(0<<COM00);
    TCCR0 |= (1<<CS02)|(1<<CS01)|(1<<CS00);
    OCR0 = 63;
    TIMSK |= (1<<OCIE0);
}

int main(void)
{
    uint8_t t = 0;
    DDRB = 0xFF;
    timer0_init();      
    timer1_init();
    sei();
    while(1){
        if (tick_1sec)
        {
            tick_1sec = 0;
            t++;
            if (t == 10){
                OCR0 = 127;
            }
            else if (t == 20){
                OCR0 = 191;
            }
            else if (t == 30){
                OCR0 = 63;
                t = 0;
            }
        }
    }
    return 0;
}

要检查的东西:

我建议将tick_1sec声明为 volatile,以防止寄存器超优化的编译器。

您的时钟频率是多少?仅当您的CPU频率为16MHz(==> 16.000.000/1024/15624)

时,您的ISR才会接送1次呼叫

您可能在硬件中有一个LED,可以从a) ISR b)中倒入if ()中的第一个CC_4中,以查看是否达到了这一点。

更新:" volatile"

@skyrift在他的评论中提供的链接非常值得一读。

当您使用Atmel Studio时,使用/不使用volatile关键字进行编译一次,并比较编译器在做什么==>解决方案Explorer/Output Files/*.lss ...您将看到每个C语句以及如何编译器将其转换为机器代码...与Micros一起工作时偶尔值得的练习...

最新更新