OpenEdv-开源电子网

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

STM32定时器怎么定时多个相同的时间段?

[复制链接]

10

主题

39

帖子

0

精华

新手上路

积分
47
金钱
47
注册时间
2021-12-2
在线时间
26 小时
发表于 2022-3-8 14:22:52 | 显示全部楼层 |阅读模式
25金钱
时间段为两个小时。随机5个按键触发定时。尽量少开定时器和中断.

最佳答案

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

你怎么那么厉害,可以加个联系方式,教教我这个爱学习的小白吗?
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

10

主题

39

帖子

0

精华

新手上路

积分
47
金钱
47
注册时间
2021-12-2
在线时间
26 小时
 楼主| 发表于 2022-3-8 14:22:53 | 显示全部楼层
LcwSwust 发表于 2022-3-9 14:47
因为Mode1_Tim和Mode2_Tim里有while(1);建议这样整:

你怎么那么厉害,可以加个联系方式,教教我这个爱学习的小白吗?
回复

使用道具 举报

12

主题

3344

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8465
金钱
8465
注册时间
2020-5-11
在线时间
3904 小时
发表于 2022-3-8 16:29:50 | 显示全部楼层
定义5个变量,一个按键对应一个变量,按下时赋值为7200,定时器中断里让5个变量每秒减1,减到0为止。
专治疑难杂症
回复

使用道具 举报

11

主题

2131

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4734
金钱
4734
注册时间
2015-1-10
在线时间
591 小时
发表于 2022-3-8 16:47:36 | 显示全部楼层
5个按键操作一个定时标志不就行了
回复

使用道具 举报

10

主题

39

帖子

0

精华

新手上路

积分
47
金钱
47
注册时间
2021-12-2
在线时间
26 小时
 楼主| 发表于 2022-3-9 14:08:57 | 显示全部楼层
LcwSwust 发表于 2022-3-8 16:29
定义5个变量,一个按键对应一个变量,按下时赋值为7200,定时器中断里让5个变量每秒减1,减到0为止。

遇到一个问题,按下KEY0时,红灯亮。计时两个小时之后红灯灭,但期间按下另一个键,绿灯没办法亮起来进倒行计时
回复

使用道具 举报

12

主题

3344

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8465
金钱
8465
注册时间
2020-5-11
在线时间
3904 小时
发表于 2022-3-9 14:11:19 | 显示全部楼层
yang9914 发表于 2022-3-9 14:08
遇到一个问题,按下KEY0时,红灯亮。计时两个小时之后红灯灭,但期间按下另一个键,绿灯没办法亮起来进倒 ...

上程序
专治疑难杂症
回复

使用道具 举报

10

主题

39

帖子

0

精华

新手上路

积分
47
金钱
47
注册时间
2021-12-2
在线时间
26 小时
 楼主| 发表于 2022-3-9 14:19:51 | 显示全部楼层


主程序

#include "sys.h"
#include "delay.h"
#include "led.h"
#include "key.h"
#include "timer.h"
/************************************************
ALIENTEK 战舰STM32F103开发板 实验3
按键输入实验-HAL库函数版
技术支持:www.openedv.com
淘宝店铺: http://eboard.taobao.com
关注微信公众平台微信号:"正点原子",免费获取STM32资料。
广州市星翼电子科技有限公司  
作者:正点原子 @ALIENTEK
************************************************/

int main(void)
{
  HAL_Init();                                     //初始化HAL库   
  Stm32_Clock_Init(RCC_PLL_MUL9);   //设置时钟,72M
        delay_init(72);                               //初始化延时函数
        LED_Init();                                                                                                //初始化LED       
        KEY_Init();                                                                                                //初始化按键
        TIM3_Init(999,7199);                                                        //装载值0.1s
        while(1)
        {
   if(WK_UP)
                 {
                  Tim_hour1();
                 }
                 delay_ms(100);
        }
}

     定时器程序

#include "timer.h"
#include "led.h"
#include "key.h"
#include "sys.h"
//////////////////////////////////////////////////////////////////////////////////         
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK STM32F103开发板
//定时器中断驱动代码          
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//创建日期:2019/9/17
//版本:V1.0
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2014-2024
//All rights reserved                                                                          
//////////////////////////////////////////////////////////////////////////////////        
u32 sec = 0;                                                                                                                                                                                //秒
int mode1;                                                                                                       
int mode2;                                                                                                                                                                                        //分钟
TIM_HandleTypeDef TIM3_Handler;                                                                                      //定时器句柄



void Tim_hour1(void)
{
        if(KEY0 == 0)
        {
                mode1 = 10;
                Mode1_Tim();
        }
               
        else if(KEY1 == 0)
        {
                mode2 = 10;
                Mode2_Tim();
        }
}       



//通用定时器3中断初始化
//arr:自动重装值。
//psc:时钟预分频数
//定时器溢出时间计算方法:Tout=((arr+1)*(psc+1))/Ft us.
//Ft=定时器工作频率,单位:Mhz
//这里使用的是定时器3!
void TIM3_Init(u16 arr,u16 psc)
{  
    TIM3_Handler.Instance=TIM3;                          //通用定时器3
    TIM3_Handler.Init.Prescaler=psc;                     //分频系数
    TIM3_Handler.Init.CounterMode=TIM_COUNTERMODE_UP;    //向上计数器
    TIM3_Handler.Init.Period=arr;                        //自动装载值
    TIM3_Handler.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1;//时钟分频因子
    HAL_TIM_Base_Init(&TIM3_Handler);
   
                HAL_TIM_Base_Start_IT(&TIM3_Handler);                                                         //使能定时器3和定时器3更新中断:TIM_IT_UPDATE   
}
                                                                                                                                                                                                                                //定时器底册驱动,开启时钟,设置中断优先级
                                                                                                                                                                                                                                //此函数会被HAL_TIM_Base_Init()函数调用
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim)
{
    if(htim->Instance==TIM3)
        {
                __HAL_RCC_TIM3_CLK_ENABLE();                                                            //使能TIM3时钟
                HAL_NVIC_SetPriority(TIM3_IRQn,1,3);                                                    //设置中断优先级,抢占优先级1,子优先级3
                HAL_NVIC_EnableIRQ(TIM3_IRQn);                                                          //开启ITM3中断   
        }
}
                                                                                                                                                                                                                                //定时器3中断服务函数
void TIM3_IRQHandler(void)
{
    HAL_TIM_IRQHandler(&TIM3_Handler);
}
                                                                                                                                                                                                                                //回调函数,定时器中断服务函数调用
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if(htim==(&TIM3_Handler))
    {
                }
                if(sec++ == 10)
                {
                        sec = 0;                                                                                                                                                                //计数清零,秒数减一
                        mode1--;
                        mode2--;
                }
}


       灯
#include "led.h"
#include "timer.h"
//////////////////////////////////////////////////////////////////////////////////         
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK STM32F103开发板
//LED驱动代码          
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//创建日期:2019/9/17
//版本:V1.0
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2014-2024
//All rights reserved                                                                          
//////////////////////////////////////////////////////////////////////////////////        

//初始化PB1为输出.并使能时钟            
//LED IO初始化
extern int mode1;
extern int mode2;       



void Mode1_Tim(void)
{
                LED0 = 0;
        while(1)
         {
                if(mode1==0)
                {LED0 = 1;break;}
         }
}

void Mode2_Tim(void)
{
                LED1 = 0;                                                                                                                                                    
        while(1)
         {
                if(mode2==0)
                {LED1 = 1;break;}
               
         }
}

回复

使用道具 举报

12

主题

3344

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8465
金钱
8465
注册时间
2020-5-11
在线时间
3904 小时
发表于 2022-3-9 14:47:20 | 显示全部楼层
yang9914 发表于 2022-3-9 14:19
主程序

#include "sys.h"

因为Mode1_Tim和Mode2_Tim里有while(1);建议这样整:
  1. void Tim_hour1(void)
  2. {
  3.         if(KEY0 == 0)
  4.         {
  5.                 mode1 = 10;
  6.         }
  7.        
  8.         else if(KEY1 == 0)
  9.         {
  10.                 mode2 = 10;
  11.         }
  12. }

  13. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
  14. {
  15.     if(htim==(&TIM3_Handler))
  16.     {
  17.                 if(sec++ == 10)
  18.                 {
  19.                         sec = 0;//计数清零,秒数减一
  20.                         if(mode1)
  21.                         {
  22.                                 mode1--;
  23.                                 LED1=0;
  24.                         }
  25.                         else
  26.                         {
  27.                                 LED1=1;
  28.                         }
  29.                        
  30.                         if(mode2)
  31.                         {
  32.                                 mode2--;
  33.                                 LED2=0;
  34.                         }
  35.                         else
  36.                         {
  37.                                 LED2=1;
  38.                         }
  39.                 }
  40.         }
  41. }
复制代码




专治疑难杂症
回复

使用道具 举报

12

主题

3344

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8465
金钱
8465
注册时间
2020-5-11
在线时间
3904 小时
发表于 2022-3-9 15:29:30 | 显示全部楼层
yang9914 发表于 2022-3-8 14:22
你怎么那么厉害,可以加个联系方式,教教我这个爱学习的小白吗?

坛里发帖就行了
专治疑难杂症
回复

使用道具 举报

10

主题

39

帖子

0

精华

新手上路

积分
47
金钱
47
注册时间
2021-12-2
在线时间
26 小时
 楼主| 发表于 2022-3-9 16:06:38 | 显示全部楼层
LcwSwust 发表于 2022-3-9 15:29
坛里发帖就行了

定时器的溢出中断和主程序的运行是同时进行的吗?
回复

使用道具 举报

12

主题

3344

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8465
金钱
8465
注册时间
2020-5-11
在线时间
3904 小时
发表于 2022-3-9 16:25:27 | 显示全部楼层
yang9914 发表于 2022-3-9 16:06
定时器的溢出中断和主程序的运行是同时进行的吗?

把单片机当作一个人,一个时间只能做一件事,定时器当作闹钟,闹钟响了这个人就去看一下做点该做的事,然后返回继续做原来的事。
专治疑难杂症
回复

使用道具 举报

10

主题

39

帖子

0

精华

新手上路

积分
47
金钱
47
注册时间
2021-12-2
在线时间
26 小时
 楼主| 发表于 2022-3-9 16:59:47 | 显示全部楼层
LcwSwust 发表于 2022-3-9 16:25
把单片机当作一个人,一个时间只能做一件事,定时器当作闹钟,闹钟响了这个人就去看一下做点该做的事,然 ...

那这个人办事效率有点高。。刚刚那个倒计时10分钟就有一分钟的误差。不准
回复

使用道具 举报

12

主题

3344

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8465
金钱
8465
注册时间
2020-5-11
在线时间
3904 小时
发表于 2022-3-9 17:11:20 | 显示全部楼层
yang9914 发表于 2022-3-9 16:59
那这个人办事效率有点高。。刚刚那个倒计时10分钟就有一分钟的误差。不准

那你得把时钟整准哦,比如这个位置:
sec = 0;//计数清零,秒数减一
这后面加一句让某个LED取反,示波器监测或对照秒表看这个1秒钟准不准。
专治疑难杂症
回复

使用道具 举报

12

主题

3344

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8465
金钱
8465
注册时间
2020-5-11
在线时间
3904 小时
发表于 2022-3-9 17:25:37 | 显示全部楼层
本帖最后由 LcwSwust 于 2022-3-9 17:27 编辑

应该就是这里差了1
if(sec++ == 10)
建议改为:
sec++ ;
if(sec>= 10)
或改为:
if(++sec == 10)
还是分开写才好,不然都不知道是先加1还是先判断。

专治疑难杂症
回复

使用道具 举报

10

主题

39

帖子

0

精华

新手上路

积分
47
金钱
47
注册时间
2021-12-2
在线时间
26 小时
 楼主| 发表于 2022-3-9 17:30:11 | 显示全部楼层
LcwSwust 发表于 2022-3-9 17:11
那你得把时钟整准哦,比如这个位置:
sec = 0;//计数清零,秒数减一
这后面加一句让某个LED取反,示波 ...

这个地方有一点慢,一分钟大概差500ms
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-2-28 00:30

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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