You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ATmega328 Timer1快速PWM模式15配置异常及无信号问题排查

问题分析与解决方案

核心疑问解答

  • 比较输出模式(COM)选择:
    对于OC1B的非反相PWM,需设置COM1B1=1且COM1B0=0——此时定时器计数到OCR1B时,OC1B引脚电平清零;计数到TOP值(OCR1A)时,引脚电平置位。如果是反相PWM,则设置COM1B1=1且COM1B0=1,电平翻转逻辑相反。若COM1B1=0,无论COM1B0取值如何,定时器都不会驱动OC1B引脚,引脚仅受GPIO寄存器控制。

  • OC1A/OC1B断开的含义:
    当COMx1=0时,定时器的比较匹配模块与OCxA/OCxB引脚“断开”,引脚不再受定时器控制,仅作为普通IO口使用,电平由DDR和PORT寄存器决定。

  • 模式15下OC1A的作用:
    快速PWM模式15(WGM1[3:0]=0b1111)的TOP值固定为OCR1A寄存器的值,和OC1A引脚是否配置为输出无关。即使OC1A断开(COM1A1=0),OCR1A依然承担TOP值的角色,定时器的计数周期由它决定,只是OC1A引脚不会输出PWM信号。

代码错误与修正

你的代码中预分频器配置错误是导致PB2无输出的核心原因:Timer1的预分频位是CS12、CS11、CS10,而非Timer0的CS02、CS00。错误的配置导致定时器未启动,自然没有PWM输出。

修正后的代码如下:

void setup(){
    DDRB |= (1 << PB2) | (1 << PB1);  // 设置OC1A(PB1)和OC1B(PB2)为输出

    // 配置快速PWM模式15(WGM1[3:0]=0b1111)
    // OC1B非反相PWM(COM1B1=1, COM1B0=0)
    TCCR1A |= (1 << COM1B1) | (1 << WGM11) | (1 << WGM10);
    // 配置TOP=OCR1A,预分频器1024(CS12=1, CS10=1)
    TCCR1B |= (1 << WGM13) | (1 << WGM12) | (1 << CS12) | (1 << CS10);
    
    TCNT1 = 0; // 重置计数器

    // 计算100Hz频率的TOP值:OCR1A = (16000000/(100*1024)) -1 = 155
    OCR1A = 155;
    OCR1B = 77; // 50%占空比((77+1)/(155+1)=50%)
}
void loop() {}

额外说明

  • 全局中断(SREG |= 0b10000000)无需开启,硬件PWM不需要中断支持,可直接删除该行。
  • 非反相PWM的占空比公式为(OCR1B + 1)/(TOP + 1),设置OCR1B=77时,占空比为78/156=50%,符合需求。

内容的提问来源于stack exchange,提问作者paxel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 14:50:02