找回密码
 立即注册
查看: 778|回复: 4

PWMA和PWMB中断不能同时使用?

[复制链接]
  • 打卡等级:偶尔看看I
  • 打卡总天数:12
  • 最近打卡:2024-10-08 15:50:35

2

主题

5

回帖

138

积分

注册会员

积分
138
发表于 2024-5-13 14:50:06 | 显示全部楼层 |阅读模式
请教各位:

PWMA作为输出,并触发ADC;PWMB作为输入,对霍尔信号计数;

如果启用了PWMA触发ADC,则PWMB中断将不会被触发;
如果不使用PWMA触发ADC,则PWMB中断可以正常触发;
请教,我是哪里弄错了吗?


代码如下:

void PWM_Init()
{
        //*** 设置前禁止PWMA/B所有输出 ***

        //=== PWMA ===
        PWMA_CCER1  = 0x00;                        //捕获/比较使能寄存器1,,,CC2/CC1,写CCMRx前必须先清零CCERx关闭通道
        PWMA_CCER2  = 0x00;                        //捕获/比较使能寄存器1,,,CC4/CC3,写CCMRx前必须先清零CCERx关闭通道
        PWMA_SR1    = 0x00;                        //状态寄存器1,,,清除事件CC4/3/2/1
        PWMA_SR2    = 0x00;                        //状态寄存器2,,,重复捕获标记CC4/3/2/1
        PWMA_ENO    = 0x00;                        //IO禁止输出PWM
        PWMA_IER    = 0x00;                        //中断使能寄存器
        //=== PWMB ===
        PWMB_CCER1  = 0x00;                        //捕获/比较使能寄存器1,,,CC6/CC5
        PWMB_CCER2  = 0x00;                        //捕获/比较使能寄存器1,,,CC8/CC7
        PWMB_SR1    = 0x00;                        //状态寄存器1,,,清除事件CC8/7/6/5
        PWMB_SR2    = 0x00;                        //状态寄存器2,,,重复捕获标记CC8/7/6/5
        PWMB_ENO    = 0x00;                        //IO禁止输出PWM,B6:ENO8P, B4:ENO7P, B2:ENO6P, B0:ENO5P
        PWMB_IER    = 0x00;                        //中断使能寄存器
        //=====================================================
       
        //*** PWMA ***
        PWMA_CCR1                = 300;                        //捕获/比较寄存器:        设置占空比时间
        PWMA_PSCRH        =        0x00;                        //PWMA主频预分频H
        PWMA_PSCRL        =        0x00;                        //PWMA主频预分频L
        PWMA_ARR                = 1999;                        //自动重装载寄存器:=        45MHz / ((0+1)x(1999+1))        =        22.5kHz
        PWMA_CCMR1        = 0x68;                        //捕获/比较模式寄存器:设置CC1为PWM模式1,,,0x60=禁止CCR1预装载(可随时更改CCR1)
        PWMA_CCER1        = 0x0F;                        //捕获/比较使能寄存器:使能CC1通道

//        //使用PWM触发ADC采样
//        PWMA_IER    = 0x01;                        //允许更新中断
//        PWMA_CR2    = 0x20;                        // 更新事件为TRG0, 用于触发ADC

        PWMA_ENO                =        0x00;                        //初始化时禁止所有输出,,,此处不使用,由Motor控制
        PWMA_BKR                = 0x80;                        //刹车寄存器:        主输出使能 相当于总开关
        PWMA_CR1                = 0x00;                        //计数器开始计数                        ,,,此处关闭,由Motor控制
       


///////////////////////////////////////////////////
//*** PWMB ***
        PWMB_CCMR1        =        0x31;                        //设置PWM5为输入,8个时钟滤波,无预分频器,映射到TI5FP5上

        PWMB_CCMR2        =        0x31;                        //设置PWM6为输入,8个时钟滤波,无预分频器,映射到TI6FP6上
        PWMB_CCMR3        =        0x31;                        //设置PWM7为输入,8个时钟滤波,无预分频器,映射到TI7FP7上
        PWMB_CCMR4        =        0x31;                        //设置PWM8为输入,8个时钟滤波,无预分频器,映射到TI8FP8上

        PWMB_CCER1         = 0x31;                        //设置PWM5捕获上升沿,PWM6捕获下降沿
        PWMB_CCER2         = 0x31;                        //设置PWM7捕获上升沿,PWM7捕获下降沿

        PWMB_CCMR1  |= 0x31;                //更新为1个事件触发一次捕获
        PWMB_CCMR2  |= 0x31;                //更新为1个事件触发一次捕获
        PWMB_CCMR3  |= 0x31;                //更新为1个事件触发一次捕获
        PWMB_CCMR4  |= 0x31;                //更新为1个事件触发一次捕获
       
        PWMB_IER           = 0x1E;                        //B0001 1110,,,使能CCIE5/6/7/8中断
        PWMB_EGR    = 0x01;                        //手工产生一次更新事件, 清除计数器和预分频计数器, 装载预分频寄存器的值
        PWMB_CR1   |= 0x01;                        //使能PWMB计数器, 允许自动重装载寄存器缓冲, 边沿对齐模式, 向上计数,  bit7=1:写自动重装载寄存器缓冲(本周期不会被打扰), =0:直接写自动重装载寄存器本(周期可能会乱掉)

        PWMB_ISR_En = PWMB_IER;        //设置标志允许通道5~8中断处理
}



void PWMA_ISR(void) interrupt 26        //PWMA_VECTOR
{
}
void PWMB_ISR(void) interrupt 27        //PWMB_VECTOR
{
//        u16        j;
        u8        sr1, sr2;
       
        //将SR1和SR2转入变量后,SR1和SR2可立即清零,避免后续处理影响下次高速中断
        sr1 = PWMB_SR1;                                        //为了快速, 中断标志用一个局部变量处理
        PWMB_SR1 = 0;                                                //清除中断标志
        sr2 = PWMB_SR2;                                        //为了快速, 中断标志用一个局部变量处理
        PWMB_SR2 = 0;                                                //清除中断标志

        sr1 &= PWMB_ISR_En;                        //每个通道可以单独允许中断处理
       
        MT.CurrHCnt++;                                        //无论正反转,均累加,用于测速

//        if(sr1 & 0x02){                                        //B0000 0010        通道5,H1A上升沿
//        }
//        if(sr1 & 0x04){                                        //B0000 0100        通道6,H1A下降沿
//        }
//        if(sr1 & 0x08){                                        //B0000 1000        通道7,H1B上升沿
//        }
//        if(sr1 & 0x10){                                        //B0001 0000        通道8,H1B下降沿
//        }
}


回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:55
  • 最近打卡:2025-05-02 08:32:59

718

主题

1万

回帖

1万

积分

管理员

积分
15632
发表于 2024-5-13 14:54:19 | 显示全部楼层
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:12
  • 最近打卡:2024-10-08 15:50:35

2

主题

5

回帖

138

积分

注册会员

积分
138
发表于 2024-5-13 14:59:26 | 显示全部楼层
神*** 发表于 2024-5-13 14:54
PWMA, PWMB 是各自独立的
深圳国芯人工智能有限公司-产品_STC8H系列 (stcai.com)

我知道是独立的啊,但是如果我使能了PWMA中断,PWMB中断就不能触发了,所以觉得很困惑?
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:435
  • 最近打卡:2025-04-30 08:43:23

33

主题

2351

回帖

4860

积分

论坛元老

积分
4860
发表于 2024-5-15 10:13:22 | 显示全部楼层
llion*** 发表于 2024-5-13 14:59
我知道是独立的啊,但是如果我使能了PWMA中断,PWMB中断就不能触发了,所以觉得很困惑? ...

如果单论PWM中断的话 ,,,  我记得例程里有个PWM做两路独立定时器的例程,,你可以测试测试那个,,
参考例程并不是对技术参 考手册的补充,而是对技术参 考手册的解释。
技术参 考手册不应该需要参考例程作为补充,而是解释成了参考例程的样子
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:4
  • 最近打卡:2025-02-27 11:58:26

1

主题

3

回帖

45

积分

新手上路

积分
45
发表于 2024-7-12 11:22:54 | 显示全部楼层
我现在也遇到了这个问题,本来使用的是PWM1P和PWM6,两个都是可以正常使用。但现在更改为使用PWM1N和PWM5,PWM2N和PWM6。配置完成后,单独开关都可以正常运行,但是一起使用的话,PWMB的两个通道的波形就会直接消失。下面这是我现在的配置
  1. void pwm_init(void)
  2. {
  3.         PWMA_CCER1 = 0x00; //写 CCMRx 前必须先清零 CCxE 关闭通道
  4.     PWMA_CCER2 = 0x00;
  5.     PWMA_CCMR1 = 0x68; //通道模式配置
  6.     PWMA_CCMR2 = 0x68;
  7.     PWMA_CCER1 = 0x55; //配置通道输出使能和极性
  8.     PWMA_CCER2 = 0x55;
  9. //    PWMA_ARRH = (u8)(PWM_PERIOD >> 8); //设置周期时间
  10. //    PWMA_ARRL = (u8)PWM_PERIOD;
  11.     PWMA_ENO = 0x00;
  12. //    PWMA_ENO |= ENO1P; //使能输出
  13.     PWMA_ENO |= ENO1N; //使能输出   
  14. //    PWMA_ENO |= ENO2P; //使能输出
  15.     PWMA_ENO |= ENO2N; //使能输出   
  16.     PWMA_PS = 0x00;  //高级 PWM 通道输出脚选择位
  17.     PWMA_PS |= PWM1_2; //选择 PWM1_2 通道  P2.1
  18.     PWMA_PS |= PWM2_1; //选择 PWM2_1 通道  P1.3
  19.     PWMA_BKR = 0x80; //使能主输出
  20.     PWMA_CR1 |= 0x01; //开始计时
  21.     PWMB_CCER1 = 0x00; //写 CCMRx 前必须先清零 CCxE 关闭通道
  22.     // PWMB_CCER2 = 0x00;
  23.     PWMB_CCMR1 = 0x68; //通道模式配置
  24.     PWMB_CCMR2 = 0x68;
  25.     PWMB_CCER1 = 0x55; //配置通道输出使能和极性
  26.     // PWMB_CCER2 = 0x33;
  27. //    PWMB_ARRH = (u8)(PWM_PERIOD >> 8); //设置周期时间
  28. //    PWMB_ARRL = (u8)PWM_PERIOD;
  29.     PWMB_ENO = 0x00;
  30.     PWMB_ENO |= ENO5P; //使能输出
  31.     PWMB_ENO |= ENO6P; //使能输出
  32.     PWMB_PS = 0x00;    //高级 PWM 通道输出脚选择位
  33.     PWMB_PS |= PWM5_1; //选择 PWM5_1 通道 P2.0
  34.     PWMB_PS |= PWM6_2; //选择 PWM6_1 通道 P5.4
  35.     PWMB_BKR = 0x80;   //使能主输出
  36.     PWMB_CR1 |= 0x01;  //开始计时
  37.        
  38. }
  39. void PWMA_ON(void)
  40. {
  41.         PWMA_CCER1 = 0x00;  //写 CCMRx 前必须先清零 CCxE 关闭通道
  42.         PWMA_CCMR1 = 0x68;  //设置 PWM1 模式1 输出
  43.         PWMA_CCMR2 = 0x68;  //设置 PWM2 模式1 输出
  44.         PWMA_CCER1 = 0x45;  //使能 CC1E 通道, 高电平有效
  45.         PWMA_SR1 = 0;       //清标志位
  46.         PWMA_CNTR = 0;      //清计数
  47.         PWMA_IER = 0x04;    //使能捕获/比较 1 中断
  48.         // PWMA_ENO = 0X0A;
  49.         PwmA_state = 1;
  50. }
  51. void PWMA_OFF(void)
  52. {
  53.         PWMA_CCER1 = 0x00; //写 CCMRx 前必须先清零 CCxE 关闭通道
  54.         PWMA_CCMR1 = 0x40; //设置 PWM1 强制为无效电平
  55.         // PWMA_CCMR2 = 0x40;  //设置 PWM2 模式1 输出
  56.         PWMA_CCER1 = 0x41; //使能 CC1E 通道, 高电平有效
  57.         // PWMA_ENO = 0x08;
  58.         PWMA_IER = 0x00;   // 关闭中断
  59.         // PWMA_ARR = PeriodA;
  60.         // PWMA_CCR2 = PeriodA / 100 * 15;
  61.         // PWMA_ENO = 0X08;
  62.         PwmA_state = 0;
  63. }
  64. void PWMB_ON(void)
  65. {
  66.         PWMB_CCER1 = 0x00;  //写 CCMRx 前必须先清零 CCxE 关闭通道
  67.         PWMB_CCMR1 = 0x68;  //设置 PWM5 模式1 输出
  68.         PWMB_CCMR2 = 0x68;  //设置 PWM6 模式1 输出
  69.         PWMB_CCER1 = 0x11;  //使能 CC1E 通道, 高电平有效
  70.         PWMB_SR1 = 0;       //清标志位
  71.         PWMB_CNTR = 0;      //清计数
  72.         PWMB_IER = 0x02;    //使能捕获/比较 1 中断
  73.         PwmB_state = 1;
  74. }
  75. void PWMB_OFF(void)
  76. {
  77.         PWMB_CCER1 = 0x00; //写 CCMRx 前必须先清零 CCxE 关闭通道
  78.         PWMB_CCMR1 = 0x40; //设置 PWM5 强制为无效电平
  79.         PWMB_CCER1 = 0x10; //使能 CC5 通道, 高电平有效
  80.         // PWMB_ENO = 0x04;
  81.         PWMB_IER = 0x00;   // 关闭中断
  82.         // PWMB_ARR = PeriodB;
  83.         // PWMB_CCR6 = PeriodB / 100 * 85;
  84.         // PWMB_ENO = 0X00;
  85.         PwmB_state = 0;
  86. }
复制代码
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-5-3 08:17 , Processed in 0.128275 second(s), 77 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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