通过定时器的Timer方式替代delay/Hal_delay函数进行定时

前言

  • 硬件:stm32f103c8t6 核心板
  • 软件:STM32CubeMX 6.4.0
  • 软件:keil5 mdk
  • 软件:野火串口调试助手

一、设置一个5秒的定时器,每隔5秒从串口发送“hello windows!”

之前一般使用delay函数实现延时,这让CPU停下来等待时间,这样极大的浪费了资源。我们可以设置定时器,解放COU,让它去忙别的事,到时间再回来处理这边的时间,资源的利用率更大。

1、创建工程项目

  • 选择STM32C8T6型号。
    在这里插入图片描述

2、项目配置

  • SYS设置,选择Serial Wire模式。
    在这里插入图片描述

  • 时钟RCC配置,将HSE选为外部晶振模式

在这里插入图片描述

  • 设置USART
    在这里插入图片描述
  • 时钟树设置
    在这里插入图片描述
  • 定时器设置
    在这里插入图片描述

分频系数由于系统处理的时候会自动加上1,于是我们填71。由于时钟树我们上面配置为72MHZ,所以72分频后得到1MHZ的时钟。1MHZ的时钟,计数5000次,得到时间5000/1000000=0.005秒。也就是每隔0.005秒定时器2会产生一次定时中断。

  • 开启定时器的中断
    在这里插入图片描述

  • 设置优先级
    在这里插入图片描述

设置工程路径、工程名,最后导出文件。
可参考:https://blog.csdn.net/qq_52215423/article/details/127516169?spm=1001.2014.3001.5501

3、代码编写

1、重定向printf函数

分别在main.c和usart.c文件添加头文件

#include "stdio.h"

keil配置允许重定向

在这里插入图片描述
在main.c文件中重写printf函数:

int fputc(int ch, FILE *f)
 
{
 
  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
 
  return ch;
 
}

2、定时器代码

在main函数里添加下面这句语句用于开启定时器

  HAL_TIM_Base_Start_IT(&htim2);

定义一个全局变量

  unsigned int flag = 1;

在while里添加输出语句

if(flag == 1){		
	  		printf("Hello windows! \r\n");
	flag=0;
		}

重写定时器的中断回调函数,当产生定时中断的时候,会自动调用这个函数。因为上面我们设置了一次中断的时间为0.005秒,所以我们需要1000次中断才满足5秒。

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	static uint32_t time_cnt =0;

	if(htim->Instance == TIM2)
	{
		if(++time_cnt >= 1000)
		{
			time_cnt =0;
			if(flag==0)
				flag=1;
			else
				flag=0;
		}
	}
}

4、效果

编译烧录成功后的效果如下:

20221102_213840

二、设置一个2秒的定时器,让LED等周期性地闪烁

上面已经写了创建项目流程,就不再赘述,直接进行项目配置。

1.项目配置

  • SYS设置,选择Serial Wire模式。
    在这里插入图片描述

  • 时钟RCC配置,将HSE选为外部晶振模式

在这里插入图片描述

  • 时钟树设置
    在这里插入图片描述

  • 配置IO管脚,用于输出LED电平,这里选择PC14.
    在这里插入图片描述

  • 定时器设置
    在这里插入图片描述

  • 开启定时器的中断
    在这里插入图片描述

  • 设置优先级
    在这里插入图片描述
    设置工程路径、工程名,最后导出文件。

2、代码编写

  • 在main函数里添加启动定时器2的语句:
HAL_TIM_Base_Start_IT(&htim2);
  • 重写定时器的中断回调函数

由于前面的时钟树的设置可知,每次的中断时间为0.005秒,于是400次的中断等于2s,符合我们的要求

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	static uint32_t time_cnt =0;

	if(htim->Instance == TIM2)
	{
		if(++time_cnt >= 400)
		{
			time_cnt =0;
			HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_14);
		}
	}
}
  • 编译烧录均无问题。

3、效果

VID_20221102_200720


三、总结

通过定时器的TImer方式极大的利用了CPU资源,并且STMCube也构建好了许多库,可以直接对定时器进行操作,方便了许多。

四、参考资料

http://www.mcublog.cn/stm32/2021_01/stm32cubemx-dingshiqi-led/

  • 6
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qq_52215423

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值