找回密码
 立即注册
查看: 228|回复: 19

STC8H8K64U, PWMA 疑似丢失中断信号 | 修改用户程序完善

[复制链接]

4

主题

22

回帖

100

积分

注册会员

积分
100
发表于 2026-8-18 17:01:35 | 显示全部楼层 |阅读模式
#include "Main.h"

#define         ENO1P                                   0x01
#define         ENO1N                                   0x02

#define         ENO2P                                   0x04
#define         ENO2N                                   0x08

#define         ENO3P                                   0x10
#define         ENO3N                                   0x20

#define         ENO4P                                   0x40
#define         ENO4N                                   0x80

#define         ENO5P                                   0x01
#define         ENO6P                                   0x04
#define         ENO7P                                   0x10
#define         ENO8P                                   0x40

void Test_InitPWMA()
{
    PWMA_CR1    = 0;
    PWMA_CR2    = 0;
        
        PWMA_CCER1  = 0;
        PWMA_CCER2  = 0;
        PWMA_SR1    = 0;
        PWMA_SR2    = 0;
        PWMA_CCMR1  = 0;
        PWMA_CCMR2  = 0;
        PWMA_CCMR3  = 0;
        PWMA_CCMR4  = 0;
        PWMA_ENO    = 0;
        PWMA_PS     = 0;
        PWMA_IER    = 0;

    PWMA_DTR    = 0;                  //死区时间配置
    PWMA_PSCR   = 2;                  //预分频寄存器, PWM时钟频率为14.7456MHz
    PWMA_ARR    = 0xFFFF;                        // 自动重装载寄存器,  控制PWM周期

        PWMA_CCMR1  = (3 << 4);        
        PWMA_CCER1 |= 0x01;                        // 开启比较输出, 高电平有效
        PWMA_PS    |= 0x00;                        
        PWMA_ENO   |= ENO1P;                        

        PWMA_CCMR2  = (3 << 4);                        // 通道1模式配置, 禁止预装载. 0: 无输出, 1:匹配时输出高, 2:匹配时输出低, 3:匹配时输出翻转.
        PWMA_CCER1 |= 0x10;                        // 开启比较输出, 高电平有效
        PWMA_PS    |= 0x00;                        
        PWMA_ENO   |= ENO2P;                        


        PWMA_CCMR3  = (3 << 4);                // 通道1模式配置, 禁止预装载. 0: 无输出, 1:匹配时输出高, 2:匹配时输出低, 3:匹配时输出翻转.
        PWMA_CCER2 |= 0x01;                        // 开启比较输出, 高电平有效
        PWMA_PS    |= 0x00;        
        PWMA_ENO   |= ENO3P;                        

        PWMA_EGR    = 0x01;                //产生一次更新事件, 清除计数器和预分频计数器, 装载预分频寄存器的值
        PWMA_BKR    = 0x80;                //主输出使能 相当于总开关

    // 使能计数器, 允许自动重装载寄存器缓冲, 边沿对齐模式, 向上计数,  bit7=1:写自动重装载寄存器缓冲(本周期不会被打扰), =0:直接写自动重装载寄存器本(周期可能会乱掉)
        // 不产生计数器更新事件
        PWMA_CR1    = b0 + b1;                // PWMA_ISR_En = PWMA_IER;        //设置标志允许通道1~4中断处理

    IP2 |= b2;
    IP2H |= b2; //PWMA 优先级最高   

    PWMA_IER |= (b1 + b2 + b3);
}

//[A1]轴 当前点位脉冲输出的下一次的CCR装载值
extern uint A1__PPO_wNextCCR__;

//[A2]轴 当前点位脉冲输出的下一次的CCR装载值
extern uint A2__PPO_wNextCCR__;

//[A3]轴 当前点位脉冲输出的下一次的CCR装载值
extern uint A3__PPO_wNextCCR__;

void PWMA_ISR(void) interrupt PWMA_VECTOR using 1
{
    uchar sr1;
_push_(DPS);
    DPS = 0;
    sr1 = PWM1_SR1;
    PWM1_SR1 = 0;
    PWM1_SR2 = 0;
    if (sr1 & b1) {
        A1__PPO_wNextCCR__ += 922;
        PWMA_CCR1 = A1__PPO_wNextCCR__;
    }
    if (sr1 & b2) {
        A2__PPO_wNextCCR__ += 7373;
        PWMA_CCR2 = A2__PPO_wNextCCR__;
    }
    if (sr1 & b3) {
        A3__PPO_wNextCCR__ += 2458;
        PWMA_CCR3 = A3__PPO_wNextCCR__;
    }
_pop_(DPS);   
}   



PWMA 通过匹配翻转的方式,输出3路不同频率的方波,
大概率出现丢失中断信号(或写CCR不成功)导致波形异常,
下图为波形:


标记为+PW处的波形为异常。是PWM时钟的溢出周期。

标记为+PW处的波形为异常。是PWM时钟的溢出周期。

TestPWM.c

3.33 KB, 下载次数: 3

这个是测试代码

回复

使用道具 举报 送花

4

主题

22

回帖

100

积分

注册会员

积分
100
 楼主| 发表于 2026-8-18 17:05:39 | 显示全部楼层
这个是PWMA中断代码
截图202608181705255442.jpg
回复

使用道具 举报 送花

4

主题

22

回帖

100

积分

注册会员

积分
100
 楼主| 发表于 2026-8-18 17:07:01 | 显示全部楼层
这个是PWMA初始化的代码
截图202608181706305390.jpg
截图202608181706487276.jpg
回复

使用道具 举报 送花

83

主题

8216

回帖

1万

积分

超级版主

积分
17634
发表于 2026-8-18 17:28:23 | 显示全部楼层
中断标志是硬件产生的,不会丢失,是你的中断间隔时间太短,还没处理完就又来中断了,看着像丢失了中断,其实是你来不及处理。PWM中断要设置为最高优先级,别的中断优先级都要比PWM中断的优先级低。最小中断间隔最好在10us以上。
回复

使用道具 举报 送花

4

主题

22

回帖

100

积分

注册会员

积分
100
 楼主| 发表于 2026-8-18 17:47:16 | 显示全部楼层
PWMA 目前的中断优先级是最高的。
截图202608181747159324.jpg
回复

使用道具 举报 送花

4

主题

22

回帖

100

积分

注册会员

积分
100
 楼主| 发表于 2026-8-18 17:54:15 | 显示全部楼层
开启总中断后,没有再执行其它指令和开启其它中断里, 依然存在这个情况。
截图202608181754133693.jpg
回复

使用道具 举报 送花

865

主题

1万

回帖

2万

积分

管理员

积分
25102
发表于 2026-8-18 17:55:44 | 显示全部楼层
截图202608181755366043.jpg

回复

使用道具 举报 送花

865

主题

1万

回帖

2万

积分

管理员

积分
25102
发表于 2026-8-18 17:56:16 | 显示全部楼层

我已经获取了足够的信息。现在我可以全面回答楼主的问题。让我整理内容并结合手册依据、论坛反馈和逻辑分析仪截图来给出一个完整的分析。

关键信息汇总:

  1. 手册依据:AI8H 高级 PWM 的中断配置、PWMA_IER/PWMA_SR1 寄存器、中断优先级(PPWMAH/PPWMA 位)、PWMA 中断向量 interrupt 26。
  2. 论坛回复 3(梁*)**:中断标志是硬件产生的不会丢失,是中断间隔太短来不及处理,看着像丢失中断其实来不及。PWM 中断要设最高优先级,最小中断间隔最好 10us 以上。
  3. 论坛相似案例(tid=22231):同时使用多个高速脉冲时中断标志位丢失,有网友指出"t=PWMA_SR1; PWMA_SR1=0;" 之间若出现新标志会被误杀的问题。还有网友建议多轴控制要用插补。

结合逻辑分析仪截图(三路 PWM,PUL2 为高速密集脉冲序列,PUL1 宽脉冲,PUL3 低速方波),这确实是一个多路 PWM 输出的步进电机控制场景。

让我给出完整的分析回答。


AI8H8K64U PWMA 疑似丢失中断 — 分析与解决建议

楼主您好,我是 STC 的 FAE 工程师。针对您 AI8H8K64U 用 PWMA 做步进电机控制疑似丢失中断 的情况,结合您提供的逻辑分析仪截图、Ai8 手册及 STC 论坛同类案例,为您做如下系统分析。


一、先澄清一个核心概念(手册依据)

从 Ai8 手册「25 16位高级PWM定时器,支持正交编码器」中断一节看,PWMA/PWMB 的中断标志位(PWMA_SR1/PWMA_SR2)是硬件产生的,本身不会"凭空丢失"。PWMA 有 8 个中断请求源:

  • 刹车中断、触发中断、COM 事件中断、输入捕捉/输出比较 4~1 中断、更新事件中断。

标志位置位的条件是硬件事件确实发生了(如计数器与比较值匹配、计数器上溢/下溢等)。所以从纯硬件角度,中断源本身是可靠的。


二、"看起来丢中断"的常见真实原因

原因 1:中断间隔太短,来不及处理(论坛梁工回复,最可能)

论坛回复 3(梁***)的判断非常到位,与手册逻辑一致:

"中断标志是硬件产生的,不会丢失,是你的中断间隔时间太短,还没处理完就又来中断了,看着像丢失了中断,其实是你来不及处理。"

您逻辑分析仪截图中 PUL2 是高速密集的脉冲序列,说明该通道中断频率很高。若在中断服务程序里执行了较多指令(如软件计数、标志翻转、甚至部分 USB 打印),中断处理时间可能超过中断周期,导致:

  • 上一个中断还没退出,下一个中断标志已置位;
  • 若在中断里用"读-清"方式(如 t = PWMA_SR1; PWMA_SR1 = 0;)清标志,中间新进来的中断标志会被一并清掉,看起来就像"丢失"了。

原因 2:中断优先级设置不合理(手册依据)

Ai8 手册「14 中断系统」明确给出 PWMA 中断优先级控制位 PPWMAH/PPWMA(IP2 的 B2 位、IP2H 的 B2 位),可配置 0~3 级。梁工建议 PWM 中断设为最高优先级(3 级),且其他所有中断优先级都要比它低。这样 PWM 中断一旦触发不会被其他中断(如 USB、串口)打断,避免被更高/同级中断抢占导致处理不及时。

手册中典型配置:

IP2  = 0x04;   // PPWMA = 1
IP2H = 0x04;   // PPWMAH = 1  →  PPWMAH:PPWMA = 11 = 最高级(3级)

原因 3:中断标志"读-改-清"导致误杀新标志(论坛 lcws*** 反馈)

论坛同类型案例(tid=22231)中,网友 lcws*** 指出一个隐蔽坑:

"t = PWMA_SR1; PWMA_SR1 = 0; 假如在这两句代码之间,PWMA_SR1 出现了新的标志,那么它就会被误杀。"

处理方法是:中断里尽量只清自己那个通道的标志位(或用写 0 清除具体某一位的方式),不要对整个 SR1 寄存器做整寄存器清零;并且在清标志前先读回、判断是哪个通道的中断。


三、结合您逻辑分析仪截图的针对性建议

您的截图显示 PUL1(宽脉冲/使能)、PUL2(高速密集脉冲/时钟、数据流)、PUL3(低速方波/状态) 三路同时在输出,说明您在用 PWMA 的多个通道同时输出(如 PWMA_CCR1/CCR2/CCR3 等)驱动步进电机。结合手册与论坛案例,建议:

  1. 先确认是"哪个通道丢":从截图看 PUL2(高速)最可能是"丢中断"的主体。请单独测 PUL2 一路,若单独运行正常、多路同开才丢,则是多通道中断互相抢占/处理不及时问题(与 tid=22231 的"多高速脉冲同时开丢中断"现象一致)。

  2. 把 PWMA 中断设为最高优先级(3 级),其他中断降级:

    IP2  = 0x04;   // PPWMA=1
    IP2H = 0x04;   // PPWMAH=1 → 3级最高
    
  3. 中断函数保持极简:把耗时的打印(USB 输出)、复杂的计算放到主循环轮询,中断里只做必要的标志翻转、计数和清标志。这符合中断处理"快进快出"的原则。梁工建议最小中断间隔最好在 10us 以上

  4. 避免对 PWMA_SR1 整体清零,改为按通道差异化处理,防止误杀新到的中断标志。

  5. 关于多轴联动:论坛回复 1(xiangz***)建议"多轴控制一定得用插补,否则不会太平稳"。如果是多轴高速脉冲输出,建议评估是否改用硬件自动控制脉冲数或插补方案,而不是依赖高频中断计数。


四、关于中断向量(手册依据)

确认您中断函数入口正确:Ai8 手册中 PWMA 中断为 interrupt 26,PWMB 为 interrupt 27。若您的 PWMA 中断函数写的是 void PWMA_ISR() interrupt 26,入口无误。


五、信息来源说明

  • 手册依据:Ai8 手册「25 16位高级PWM定时器,支持正交编码器」中断、PWMA_IER/PWMA_SR1 寄存器部分;「14 中断系统」中断优先级寄存器(PPWMAH/PPWMA)部分。
  • 论坛参考
    • Thread-25324(本贴)回复 3(梁***)——中断间隔太短、优先级设置;
    • Thread-22231(同款 stc8h8k64u 多高速脉冲丢中断)——多通道中断抢占、PWMA_SR1 读清误杀新标志(lcws***)、插补建议(xiangz***)。
  • 需说明:关于"读 PWMA_SR1 后整寄存器清零会误杀新中断标志"、"多轴用插补"等为论坛用户经验(标注"据论坛用户反馈"),手册中未直接给出该表述;PWMA 中断向量 interrupt 26、优先级 PPWMAH/PPWMA 等为手册明确内容。

如果您愿意提供 PWMA 初始化的完整代码(尤其是中断函数主体的具体内容),我可以进一步帮您定位是哪一句导致处理耗时过长,或是否误清了标志位。需要的话请把中断函数部分贴出来。


📌 相关论坛讨论

  1. AI8H8K64U PWMA 疑似丢失中断信号(本帖)
  2. stc8h8k64u 同时使用多个高速脉冲功能时,丢中断的情况探求

⏱️ 总回答用时 39.5s


🔍 搜索 "https://www.stcaimcu.com/thread-25324-1-1.html"

⏱️ 查找用时 22.8s | 总回答用时 39.0s

回复

使用道具 举报 送花

4

主题

22

回帖

100

积分

注册会员

积分
100
 楼主| 发表于 2026-8-18 18:16:03 | 显示全部楼层
不开总中断, 只是查询PWMA_SR1的标志, 依然可以复现这种情况, 中断来不及处理的这个情况, 可以排除。
截图202608181813136498.jpg
回复

使用道具 举报 送花

4

主题

22

回帖

100

积分

注册会员

积分
100
 楼主| 发表于 2026-8-18 18:16:13 | 显示全部楼层
这个是波形图
截图202608181816069388.jpg
回复

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2026-9-22 06:03 , Processed in 0.074811 second(s), 78 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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