STC8H PWMB捕获霍尔编码器信号
(1)main.c中运行SFR访问 P_SW2 = 0x80
(2)按实际电路连接切换管脚 PWMB_PS
(3)初始化时关闭所有PWM输出/输入
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; //中断使能寄存器
PWM规划
(1) 用PWM5捕获H1A上升沿,用PWM6捕获H1A下降沿
(2) 用PWM7捕获H1B上升沿,用PWM8捕获H1B下降沿
H1A --> PWM5 --> TI5FP5 --> 上升沿
-> PWM6 --> TI6FP6 --> 下降沿
H1B --> PWM7 --> TI7FP7 --> 上升沿
-> PWM8 --> TI8FP8 --> 下降沿
设置代码
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 PWMB_ISR(void) interrupt 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上升沿
MT.CurrHVal++;
}
if(sr1 & 0x04){ //B0000 0100 通道6,H1A下降沿
MT.CurrHVal++;
}
if(sr1 & 0x08){ //B0000 1000 通道7,H1B上升沿
MT.CurrHVal++;
}
if(sr1 & 0x10){ //B0001 0000 通道8,H1B下降沿
MT.CurrHVal++;
}
}