新手上路
- 积分
- 26
- 金钱
- 26
- 注册时间
- 2022-3-21
- 在线时间
- 5 小时
|
1金钱
我通过寄存器初始化了定时器2,代码如下
SET_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM2EN);
WRITE_REG(TIMx->PSC, 9000);
WRITE_REG(TIMx->ARR, 10000);
MODIFY_REG(TIMx->CR1, TIM_CR1_CEN, (0x1 & TIM_CR1_CEN));
NVIC_SetPriorityGrouping(0x5);
NVIC_EnableIRQ(TIM2_IRQn);
NVIC_SetPriority(TIM2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 3, 3));
SET_BIT(TIMx->DIER, TIM_DIER_UIE);
经测试可以进入中断函数,在中断函数中实现LED取反操作,发现LED状态没有改变。中断函数如下
void TIM2_IRQHandler(void)
{
red_Led = ~red_Led;
CLEAR_BIT(TIM2->SR, TIM_SR_UIF);
}
而后在中断函数中加入串口输出,代码如下
void TIM2_IRQHandler(void)
{
red_Led = ~red_Led;
printf("1\r\n");
CLEAR_BIT(TIM2->SR, TIM_SR_UIF);
}
可以看到串口助手输出了两次1。
后来查询数据手册发现有一个叫重复计数器的寄存器也会产生更新中断,所以尝试将代码改成如下
void TIM2_IRQHandler(void)
{
red_Led = ~red_Led;
printf("1\r\n");
CLEAR_BIT(TIM2->SR, TIM_SR_UIF);
TIM2->RCR = 0;
}
发现现像正常,后改成原子例程的形式
void TIM2_IRQHandler(void)
{
if(READ_BIT(TIM2->SR, TIM_SR_UIF) == TIM_SR_UIF){
red_Led = ~red_Led;
CLEAR_BIT(TIM2->SR, TIM_SR_UIF);
}
printf("1\r\n");
}
发现现像也是正常的。
那么问题就出现了
第一,定时器2并没有RCR这个寄存器,为什么每次清中断后将这个寄存器写0就没有问题了。
第二,按原子例程中的,判断一下标志位现象就正常了,也没有连续两次进入中断的现象。
不理解是为什么,希望有知道的大神帮着解答一下,谢谢。
|
最佳答案
查看完整内容[请看2#楼]
清中断标志位放在最后可能导致进两次中断. 因为中断清理这个动作需要时间 可能你退出之后中断还没清完 导致又进了中断. 把clearbit放在一进中断就好了. 给它一点时间完成.
|