arduino pwm 不使用库函数
时间: 2025-04-17 08:52:50 浏览: 30
### 不使用库函数在 Arduino 中实现 PWM
PWM (脉宽调制) 是通过改变信号高电平持续时间的比例来调整输出功率的技术。如果不借助现成的库,在 Arduino 上可以通过定时器中断和直接操作寄存器的方式创建自定义的 PWM 输出。
#### 使用定时器中断模拟 PWM
对于基于 AVR 微控制器(如 ATmega328P, 常见于 Uno 板卡),可以利用硬件定时器触发中断服务程序(ISR), 在其中手动切换 GPIO 引脚状态以形成期望占空比的方波:
```cpp
volatile uint8_t toggle = LOW;
const unsigned long period = 100; // 完整周期的时间(us)
unsigned long dutyCycle = 75; // 占空比百分数(%)
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
noInterrupts(); // 关闭所有中断
TCCR1A = 0; // 设置整个TCCR1x寄存器为0
TCCR1B = 0;
TCNT1 = 0; // 初始化计数值为0
OCR1A = F_CPU / 64 / 1000 - 1; // 设定比较匹配值,这里假设预分频因子为64
// 并希望每毫秒发生一次溢出事件
TIMSK1 |= _BV(OCIE1A); // 开启比较匹配中断允许位
TCCR1B |= _BV(WGM12); // 启用 CTC 模式
TCCR1B |= _BV(CS11) | _BV(CS10); // 预分频因子设为64
interrupts(); // 打开全局中断
}
ISR(TIMER1_COMPA_vect){
static unsigned long startTimeMicros;
unsigned long nowTimeMicros = micros();
if(nowTimeMicros - startTimeMicros >= dutyCycle * period / 100UL){
digitalWriteFast(LED_BUILTIN,!toggle);
startTimeMicros += period;
toggle=!toggle;
}
}
```
上述代码片段展示了如何配置 Timer1 进入 Clear Timer on Compare Match (CTC) 工作模式,并设定每隔一定间隔触发 ISR 。每次进入 ISR ,都会检查当前时刻是否达到了预期的高电平宽度;一旦达到,则翻转引脚电平并重置起始时间戳以便计算下一个周期内的高低电平转换点[^1]。
需要注意的是 `digitalWriteFast()` 函数并非标准 Arduino 库的一部分而是来自第三方优化过的写法用于加速 I/O 操作速度。如果目标平台不支持该指令则应回退至普通的 `digitalWrite()` 方法尽管性能会有所下降。
阅读全文
相关推荐


















