STM32F407ZET6的TIM5有问题?

2019-07-21 03:21发布

论坛上没找到相近的答案。
我用了下STM32F407ZET6的TIM5定时器,TIM5 ->ARR设置的值比较大(因为需要定时2小时),手册上说TIM5是32位的,反正ARR也是个32位的。 设置了之后,就发现了个奇怪现象: 开启TIM5之后,立刻进入TIM5_IRQHandler中断处理,闹鬼一样。如果TIM5设置持续计时,那么后续的TIM5_IRQHandler时间间隔是正确的。就是第一次,会立刻进入中断。 不知道什么原因。
有谁遇到过同样问题吗?  能不能说下怎么解决的?
TIM3也有同样问题,这是什么情况?

嗯,所有TIMER都这样。我哪个参数没传对?

贴一下代码吧,万一是个小儿科问题呢?
[mw_shl_code=c,true]TIMERFUN Timer2Fun = 0; TIMERFUN Timer3Fun = 0; TIMERFUN Timer4Fun = 0; TIMERFUN Timer5Fun = 0; TIMERFUN Timer9Fun = 0; TIMERFUN Timer10Fun = 0; TIMERFUN Timer11Fun = 0; TIMERFUN Timer12Fun = 0; TIMERFUN Timer13Fun = 0; TIMERFUN Timer14Fun = 0; u8 ucTimer2Para = 0; u8 ucTimer3Para = 0; u8 ucTimer4Para = 0; u8 ucTimer5Para = 0; u8 ucTimer9Para = 0; u8 ucTimer10Para = 0; u8 ucTimer11Para = 0; u8 ucTimer12Para = 0; u8 ucTimer13Para = 0; u8 ucTimer14Para = 0; u8 ucTimer2Fixer = 0; u8 ucTimer3Fixer = 0; u8 ucTimer4Fixer = 0; u8 ucTimer5Fixer = 0; u8 ucTimer9Fixer = 0; u8 ucTimer10Fixer = 0; u8 ucTimer11Fixer = 0; u8 ucTimer12Fixer = 0; u8 ucTimer13Fixer = 0; u8 ucTimer14Fixer = 0; u8 uc16bTimerMask = 0; u8 uc32bTimerMask = 0; u8 ucTimerId[10] = { 0 }; //定时器2中断服务程序 void TIM2_IRQHandler(void) { if(TIM2->SR&0X0001)//溢出中断 { if(Timer2Fun) { (*Timer2Fun)(ucTimer2Para); } } TIM2->SR&=~(1<<0);//清除中断标志位 } //定时器3中断服务程序 void TIM3_IRQHandler(void) { if(TIM3->SR&0X0001)//溢出中断 { if(Timer3Fun) { (*Timer3Fun)(ucTimer3Para); } } TIM3->SR&=~(1<<0);//清除中断标志位 } //定时器4中断服务程序 void TIM4_IRQHandler(void) { if(TIM4->SR&0X0001)//溢出中断 { if(Timer4Fun) { (*Timer4Fun)(ucTimer4Para); } } TIM4->SR&=~(1<<0);//清除中断标志位 } //定时器5中断服务程序 void TIM5_IRQHandler(void) { if(TIM5->SR&0X0001)//溢出中断 { if(1 == ucTimer5Fixer) { if(Timer5Fun) { (*Timer5Fun)(ucTimer5Para); } } else { ucTimer5Fixer = 1; } } TIM5->SR&=~(1<<0);//清除中断标志位 } /*使能基本计时器 ucTimerIdx:计时器编号 范围:2~5 unCount 自动重装值。 unRunningFreqency 计数器工作频率 范围1282-84M 如uwCount = 20, unRunningFreqency = 10K 那么计数器结束时经过的时间是20 / 10K = 2ms ucOpt 可选参数 0:记数1次即停止, 1:持续记数 pHandler 计数完成后执行函数 ucPara 执行函数的参数 返回值: 0:成功 1:ucOpt unRunningFreqency unCount参数错误 2:定时器编号参数错误 3:定时器已经被占用 4:16位定时器传入的计数参数超阈值 */ u8 SetTimer(u8 ucTimerIdx, u32 unCount, u32 unRunningFreqency,u8 ucOpt,TIMERFUN pHandler,u8 ucPara) { u16 uwPsc = 84000000 / unRunningFreqency; //参数检查 if(unCount < 2 || unRunningFreqency < 1282 || unRunningFreqency > 84000000 || ucOpt > 1) { return 1; //参数错误:重装值、分频数设置错误 } if(ucTimerIdx > 1 && ucTimerIdx < 6) { RCC ->APB1ENR |= 1 << (ucTimerIdx - 2); } else { return 2; //参数错误:不是2-5定时器 } switch(ucTimerIdx) { case 2: if(0x0001 & TIM2 ->CR1) //定时器正在被使用 { return 3; } if(0 == ucOpt) { TIM2 ->CR1 |= 1 << 3; } else if(1 == ucOpt) { TIM2 ->CR1 &= ~(1 << 3); } TIM2 ->ARR = unCount - 1; TIM2 ->SC = uwPsc - 1; TIM2 ->DIER |= 1; Timer2Fun = pHandler; ucTimer2Para = ucPara; MY_NVIC_Init(0,ucTimerIdx - 2,TIM2_IRQn,2); TIM2->SR = 0;//清除中断标志位 TIM2 ->CR1 |= 0x01; break; case 3: if(unCount > 0x0000FFFF) { return 4; } if(0x0001 & TIM3 ->CR1) //定时器正在被使用 { return 3; } TIM3 ->ARR = unCount - 1; TIM3 ->SC = uwPsc - 1; TIM3 ->DIER |= 1; if(0 == ucOpt) { TIM3 ->CR1 |= 1 << 3; } else if(1 == ucOpt) { TIM3 ->CR1 &= ~(1 << 3); } Timer3Fun = pHandler; ucTimer3Para = ucPara; MY_NVIC_Init(0,ucTimerIdx - 2,TIM3_IRQn,2); TIM3->SR = 0;//清除中断标志位 TIM3 ->CR1 |= 0x01; break; case 4: if(unCount > 0x0000FFFF) { return 4; } if(0x0001 & TIM4 ->CR1) //定时器正在被使用 { return 3; } TIM4 ->ARR = unCount - 1; TIM4 ->SC = uwPsc - 1; TIM4 ->DIER |= 1; if(0 == ucOpt) { TIM4 ->CR1 |= 1 << 3; } else if(1 == ucOpt) { TIM4 ->CR1 &= ~(1 << 3); } Timer4Fun = pHandler; ucTimer4Para = ucPara; MY_NVIC_Init(0,ucTimerIdx - 2,TIM4_IRQn,2); TIM4->SR = 0;//清除中断标志位 TIM4 ->CR1 |= 0x01; break; case 5: if(0x0001 & TIM5 ->CR1) //定时器正在被使用 { return 3; } TIM5 ->ARR = unCount - 1; TIM5 ->SC = uwPsc - 1; TIM5 ->DIER |= 1; if(0 == ucOpt) { TIM5 ->CR1 |= 1 << 3; } else if(1 == ucOpt) { TIM5 ->CR1 &= ~(1 << 3); } Timer5Fun = pHandler; ucTimer5Para = ucPara; MY_NVIC_Init(0,ucTimerIdx - 2,TIM5_IRQn,2); TIM5->SR = 0;//清除中断标志位 TIM5 ->CR1 |= 0x01; break; default: break; } return 0; //返回成功 } /*停止基本计时器 使能位置0,停止其时钟 ucTimerIdx:计时器编号 范围:2~5 ucOpt 可选参数 保留不用 */ void KillTimer(u8 ucTimerIdx,u8 ucOpt) { switch(ucTimerIdx) { case 2: TIM2 ->CR1 &= 0xFFFE; RCC ->APB1ENR &= 0xFFFFFFFE; Timer2Fun = 0; ucTimer2Para = 0; ucTimer2Fixer = 0; break; case 3: TIM3 ->CR1 &= 0xFFFE; RCC ->APB1ENR &= 0xFFFFFFFD; Timer3Fun = 0; ucTimer3Para = 0; ucTimer3Fixer = 0; break; case 4: TIM4 ->CR1 &= 0xFFFE; RCC ->APB1ENR &= 0xFFFFFFFB; Timer4Fun = 0; ucTimer4Para = 0; ucTimer4Fixer = 0; break; case 5: TIM5 ->CR1 &= 0xFFFE; RCC ->APB1ENR &= 0xFFFFFFF7; Timer5Fun = 0; ucTimer5Para = 0; ucTimer5Fixer = 0; break; default: break; } } [/mw_shl_code]

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
3条回答
正点原子
1楼-- · 2019-07-21 06:45
第一次进中断的问题,貌似STM32一直有,你程序上处理下吧。
mack13013
2楼-- · 2019-07-21 10:52
 精彩回答 2  元偷偷看……
mack13013
3楼-- · 2019-07-21 15:50
回复【3楼】mack13013:
---------------------------------
嗯,OPM在使用外部触发的时候有用。没实验,不知道有没有立即进入中断的问题。

一周热门 更多>