找回密码
 立即注册
查看: 66|回复: 3

PWM

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:3
  • 最近打卡:2025-10-25 08:45:22
已绑定手机

5

主题

1

回帖

29

积分

新手上路

积分
29
发表于 7 天前 | 显示全部楼层 |阅读模式
使用库函数在PWM中断中计数中断个数,但第二触发点中断达到四个时关闭pwm,但是会出现如图情况
截图202510250956084289.jpg
回复

使用道具 举报 送花

3

主题

1848

回帖

544

积分

等待验证会员

积分
544
发表于 7 天前 | 显示全部楼层
关于您在使用国芯人工智能(CXAI)或通用MCU进行PWM控制时遇到的问题,即“在PWM中断中计数中断个数,当第二触发点中断达到四个时关闭PWM,但出现了异常情况”,我们在此进行技术分析与建议。

一、问题描述回顾

您在使用库函数配置PWM,并在PWM中断中对中断次数进行计数。当检测到“第二触发点中断”达到4次时,关闭PWM输出。然而实际运行过程中出现了异常现象,具体表现为PWM未能如期关闭,或关闭时机不准确,甚至出现程序异常。

二、可能原因分析

1. 中断服务函数执行时间过长
若在中断服务函数中执行复杂逻辑(如多次条件判断、计数器操作、关闭PWM等),可能导致中断嵌套或中断响应延迟。
特别是在高频率PWM下,中断触发间隔短,若未及时退出中断服务函数,可能造成中断堆积。

2. 计数逻辑设计存在竞争条件
若中断计数变量为全局变量,且未使用volatile修饰,编译器可能进行优化,导致变量值未及时更新。
若多个中断源共用一个中断服务函数,未正确区分“第二触发点”中断来源,可能误计数。

3. PWM关闭操作未正确执行
关闭PWM通常需要调用特定库函数或寄存器操作,若未正确调用或未等待PWM通道稳定关闭,可能导致关闭失败。
某些MCU在关闭PWM后仍会输出一个完整周期的波形,需注意时序。

4. 中断标志未清除
若在中断服务函数中未清除中断标志位,可能导致中断重复触发。
特别是使用比较匹配或周期中断时,需明确清除对应标志。

5. 多通道/多中断源干扰
若使用多个PWM通道或其它外设中断,未正确屏蔽或判断中断源,可能导致误触发。

三、建议解决方案

1. 优化中断服务函数逻辑

中断服务函数应尽可能简洁,仅执行必要操作。例如:
  1. c
  2. volatile uint8t intcount = 0;
  3. void PWMIRQHandler(void) {
  4.     if (PWMGetIntFlag(PWMCHANNEL2)) {
  5.         intcount++;
  6.         if (intcount == 4) {
  7.             PWMStop(PWMCHANNEL2);
  8.         }
  9.         PWMClearIntFlag(PWMCHANNEL2);  // 清除中断标志
  10.     }
  11. }
复制代码

2. 使用 volatile 修饰中断计数器

确保中断服务函数中使用的计数器变量不会被编译器优化:
  1. c
  2. volatile uint8t intcount = 0;
复制代码

3. 确保中断标志清除

在每次进入中断服务函数后,必须清除对应中断标志,否则可能重复进入中断。
  1. c
  2. PWMClearIntFlag(PWMCHANNEL2);
复制代码

4. 检查PWM关闭函数调用方式

确认关闭PWM的函数是否正确调用,并是否真正停止了输出。例如:
  1. c
  2. PWMStop(PWMCHANNEL2);
复制代码

部分MCU还需关闭PWM模块时钟或使能位,需参考数据手册。

5. 使用调试工具辅助分析
使用逻辑分析仪或示波器观察PWM波形与中断触发时刻。
在中断服务函数中添加调试输出(如通过串口打印intcount),确认计数逻辑是否正常。

6. 增加状态判断与保护机制

可加入状态标志,防止多次关闭PWM或误操作:
  1. c
  2. volatile uint8t pwmstopped = 0;
  3. void PWMIRQHandler(void) {
  4.     if (PWMGetIntFlag(PWMCHANNEL2) && !pwmstopped) {
  5.         intcount++;
  6.         if (intcount == 4) {
  7.             PWMStop(PWMCHANNEL2);
  8.             pwmstopped = 1;
  9.         }
  10.         PWMClearIntFlag(PWMCHANNEL2);
  11.     }
  12. }
复制代码

四、常见错误示例与修正

错误示例:
  1. c
  2. void PWMIRQHandler(void) {
  3.     intcount++;
  4.     if (intcount == 4) {
  5.         PWMStop();
  6.     }
  7. }
复制代码

问题:
未清除中断标志,可能导致重复中断。
未判断中断来源,若多个通道共用中断函数,可能误操作。
未使用volatile修饰intcount,变量可能未被更新。

正确写法:
  1. c
  2. volatile uint8t intcount = 0;
  3. void PWMIRQHandler(void) {
  4.     if (PWMGetIntFlag(PWMCHANNEL2)) {
  5.         intcount++;
  6.         if (intcount == 4) {
  7.             PWMStop(PWMCHANNEL2);
  8.         }
  9.         PWMClearIntFlag(PWMCHANNEL2);
  10.     }
  11. }
复制代码

五、总结

在使用PWM中断进行计数控制时,务必注意以下几点:

1. 中断服务函数应简洁高效,避免复杂逻辑;
2. 全局变量应使用volatile修饰;
3. 必须清除中断标志;
4. 正确调用PWM关闭函数;
5. 防止误触发与重复操作;
6. 使用调试手段辅助排查问题。

如能按照上述建议优化代码逻辑与中断处理流程,应能有效解决“第二触发点中断达到四个时关闭PWM”时出现的异常情况。

如仍有问题,建议提供具体代码片段与示波器截图,以便进一步分析。

国芯人工智能(CXAI)技术支持团队  
2024年10月

[本文内容由国芯人工智能辅助生成,仅供参考]
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:544
  • 最近打卡:2025-10-31 09:14:02
已绑定手机

48

主题

2300

回帖

8120

积分

论坛元老

积分
8120
发表于 7 天前 | 显示全部楼层
可参考ISP软件里面的例子
截图202510251411575072.jpg
回复

使用道具 举报 送花

  • 打卡等级:以坛为家III
  • 打卡总天数:606
  • 最近打卡:2025-11-01 11:29:35
已绑定手机
已实名认证

122

主题

2948

回帖

7664

积分

版主

积分
7664
发表于 7 天前 | 显示全部楼层
如果是计多少个脉冲后关闭PWM,可以使用PWM的重复计数器
截图202510251425097793.jpg
直接设置重复计数器为所需脉冲个数,这样可以进入中断时直接关闭PWM
设置之前记得使用PWMx_EGR = 0x01;(x为A或者B)来更新一次计数器配置和清零计数器
截图202510251426582217.jpg
回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-11-1 22:13 , Processed in 0.126193 second(s), 67 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表