论坛上没找到相近的答案。
我用了下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]
---------------------------------
嗯,OPM在使用外部触发的时候有用。没实验,不知道有没有立即进入中断的问题。
一周热门 更多>