Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Width AVR Studio上的脉宽调制(PWM)_Width_Avr_Pulse_Atmega - Fatal编程技术网

Width AVR Studio上的脉宽调制(PWM)

Width AVR Studio上的脉宽调制(PWM),width,avr,pulse,atmega,Width,Avr,Pulse,Atmega,我正在尝试对ATmega8上的LED使用PWM,端口B的任何引脚。设置计时器一直很烦人,我不知道如何处理我的OCR1A。这是我的代码,我希望得到一些反馈 我只是想弄清楚如何使用PWM。我知道这个概念,OCR1A应该是我想要脉冲开启的整个计数器时间的分数 #define F_CPU 1000000 // 1 MHz #include <avr/io.h> #include <avr/delay.h> #include <avr/interrupt.h> i

我正在尝试对ATmega8上的LED使用PWM,端口B的任何引脚。设置计时器一直很烦人,我不知道如何处理我的OCR1A。这是我的代码,我希望得到一些反馈

我只是想弄清楚如何使用PWM。我知道这个概念,OCR1A应该是我想要脉冲开启的整个计数器时间的分数

#define F_CPU 1000000  // 1 MHz

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

int main(void){

    TCCR1A |= (1 << CS10) | (1 << CS12) | (1 << CS11);
    OCR1A = 0x0000;
    TCCR1A |= ( 0 << WGM11 ) | ( 1 << WGM10 ) | (WGM12 << 1) | (WGM13 << 0);
    TCCR1A |= ( 1 << COM1A0 ) | ( 0 << COM1A1 );
    TIMSK |= (1 << TOIE1); // Enable timer interrupt
    DDRB = 0xFF;
    sei(); // Enable global interrupts
    PORTB = 0b00000000;

    while(1)
    {
        OCR1A = 0x00FF; //I'm trying to get the timer to alternate being on for 100% of the time,
        _delay_ms(200);
        OCR1A = 0x0066; // Then 50%
        _delay_ms(200);
        OCR1A = 0x0000; // Then 0%
        _delay_ms(200);
    }
}

ISR (TIMER1_COMA_vect)  // timer0 overflow interrupt
{
    PORTB =~ PORTB;
}
#定义F_CPU 1000000//1 MHz
#包括
#包括
#包括
内部主(空){

TCCR1A |=(1您需要使用以下两行初始化OCR1A:

TCCR1A = (1 << WGM10) | (1 << COM1A1);
TCCR1B = (1 << CS10) | (1 << WGM12);
知道范围是0-255。数一数你的百分比,就知道了

#define F_CPU 1000000  // 1 MHz
#include <avr/io.h>
#include <avr/delay.h>
#include <avr/interrupt.h>

int main(void){
    TCCR1A = (1 << WGM10) | (1 << COM1A1);
    TCCR1B = (1 << CS10) | (1 << WGM12);
    DDRB = 0xFF;
    sei(); // Enable global interrupts
    PORTB = 0b00000000;

    while(1)
    {
        OCR1A = 255;
        _delay_ms(200);
        OCR1A = 125;
        _delay_ms(200);
        OCR1A = 0;
        _delay_ms(200);
    }
}
#定义F_CPU 1000000//1 MHz
#包括
#包括
#包括
内部主(空){

TCCR1A=(1No,这不是您应该如何进行PWM的方式。例如,如何使用它设置PWM速率,例如42%?此外,代码大小很大,可以以更有效的方式进行。此外,您还浪费了一个16位计时器来进行8位操作。您有2个8位计时器(计时器/计数器0和2),以及一个16位计时器,
计时器/计数器1

将未使用的端口引脚设置为输出也是一个坏主意。所有未连接到任何东西的端口引脚都应保留为输入

ATmega8在定时器1和定时器2上有一个内置的PWM发生器,无需通过软件进行模拟。您甚至不必手动设置端口(只需将相应的端口引脚设置为输出)

你甚至不需要任何打扰

#define fillrate OCR2A 


 //...

 // main()

PORTB=0x00;
DDRB=0x08;  //We use PORTB.3 as output, for OC2A, see the atmega8 reference manual

// Mode: Phase correct PWM top=0xFF
// OC2A output: Non-Inverted PWM
TCCR2A=0x81;
// Set the speed here, it will depend on your clock rate.
TCCR2B=0x02;

// for example, this will alternate between 75% and 42% PWM
while(1)
{
    fillrate = 191; // ca. 75% PWM
    delay_ms(2000);

    fillrate = 107; // ca. 42% PWM
    delay_ms(2000);
}

请注意,您可以使用另一个LED和另一个PWM,方法是使用相同的计时器并设置OCR2B而不是OCR2A。不要忘记设置TCCR2A以启用OCR2B作为PWM的输出,因为在本例中,仅允许OCR2A。

已回答,将于明天(8小时后)发布.为了更深入地理解,我建议阅读数据表:讨论中没有太多需要补充的内容,请注意,如果您使用
PINB=0xff
而不是
PORTB=~PORTB
,切换pin会更快。当然,如果您绝对需要使用Timer1,因为您的硬件已经完成,您可以使用TC执行同样的操作CR1和OCR1而不是2。当然,我对计时器初始化的值进行了硬编码,以说明设置了哪些位,您可以使用奇特的宏来代替。您在哪里找到寄存器TCCR2A?我只在数据表中找到TCCR2。另外,我想提一下,更可读的方法是将要设置的位左移:
TCCR2=(1)你的帖子让我意识到我必须让OCR1B大于0才能看到非平凡的PWM输出。谢谢。我宁愿轮询计时器值,或者设置一个中断来更改比较寄存器的值。
#define fillrate OCR2A 


 //...

 // main()

PORTB=0x00;
DDRB=0x08;  //We use PORTB.3 as output, for OC2A, see the atmega8 reference manual

// Mode: Phase correct PWM top=0xFF
// OC2A output: Non-Inverted PWM
TCCR2A=0x81;
// Set the speed here, it will depend on your clock rate.
TCCR2B=0x02;

// for example, this will alternate between 75% and 42% PWM
while(1)
{
    fillrate = 191; // ca. 75% PWM
    delay_ms(2000);

    fillrate = 107; // ca. 42% PWM
    delay_ms(2000);
}