0

我为 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;
}
4

1 回答 1

2

检查事项:

我建议声明tick_1secvolatile防止编译器对该寄存器进行超优化。

你的时钟频率是多少?仅当您的 CPU 频率为 16MHz (==> 16.000.000 / 1024 / 15624) 时,您的 ISR 才会提供 1s 调用

您的硬件中可能有一个 LED,您可以在第一个输入中从 a) 和ISRb)反转它,看看是否曾经达到。if ()main

更新:“易失性”

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

当您使用 Atmel Studio 时,使用/不使用volatile关键字编译一次代码并比较编译器正在执行的操作 ==> 解决方案资源管理器 / 输出文件 / *.lss ...您将看到每个 C 语句以及编译器如何将其转换为机器代码......在使用微机时值得偶尔进行一次练习......

于 2014-01-21T18:18:30.643 回答