c语言 - 引脚在 CTC 模式下不切换



我正在尝试以给定频率在CTC模式下切换OC1A引脚(PB1(。但 PB1 不会切换。如果我尝试使用中断切换引脚,一切正常,但对于我的项目,有必要在不中断的情况下进行。也许我错过了什么?

我在Atmega328P上使用Arduino Nano。根据数据表:

表 15-2.比较输出模式,非PWM

COM1A1/COM1B1COM1A0/COM1B0 说明

00 端口操作正常,OC1A/OC1B 已断开连接。

0 1 在比较匹配时切换 OC1A/OC1B。

1 0 在比较匹配时清除 OC1A/OC1B(将输出设置为低电平(。

11 在比较匹配时设置 OC1A/OC1B(将输出设置为高电平(。

如果我是对的,可以设置 COM1A0 位,OC1A 将在 TCNT1 达到 TOP 值时切换。但是在我的代码中它不起作用:

#include <Arduino.h>
void setup() {
DDRB |= (1<<PB1);
PORTB &= ~(1<<PB1); 
TCCR1B |= (1<<CS11)|(1<<WGM12); //prescaler 8 CTC mode with TOP on OCR1A
TCCR1A |= (1<<COM1A0); //toggle PB1
TCNT1 = 0;
OCR1A = 30000;
}
void loop() {

}

如果我使用中断端口正在切换,但更改 OCR1A 对频率没有影响。

#include <Arduino.h>
void setup() {
DDRB |= (1<<PB1);
PORTB &= ~(1<<PB1); 
TCCR1B |= (1<<CS11)|(1<<WGM12); //prescaler 8 CTC mode with TOP on OCR1A
TCCR1A |= (1<<COM1A0); //toggle PB1
TCNT1 = 0;
OCR1A = 30000;
TIMSK1 |= (1<<OCIE1A);
}
void loop() {

}
ISR(TIMER1_COMPA_vect)
{
PINB = (1<<PB1);
}

是否可以在 CTC 中使用 OCR1A 作为顶部时切换 OC1A?或者我必须使用 WGM13:0=12 和 ICR1 作为 TOP?

问题是你假设那些寄存器中所有位的值都是0。Arduino代码将计时器用于自己的目的,因此这不是一个好的假设。您应该设置/清除您关心其值的所有位。

你忘了设置名为sei((的全局中断标志。 您的代码准备了所有内容,但未设置全局中断标志。 在 void setup(( 中,添加 sei(( 以启用它,并添加 cli(( 以禁用全局中断标志。

最新更新