簡體   English   中英

如何使用Pwm Atmega AVR增加亮度或使LED變暗

[英]How to increase brightness or dim the LED using pwm atmega avr

我不知道為什么,但不是增加亮度,而是增加LED脈沖,每個脈沖之間的間隔越來越短。 這是從教程中復制的代碼,在他的視頻中效果很好,但對我來說,即使在模擬器中也沒有。 怎么會這樣

使用AVR 328p。

#define F_CPU   20000000

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

double dutyCycle = 0;

int main(void)
{   
    DDRD = (1 << PORTD6);
    TCCR0A = (1 << COM0A1) | (1 << WGM00) | (1 << WGM01);
    TIMSK0 = (1 << TOIE0);
    OCR0A = (dutyCycle/100.0)*255.0;
    sei();

    TCCR0B = (1 << CS00) | (1 << CS02);
    while(1)
    {
        _delay_ms(100);
        dutyCycle += 10;
        if(dutyCycle > 100){
            dutyCycle = 0;
        }                       
    }
}

ISR(TIMER0_OVF_vect){ OCR0A = (dutyCycle/100.0)*255;}

1)如果在主代碼和中斷中同時使用某些變量,則必須將其標記為volatile 然后,對其的每次讀取或寫入都將被編譯為相應存儲單元的讀取/寫入。 否則,編譯器可以進行優化,從而最大程度地減少內存訪問。 因此,在中斷中看不到寫入主程序內部的變量。

2)為什么要使用double 除非非常有必要,否則不要使用浮點數。 AVR不支持浮點運算的硬件,因此每個浮點運算將表示為多個運算。 在您的示例中,使用從0到255的整數變量不會停止任何事情。即使您要使用0-100范圍變量,也可以使用整數算術重新計算它。

3)注意更新超過1個字節長的變量。 AVR是8位架構。 這意味着,要更新內存中超過8位寬的變量,需要執行一系列的多次操作。 長度為8個字節的double ,需要太多此類操作。 該中斷可能在該系列的中間時刻觸發,這意味着在ISR內部獲取的變量的值將僅部分更新,從而導致不可預測的結果。 在主代碼中, cli() - sei()任何更新都將在ISR內部使用,且變量的更新應超過1個字節。

3)避免在ISR中進行艱難的計算。 根據經驗:任何ISR都應盡快完成,所有密集的計算都應放在ISR之外。

4)在此示例中,您完全不需要ISR! 您可以在主代碼中編寫OCR0A。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM