OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6929|回复: 3

STM32F407ZET6的TIM5有问题?

[复制链接]

33

主题

984

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
7952
金钱
7952
注册时间
2014-8-13
在线时间
1590 小时
发表于 2015-4-16 21:00:16 | 显示全部楼层 |阅读模式
5金钱

论坛上没找到相近的答案。


我用了下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]



最佳答案

查看完整内容[请看2#楼]

第一次进中断的问题,貌似STM32一直有,你程序上处理下吧。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165371
金钱
165371
注册时间
2010-12-1
在线时间
2110 小时
发表于 2015-4-16 21:00:17 | 显示全部楼层
第一次进中断的问题,貌似STM32一直有,你程序上处理下吧。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

33

主题

984

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
7952
金钱
7952
注册时间
2014-8-13
在线时间
1590 小时
 楼主| 发表于 2015-4-17 10:39:03 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
如果STM32一直有第一次进中断问题,那TIMx ->CR1的OPM位还有什么用?
回复

使用道具 举报

33

主题

984

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
7952
金钱
7952
注册时间
2014-8-13
在线时间
1590 小时
 楼主| 发表于 2015-4-17 12:18:51 | 显示全部楼层
回复【3楼】mack13013:
---------------------------------
嗯,OPM在使用外部触发的时候有用。没实验,不知道有没有立即进入中断的问题。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-24 12:00

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表