我希望使用LPTIM4实现1秒钟一次的内部中断,中断发生后翻转IO。
调用定时器开始函数后立即进入中断。中断函数中清除中断后,马上又进入中断,感觉没有清除成功。通过调试观察寄存器LPTIM4->ISR确实没有马上清除。哪位老师帮我看看是哪里的问题。
我使用HAL库也试了一下,还是相同的现象。
定时器开始函数
void LPTIM4_Start_IT(uint32_t Period)
{
LPTIM4->CFGR &= ~(LPTIM_CFGR_WAVE);
LPTIM4->CR |= (LPTIM_CR_ENABLE);
LPTIM4->ICR = (LPTIM_ICR_CMP1OKCF);
LPTIM4->CCR1 = (Period/2 - 1);
while(!(LPTIM_ICR_CMP1OKCF & LPTIM4->ISR));
LPTIM4->ICR = (LPTIM_ICR_ARROKCF);
LPTIM4->ARR = (Period - 1);
while(!(LPTIM_ICR_ARROKCF & LPTIM4->ISR));
LPTIM4->ICR = (LPTIM_ICR_DIEROKCF);
LPTIM4->DIER |= (LPTIM_DIER_UEIE | LPTIM_DIER_ARRMIE | LPTIM_DIER_CC1IE);
while(!(LPTIM_ISR_DIEROK & LPTIM4->ISR));
LPTIM4->CR &= ~(LPTIM_CR_ENABLE);
LPTIM4->ICR = (LPTIM_ICR_DIEROKCF | LPTIM_ICR_REPOKCF | LPTIM_ICR_ARROKCF | LPTIM_ICR_CMP1OKCF);
LPTIM4->CR |= (LPTIM_CR_ENABLE);
LPTIM4->CR |= (LPTIM_CR_CNTSTRT);
}
中断函数
void LPTIM4_IRQHandler(void)
{
if(LPTIM_ISR_ARRM & LPTIM4->ISR)
{
LPTIM4->ICR = (LPTIM_ICR_ARRMCF);
HAL_GPIO_TogglePin(GPIOC, CTRL3_Pin);
}
if(LPTIM_ISR_CC1IF & LPTIM4->ISR)
{
LPTIM4->ICR = (LPTIM_ICR_CC1CF);
}
if(LPTIM_ISR_UE & LPTIM4->ISR)
{
LPTIM4->ICR = (LPTIM_ICR_UECF);
}
}
主函数
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_LPTIM4_Init();
LPTIM4_Start_IT(1000);
while (1)
{}
}
|
自己顶一下
看你的代码开启了多个中断,你开启你需要的即可,不要的就别使能了;
另外的IRQ函数可以尝试稍微改写下,比方这样:
void LPTIM4_IRQHandler(void)
{
uint32_t isr =LPTIM4->ISR;
uint32_t icr = 0;
if (isr & LPTIM_ISR_ARRM)
{
icr |=LPTIM_ICR_ARRMCF; }
if (isr & LPTIM_ISR_CC1IF)
{
icr |=LPTIM_ICR_CC1CF; }
if (isr & LPTIM_ISR_UE)
{
icr |=LPTIM_ICR_UECF;
}
if (icr)
{
LPTIM4->ICR = icr; //统一一次性清
}
if (isr & LPTIM_ISR_ARRM)
{
HAL_GPIO_TogglePin(GPIOC, CTRL3_Pin);
}
}
很多时候,频率设定的快,调试时瞬间就触发中断,看起来就像连续的。
另外ST有现成的CubeMx, 用它生成软件就方便很多,也有很多例程参考。