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

stc8h8k64u 同时使用多个高速脉冲功能时,丢中断的情况探求

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:1
  • 最近打卡:2026-01-17 20:50:17
已绑定手机

1

主题

0

回帖

15

积分

新手上路

积分
15
发表于 2026-1-17 21:33:17 | 显示全部楼层 |阅读模式


问题描述:同时使用三个高速脉冲输出功能时(PWMA_CCR4、PWMA_CCR3、PWMA_CCR2),发生中断标志位丢失的情况。按附录代码运行可观测到以下现象:

1、通过逻辑分析仪检测P34脚(PWMA_4P),可检测到高速脉冲不连续,脉冲中断的时长约32.8ms;
2、补全相关USB代码部分,打印输出ccr4_err_cnt变量,该值发生变化;
通过检测该值判断中断是否被响应的原理如下:
1)P34脚的硬件反转早于中断响应;
2)在中断函数中,翻转自定义标志位ccr4f,正常过程中,ccr4f 的值应与P34的值一致;
3)当ccr4f与P34的值不一致时,表示有一次中断函数未被执行,ccr4_err_cnt加1;
4)通过观测ccr4_err_cnt的值变化,分析未响应中断函数的次数。

代码中清除中断标志位的代码如下

        t=PWMA_SR1;        PWMA_SR1 =0; //清楚中断标志

若使用  PWMA_SR1 &= ~0x10 的方式清楚中断标志,ccr4_err_cnt的变化速录会更快,也就是在单位时间内,未响应的中断函数次数更多。
补充说明:
发生中断未响应时,通过逻辑分析仪可观测到丢失中断的PWM管脚滞后其他管脚约1.5us。例如PWMA3N的管脚使用P15,当P15发生硬件翻转时,若在1.5us左右P34(PWMA4P)管脚发生硬件翻转,则在PWMA的中断函数中,PWMA4的中断函数会发生无法响应的情况。

上述现象将导致通过脉冲控制多个步进电机时,电机运行速度不稳定,并且该现象可能存在于其他中断标志位在片外RAM的中断响应中。

代码片段如下:

//pwm代码



#include    "STC8H.h"
#define     FOSC 24000000L
#include    "intrins.h"

#define PWM1_1          0x00                    //P:P1.0  N:P1.1
#define PWM1_2          0x01                    //P:P2.0  N:P2.1
#define PWM1_3          0x02                    //P:P6.0  N:P6.1

#define PWM2_1          0x00                    //P:P1.2/P5.4  N:P1.3
#define PWM2_2          0x04                    //P:P2.2  N:P2.3
#define PWM2_3          0x08                    //P:P6.2  N:P6.3

#define PWM3_1          0x00                    //P:P1.4  N:P1.5
#define PWM3_2          0x10                    //P:P2.4  N:P2.5
#define PWM3_3          0x20                    //P:P6.4  N:P6.5

#define PWM4_1          0x00                    //P:P1.6  N:P1.7
#define PWM4_2          0x40                    //P:P2.6  N:P2.7
#define PWM4_3          0x80                    //P:P6.6  N:P6.7
#define PWM4_4          0xC0                    //P:P3.4  N:P3.3

#define ENO1P           0x01
#define ENO1N           0x02
#define ENO2P           0x04
#define ENO2N           0x08
#define ENO3P           0x10
#define ENO3N           0x20
#define ENO4P           0x40
#define ENO4N           0x80


bit ccr4f=0;
uint data ccr4_err_cnt=0;
uint PWMA_CCR3_set;
uint PWMA_CCR2_set;
uint PWMA_CCR4_set;


void PWMA_cfg()
{
        IP2=0x04;IP2H=0x04;//将中断设为最高优先级,最高优先级的中断只有这一个

        PWMA_ENO=0;
        //使能PWMA输出
        PWMA_PSCR=(FOSC/2000000)-1;                                                         //计数器时钟(FOCS/(PWMB_PSCR+1))
        PWMA_ARR = 0xffff;                             //设置周期时间
       
        PWMA_CCER1 = 0x00;                          //写CCMRx前必须先清零CCERx关闭通道
        PWMA_CCER2 = 0x00;                          //写CCMRx前必须先清零CCERx关闭通道
       
        PWMA_CCMR1 = 0;                          //冻结CCR1
        PWMA_CCMR2 = 0x30;                          //设置CCR2为翻转输出模式
        PWMA_CCMR3 = 0x30;                          //设置CCR3为翻转输出模式
        PWMA_CCMR4 = 0x30;                       //设置CCR4为翻转输出模式
       
        PWMA_CCER1 = 0x10;                          //禁用CC1通道
        PWMA_CCER2 = 0x14;                      //使能CCR4P通道比较,//使能CCR3N通道比较

       
        PWMA_CCR2_set = 100;
        PWMA_CCR2 = PWMA_CCR2_set;                            //设置占空比时间
        PWMA_CCR2_set += 100;
       
        PWMA_CCR3_set = 100;
        PWMA_CCR3 = PWMA_CCR3_set;                            //设置占空比时间
        PWMA_CCR3_set += 100;
       
        PWMA_CCR4_set = 100;
        PWMA_CCR4 = PWMA_CCR4_set;                            //设置占空比时间
        PWMA_CCR4_set += 100;

        PWMA_IER = 0x18; //允许PWM4/3 中断
       
        //设置PWM3/PWM4输出口
        PWMA_PS = PWM4_4; //高级 PWM 通道输出脚选择位
       
    PWMA_BKR = 0x80;                            //使能主输出
    PWMA_CR1 = 0x01;                            //开始计时
}

void PWMA_ISR() interrupt 26 //PWMA中断
{
        uchar data t;
       
        //消除 中断标志位
        t=PWMA_SR1;
        PWMA_SR1 =0; //清楚其他中断标志
        if((t&0x10)>0)
        {
                PWMA_CCR4 = PWMA_CCR4_set;
               
                for(t=0;t<3;t++); //模拟其他指令时长
               
                PWMA_ENO |= ENO4P;
                PWMA_CCR4_set += 49;
                ccr4f = !ccr4f;
                if(ccr4f != P34) {ccr4f=P34;ccr4_err_cnt++;}
        }
       
        if((t&0x08)>0)
        {
                PWMA_CCR3 = PWMA_CCR3_set;
               
                for(t=0;t<8;t++); //模拟其他指令时长
               
                PWMA_CCR3_set += 70;
        }
       
}


可按如下结构补全为可运行代码
void main()
{
//其他初始化代码
PWMA_cfg() ;
while(1);
}
//补全后
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:539
  • 最近打卡:2026-03-26 23:16:14
已绑定手机

15

主题

616

回帖

1577

积分

荣誉版主

积分
1577
发表于 2026-1-18 01:05:33 | 显示全部楼层
多轴控制,一定得用插补,否则不会太平稳的.
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:395
  • 最近打卡:2026-03-27 09:47:09
已绑定手机

6

主题

331

回帖

1697

积分

金牌会员

积分
1697
发表于 2026-3-17 14:58:40 | 显示全部楼层
单个高速脉冲输出时,是啥情况
学习
回复

使用道具 举报 送花

  • 打卡等级:常住居民II
  • 打卡总天数:87
  • 最近打卡:2026-03-27 09:14:52
已绑定手机

4

主题

234

回帖

852

积分

高级会员

积分
852
发表于 2026-3-17 16:05:37 | 显示全部楼层
看来这里面有坑啊,要小心了。
t=PWMA_SR1;
PWMA_SR1 =0; //清楚其他中断标志
假如在这两句代码之间,PWMA_SR1 出现了新的标志,那么它就会被误杀,我暂时没想到办法,楼主测试一下看是不是这个原因。
回复

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2026-3-27 10:54 , Processed in 0.107351 second(s), 64 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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