OpenEdv-开源电子网

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

STM32F103如何用定时器写1分钟的定时

[复制链接]

48

主题

179

帖子

0

精华

初级会员

Rank: 2

积分
185
金钱
185
注册时间
2017-6-19
在线时间
90 小时
发表于 2020-7-18 10:02:10 | 显示全部楼层 |阅读模式
20金钱
如题,想要通过定时器做一
  1. TIM4_Int_Init(4999,7199);//10Khz的计数频率,计数到5000为500ms  
  2. //定时器4中断服务程序
  3. void TIM4_IRQHandler(void)   //TIM4中断
  4. {
  5.         int i=0;
  6.         if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)  //检查TIM4更新中断发生与否
  7.                 {
  8.                         i++;
  9.                         if (i==120)
  10.                         {
  11.                         i=0;
  12.                         LED0=!LED0;
  13.                         }
  14.                 TIM_ClearITPendingBit(TIM4, TIM_IT_Update  );  //清除TIMx更新中断标志
  15.                         
  16.                 }
  17. }

复制代码

个1分钟的延时,led先亮1分钟,然后熄灭1分钟。由于delay()函数做不了时间这么久的延时,所以打算用定时器来做,我已经配置好了定时器定时0.5s,循环120次即为1分钟。但就是循环120次这里老实没写好,代码如下,求大神指教。

最佳答案

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

你这程序每次i都是1,肯定不行啊,要么用全局变量、要么用static修饰变量
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

48

主题

179

帖子

0

精华

初级会员

Rank: 2

积分
185
金钱
185
注册时间
2017-6-19
在线时间
90 小时
 楼主| 发表于 2020-7-18 10:12:29 | 显示全部楼层
自己查了下资料,看了下,将int i=0改为static int i = 0就行了。对static的用法还是不太熟练
回复

使用道具 举报

22

主题

2254

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4486
金钱
4486
注册时间
2013-4-22
在线时间
337 小时
发表于 2020-7-18 10:02:11 | 显示全部楼层
你这程序每次i都是1,肯定不行啊,要么用全局变量、要么用static修饰变量
回复

使用道具 举报

48

主题

179

帖子

0

精华

初级会员

Rank: 2

积分
185
金钱
185
注册时间
2017-6-19
在线时间
90 小时
 楼主| 发表于 2020-7-18 11:30:31 | 显示全部楼层
三叶草 发表于 2020-7-18 11:18
你这程序每次i都是1,肯定不行啊,要么用全局变量、要么用static修饰变量

怎么可以把这个定时1分钟封装成一个类似于delay()一样的函数,这样我要用到一分钟的延时就可以直接用了。现在我必须要把需要延时1分钟的各种外设函数放在中断服务函数里面,多了的话,就容易出现逻辑的错误。
回复

使用道具 举报

34

主题

255

帖子

0

精华

高级会员

Rank: 4

积分
912
金钱
912
注册时间
2019-7-5
在线时间
189 小时
发表于 2020-7-18 12:31:39 | 显示全部楼层
王大爷爱吃鱼 发表于 2020-7-18 11:30
怎么可以把这个定时1分钟封装成一个类似于delay()一样的函数,这样我要用到一分钟的延时就可以直接用了。 ...

设置一个全局变量a,定时器设置位1s,定时器每次中断,a+1,
当a=60,就是一分钟了
回复

使用道具 举报

48

主题

179

帖子

0

精华

初级会员

Rank: 2

积分
185
金钱
185
注册时间
2017-6-19
在线时间
90 小时
 楼主| 发表于 2020-8-10 14:57:09 | 显示全部楼层
因为TIM2.TIM3.TIM4.TIM5.都是通用定时器,所以只需要把代码的TIM3换成其他三个定时器,都是可以的
  1. TIM3_Int_Init(4999,7199);//溢出时间为(5000*7200)/72=500000us=500ms
  2. void TIM3_Int_Init(u16 arr,u16 psc)
  3. {
  4.     TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  5.         NVIC_InitTypeDef NVIC_InitStructure;

  6.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能
  7.        
  8.         //定时器TIM3初始化
  9.         TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值       
  10.         TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
  11.         TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
  12.         TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
  13.         TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位

  14.         TIM_ITConfig(TIM5,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断

  15.         //中断优先级NVIC设置
  16.         NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;  //TIM3中断
  17.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级
  18.         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级3级
  19.         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
  20.         NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器


  21.         TIM_Cmd(TIM5, ENABLE);  //使能TIMx                                         
  22. }
  23. //定时器3中断服务程序
  24. void TIM5_IRQHandler(void)   //TIM3中断
  25. {
  26.         static int i=0;       
  27.         if (TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET)  //检查TIM3更新中断发生与否
  28.                 {
  29.                 i++;
  30.                 if(i==8)  //定时时间0.5*8=4s
  31.                         {
  32.                         LED1=~LED1;  
  33.                         i=0;
  34.                         }
  35.                 TIM_ClearITPendingBit(TIM5, TIM_IT_Update  );  //清除TIMx更新中断标志
  36.                 }
  37. }
复制代码
回复

使用道具 举报

6

主题

279

帖子

0

精华

高级会员

Rank: 4

积分
750
金钱
750
注册时间
2015-3-27
在线时间
98 小时
发表于 2020-8-10 15:40:32 | 显示全部楼层
你可以借鉴原子哥的做法,好像叫 时钟摘取?
- 设置定时器中断溢出为 1s
- 每一次溢出都累加变量 sec_cnt,即 sec_cnt
这样你就获取一个与秒相关的变量,延时函数 堵塞 的写法比较简单:
void delay_ms(u16 cnt)
{
      uint16_t static start = sec_cnt;
      while(sec_cnt < start+cnt);
}

基本思路就是等待时间到达,但是这样比较占用系统资源
回复

使用道具 举报

48

主题

179

帖子

0

精华

初级会员

Rank: 2

积分
185
金钱
185
注册时间
2017-6-19
在线时间
90 小时
 楼主| 发表于 2020-8-10 15:58:00 | 显示全部楼层
弦子的弦 发表于 2020-8-10 15:40
你可以借鉴原子哥的做法,好像叫 时钟摘取?
- 设置定时器中断溢出为 1s
- 每一次溢出都累加变量 sec_cnt ...

好的,谢谢,可以当做一个方法借鉴下思路。
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-30 11:56

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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