【问题标题】:pwm value not changingpwm 值不变
【发布时间】:2014-01-21 07:52:09
【问题描述】:

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

【问题讨论】:

  • 请用四个空格正确格式化您的代码。

标签: avr pwm


【解决方案1】:

检查事项:

我建议将tick_1sec 声明为volatile 以防止编译器对该寄存器进行超优化。

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

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

更新:“易失性”

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

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

【讨论】:

  • 这几乎肯定是问题所在 - avr-gcc 将清除在中断中修改但未声明为 volatile 的大多数变量。请参阅此处的第 5 部分:avrfreaks.net/…
  • 我花时间查看它并修改了代码,正如您所说的,其他部分相同。我不知道确切的原因,但后来它起作用了。将 Tick_1sec 声明为 volatile 变量很可能是原因。谢谢你..
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-05
  • 1970-01-01
  • 2015-10-06
  • 2023-04-10
  • 1970-01-01
相关资源
最近更新 更多