llionwang 发表于 2024-5-13 14:50:06

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

请教各位:

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下降沿
//        }
}


神农鼎 发表于 2024-5-13 14:54:19

PWMA, PWMB 是各自独立的
深圳国芯人工智能有限公司-产品_STC8H系列 (stcai.com)





llionwang 发表于 2024-5-13 14:59:26

神农鼎 发表于 2024-5-13 14:54
PWMA, PWMB 是各自独立的
深圳国芯人工智能有限公司-产品_STC8H系列 (stcai.com)



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

_奶咖君_ 发表于 2024-5-15 10:13:22

llionwang 发表于 2024-5-13 14:59
我知道是独立的啊,但是如果我使能了PWMA中断,PWMB中断就不能触发了,所以觉得很困惑? ...

如果单论PWM中断的话 ,,,我记得例程里有个PWM做两路独立定时器的例程,,你可以测试测试那个,,

等你下课 发表于 2024-7-12 11:22:54

我现在也遇到了这个问题,本来使用的是PWM1P和PWM6,两个都是可以正常使用。但现在更改为使用PWM1N和PWM5,PWM2N和PWM6。配置完成后,单独开关都可以正常运行,但是一起使用的话,PWMB的两个通道的波形就会直接消失。下面这是我现在的配置
void pwm_init(void)
{

        PWMA_CCER1 = 0x00; //写 CCMRx 前必须先清零 CCxE 关闭通道
    PWMA_CCER2 = 0x00;
    PWMA_CCMR1 = 0x68; //通道模式配置
    PWMA_CCMR2 = 0x68;
    PWMA_CCER1 = 0x55; //配置通道输出使能和极性
    PWMA_CCER2 = 0x55;

//    PWMA_ARRH = (u8)(PWM_PERIOD >> 8); //设置周期时间
//    PWMA_ARRL = (u8)PWM_PERIOD;

    PWMA_ENO = 0x00;
//    PWMA_ENO |= ENO1P; //使能输出
    PWMA_ENO |= ENO1N; //使能输出   
//    PWMA_ENO |= ENO2P; //使能输出
    PWMA_ENO |= ENO2N; //使能输出   


    PWMA_PS = 0x00;//高级 PWM 通道输出脚选择位
    PWMA_PS |= PWM1_2; //选择 PWM1_2 通道P2.1
    PWMA_PS |= PWM2_1; //选择 PWM2_1 通道P1.3


    PWMA_BKR = 0x80; //使能主输出
    PWMA_CR1 |= 0x01; //开始计时

    PWMB_CCER1 = 0x00; //写 CCMRx 前必须先清零 CCxE 关闭通道
    // PWMB_CCER2 = 0x00;
    PWMB_CCMR1 = 0x68; //通道模式配置
    PWMB_CCMR2 = 0x68;
    PWMB_CCER1 = 0x55; //配置通道输出使能和极性
    // PWMB_CCER2 = 0x33;

//    PWMB_ARRH = (u8)(PWM_PERIOD >> 8); //设置周期时间
//    PWMB_ARRL = (u8)PWM_PERIOD;

    PWMB_ENO = 0x00;
    PWMB_ENO |= ENO5P; //使能输出
    PWMB_ENO |= ENO6P; //使能输出
    PWMB_PS = 0x00;    //高级 PWM 通道输出脚选择位
    PWMB_PS |= PWM5_1; //选择 PWM5_1 通道 P2.0
    PWMB_PS |= PWM6_2; //选择 PWM6_1 通道 P5.4

    PWMB_BKR = 0x80;   //使能主输出
    PWMB_CR1 |= 0x01;//开始计时
       

}


void PWMA_ON(void)
{
        PWMA_CCER1 = 0x00;//写 CCMRx 前必须先清零 CCxE 关闭通道
        PWMA_CCMR1 = 0x68;//设置 PWM1 模式1 输出
        PWMA_CCMR2 = 0x68;//设置 PWM2 模式1 输出
        PWMA_CCER1 = 0x45;//使能 CC1E 通道, 高电平有效
        PWMA_SR1 = 0;       //清标志位
        PWMA_CNTR = 0;      //清计数
        PWMA_IER = 0x04;    //使能捕获/比较 1 中断

        // PWMA_ENO = 0X0A;
        PwmA_state = 1;
}

void PWMA_OFF(void)
{
        PWMA_CCER1 = 0x00; //写 CCMRx 前必须先清零 CCxE 关闭通道
        PWMA_CCMR1 = 0x40; //设置 PWM1 强制为无效电平
        // PWMA_CCMR2 = 0x40;//设置 PWM2 模式1 输出
        PWMA_CCER1 = 0x41; //使能 CC1E 通道, 高电平有效
        // PWMA_ENO = 0x08;
        PWMA_IER = 0x00;   // 关闭中断

        // PWMA_ARR = PeriodA;
        // PWMA_CCR2 = PeriodA / 100 * 15;

        // PWMA_ENO = 0X08;
        PwmA_state = 0;
}


void PWMB_ON(void)
{

        PWMB_CCER1 = 0x00;//写 CCMRx 前必须先清零 CCxE 关闭通道
        PWMB_CCMR1 = 0x68;//设置 PWM5 模式1 输出
        PWMB_CCMR2 = 0x68;//设置 PWM6 模式1 输出
        PWMB_CCER1 = 0x11;//使能 CC1E 通道, 高电平有效
        PWMB_SR1 = 0;       //清标志位
        PWMB_CNTR = 0;      //清计数
        PWMB_IER = 0x02;    //使能捕获/比较 1 中断

        PwmB_state = 1;
}


void PWMB_OFF(void)
{
        PWMB_CCER1 = 0x00; //写 CCMRx 前必须先清零 CCxE 关闭通道
        PWMB_CCMR1 = 0x40; //设置 PWM5 强制为无效电平
        PWMB_CCER1 = 0x10; //使能 CC5 通道, 高电平有效
        // PWMB_ENO = 0x04;
        PWMB_IER = 0x00;   // 关闭中断

        // PWMB_ARR = PeriodB;
        // PWMB_CCR6 = PeriodB / 100 * 85;


        // PWMB_ENO = 0X00;

        PwmB_state = 0;
}
页: [1]
查看完整版本: PWMA和PWMB中断不能同时使用?