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下降沿
// }
}
PWMA, PWMB 是各自独立的
深圳国芯人工智能有限公司-产品_STC8H系列 (stcai.com)
神农鼎 发表于 2024-5-13 14:54
PWMA, PWMB 是各自独立的
深圳国芯人工智能有限公司-产品_STC8H系列 (stcai.com)
我知道是独立的啊,但是如果我使能了PWMA中断,PWMB中断就不能触发了,所以觉得很困惑? llionwang 发表于 2024-5-13 14:59
我知道是独立的啊,但是如果我使能了PWMA中断,PWMB中断就不能触发了,所以觉得很困惑? ...
如果单论PWM中断的话 ,,,我记得例程里有个PWM做两路独立定时器的例程,,你可以测试测试那个,, 我现在也遇到了这个问题,本来使用的是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]