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

ATmega88PB配置相位频率校正PWM时OCR1A引脚持续高电平求助

问题描述

在ATmega88PB单片机上实现相位频率校正PWM功能时,编写了如下PWM初始化函数:

void PWM_INIT2()
{
DDRB|=(1<<PINB1) | (1<<PINB2);
TCCR1B |= (1<<WGM13) |  (1<<CS10);
TCCR1A |= (1<<COM1B0) | (1<<COM1B1) | (1<<COM1A1);
}

将该初始化函数加入主函数运行后,OCR1A对应的输出引脚始终保持高电平,主函数代码如下:

int main(void)
{
  PWM_INIT2();

  while (1) 
  {
            
  }
}
问题根源
  • PWM计数周期上限未配置:当前代码中WGM13置1、其余WGM1位为0,对应定时器1相位频率校正PWM模式8,该模式的计数TOP值由ICR1寄存器决定。代码未给ICR1赋值,芯片上电后ICR1默认值为0,定时器无法完成正常的上下计数循环。
  • OCR1A比较值未初始化:芯片上电后OCR1A默认值为0,配合当前设置的COM1A1置1的非反转PWM输出规则,没有有效比较匹配事件触发引脚电平翻转,最终引脚持续锁死高电平。
  • 寄存器配置未做前置清零:直接使用|=操作写TCCR1A、TCCR1B寄存器,没有先清除寄存器上电后的默认残留值,可能混入无关配置位导致PWM运行逻辑异常。
  • OC1B输出配置错误:代码同时置位COM1B0和COM1B1,在相位频率校正PWM模式下该配置为比较匹配时OC1B引脚电平反转,不是常规的固定占空比PWM输出模式,会导致OC1B输出不符合预期。
可行解决方案

修正后的初始化参考代码如下(以系统时钟8MHz、输出200Hz PWM为例):

void PWM_INIT2()
{
  // 配置OC1A(PB1)、OC1B(PB2)为输出方向
  DDRB |= (1<<PINB1) | (1<<PINB2);
  
  // 先清零定时器1控制寄存器,排除默认值干扰
  TCCR1A = 0;
  TCCR1B = 0;
  
  // 配置相位频率校正PWM模式(模式8,TOP=ICR1),无预分频
  TCCR1B |= (1<<WGM13) | (1<<CS10);
  // OC1A、OC1B均配置为非反转PWM输出
  TCCR1A |= (1<<COM1A1) | (1<<COM1B1);
  
  // 设置PWM周期TOP值,8MHz无预分频下PWM频率=8000000/(2*ICR1)
  ICR1 = 20000;
  // 设置OCR1A比较值,对应50%占空比
  OCR1A = 10000;
  // 设置OCR1B比较值,对应25%占空比
  OCR1B = 5000;
}

配置注意事项:

  • 选择相位频率校正PWM模式时,必须根据所选WGM组合给对应的TOP源寄存器(ICR1或OCR1A)赋值大于0的有效值,否则定时器无法启动正常计数循环。
  • 启动PWM前必须给OCR1x寄存器设置小于TOP值的初始比较值,避免输出电平锁死。
  • 配置定时器功能寄存器前建议先将寄存器清零,避免复位残留值导致功能异常。
  • COM位配置要匹配输出需求:常规非反转PWM输出仅需置位COM1x1,同时置位COM1x0会开启比较匹配反转功能,占空比逻辑会偏离预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 18:51:18