【问题标题】:PWM with ATMega164PA带 ATMega164PA 的 PWM
【发布时间】:2017-02-16 12:56:52
【问题描述】:

我正在尝试使用 ATMega164PA 上的 Timer0 的 PWM 来增加 LED 的亮度。在 LED 下运行我的代码后,LED 只会保持发光状态,不会改变其亮度。

请查看我的代码,如果我做错了什么,请告诉我:

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

int dutycycle = 0;  // Variable for dutycycle 

/********************************************** MAIN ****************************************************/
int main(void)
{
    DDRB |= (1 << PB3); // Make pins output and OC0A pin for PWM 

    TCCR0A |= (1 << COM0A1) | (1<<WGM01) | (1<<WGM00);  // Clear OC0A on comare match and set OC0A at BOTTOM

    TIMSK0 |= (1<<TOIE0);   // Overflow Interrupt Enabled 

    TCNT0 = 0;  // Set Counter Value Register for comparison with OCR0A

    OCR0A = (dutycycle / 100) * 255;    // Set duty cycle ON period

    sei();      // Enable global interrupts 

    TCCR0B |= (1 << CS00);  // Prescale of 1 - start timer 

    while (1)
    {
        _delay_ms(500);

        dutycycle += 10;        // increase duty cycle by 10% every 500ms 

        if (dutycycle > 100)    // if duty cycle is greater than 100% set to 0
        {
            dutycycle = 0; 
        }
    }
}

ISR(TIMER0_OVF_vect)
{
    OCR0A = (dutycycle / 100) * 255;    // Set duty cycle ON period
}

【问题讨论】:

    标签: c microcontroller avr pwm atmega16


    【解决方案1】:

    我不确定你的方法的逻辑,但我可以看到一个明显的问题,它给你带来了困难。

    整数除法不会产生分数。相反,它将结果向下舍入到最接近的整数。这意味着dutycycle / 100 几乎总是为0,因为您确保dutycycle &lt;= 100。所以OCR0A 几乎总是 0。一个例外是当dutycycle 正好是 100 时,它将OCR0A 设置为 255。

    解决此问题的一种方法是改用OCR0A = dutycycle * 255 / 100;。我不知道这是否会解决所有问题,只是我看到的第一个问题。

    【讨论】:

    • 我正在尝试将占空比增加 10%,直到达到 100%。发生这种情况时,我想将占空比值重置为 0 并重复。当我更改代码顶部的整数值时,我只会得到一个输出,似乎 main 内部的计算被忽略了,而 OCR0A 只是被分配给占空比整数。我做了你建议的改变,但仍然没有运气:(
    猜你喜欢
    • 1970-01-01
    • 2023-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-06
    • 2023-04-10
    相关资源
    最近更新 更多