我是AVR C編程新手,我正在用Atmega328p計數器/定時器上的16位定時器測試一個簡單的PWM,它可以用作LED的調光器。16位定時器PWM LED調光器
我的代碼:
#define F_CPU 16000000UL
void initTimer();
int x = 1;
int n = 1000;
int main(void)
{
initTimer();
DDRB |= (1 << PB1)| (1 << PB2);
while(1)
{
x++;
if(x > 65) {
x = 1;
}
}
}
void initTimer() {
TCCR1A = (1 << COM1A1) | (1 << COM1B1) | (1 << WGM11);
TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS11);
// used for TOP, makes for 50 Hz PWM
ICR1 = 40000;
OCR1A = n * x;
}
ISR(TIMER1_OVF_vect)
{
OCR1A = n * x;
}
問題是,它不顯示變暗效果,LED的亮度保持不變,以任何值I爲OCR1A(PB1)的輸出引腳初始設定,其假設當中斷髮生時改變值,但它只是不這樣做,這是假設是簡單的測試我做錯了什麼?
更新:
至於建議,我能夠使用TIMSK1寄存器和SEI(),但仍是同樣的問題,LED的亮度保持恆定的中斷來不管這是在指定OCR1A的原始值initTimer()。
int main(void)
{
initTimer();
DDRB |= (1 << PB1)| (1 << PB2);
while(1)
{
x++;
if(x > 65) {
x = 1;
}
}
}
void initTimer() {
ICR1 = 40000;
OCR1A = n * x;
TCCR1A = (1 << COM1A1) | (1 << COM1B1) | (1 << WGM11);
TIMSK1 |= (1 << ICIE1);
TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS11);
sei();
}
ISR (TIMER1_COMPA_vect)
{
OCR1A = n * x;
}
雖然我嘗試另一種辦法,這給了我調光影響:
int main(void)
{
initTimer();
DDRB |= (1 << PB1)| (1 << PB2);
while(1)
{
_delay_ms(20);
OCR1A = n * 4;
_delay_ms(20);
OCR1A = n * 8;
_delay_ms(20);
OCR1A = n * 15;
_delay_ms(20);
OCR1A = n * 25;
_delay_ms(20);
OCR1A = n * 1;
}
}
void initTimer() {
ICR1 = 40000;
OCR1A = n * x;
TCCR1A = (1 << COM1A1) | (1 << COM1B1) | (1 << WGM11);
TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS11);
}
如此看來問題是與中斷,因爲PWM影響的作品,但它只是沒有與中斷處理工作。