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

news/2025/3/15 11:14:28/

文章目录

  • 前言
  • 一、设置一个5秒的定时器,每隔5秒从串口发送“hello windows!”
    • 1、创建工程项目
    • 2、项目配置
    • 3、代码编写
      • 1、重定向printf函数
      • 2、定时器代码
    • 4、效果
  • 二、设置一个2秒的定时器,让LED等周期性地闪烁
    • 1.项目配置
    • 2、代码编写
    • 3、效果
  • 三、总结
  • 四、参考资料

前言

  • 硬件: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;elseflag=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/


http://www.ppmy.cn/news/810121.html

相关文章

蓝桥杯学习笔记三:Delay函数毫秒变微秒

平时的HAL_Delay()都是毫秒单位的,但是进去这个函数看看的话,也看不出来是咋回事,我也不理解。但是就说在网上知道了一个方法:用SysTick_Config();这个函数就是来控制Delay函数的单位1代表计数器计数多少次。比如SysTick_Config(8…

Freertos中两个delay函数

vTaskDelay:至少等待指定个数的 Tick Interrupt 才能变为就绪状态 vTaskDelayUntil:等待到指定的绝对时刻,才能变为就绪态。 main代码: int main( void ) {prvSetupHardware();/* Task1的优先级更高, Task1先执行 */xTaskCreate…

linux中的sleep函数和delay函数

对于做过单片机程序的朋友来说,delay是很常见的函数,通常就是while或者for循环,进行空指令的执行,由于单片机的晶振固定,一个机器周期的时间是固定的,执行多少个空指令, 就可以完成多少个机器周…

【51单片机C语言】2-1模块化Delay函数

1.新建一个Delay.c文件和Delay.h文件 2.Delay.c中,Delay函数代码如下:(11.0592MHz,可以由stc软件自带的计算器计算出来) //Delay函数模块化 void Delay(unsigned int xms) //Delay Function 11.0592MHz {unsigned c…

STM32delay函数应用与说明

STM32delay函数应用应用与说明 Cortex M4内核编程手册有关时钟系统的内容定时函数的实现delay_init 函数delay_us 函数 对与32中的delay函数有很多中形式可以使用,这里提供一些自己使用遇到过的函数类型。 Cortex M4内核编程手册有关时钟系统的内容 p230 SysTick t…

android wait函数使用,Android Sleep/Wait/Delay函数

首先,我是一个初学Android的世界,所以请道歉,如果这是愚蠢的问题.. 我正在尝试做以下事情: 启用移动数据 等待10秒 一个。检查Mobile是否有IP地址(数据连接成功) 湾如果未连接,则禁用数据 C。转到第1步 这些步骤1到3在For循环中执行用户给定的重试次数。 现在我的问题是:…

delay函数

在VC中使用带上头文件#include <windows.h>注意:在VC中Sleep中的第一个英文字符为大写的"S"在标准C中是sleep, 不要大写.. 下面使用大写的来说明,, 具体用什么看你用什么编译器. 简单的说VC用Sleep, 别的一律使用sleep.Sleep函数的一般形式:Sleep(unisgned lon…

c语言delay函数的作用,delay函数 delay() c语言延迟函数

51单片机C语言中delay函数是怎么定义和使用的?很多时候我们看别人的故事哀其不幸恨其不争等到发现在自己身上好像突然就明白了别人的道理。 void Delay (unsigned int a){ unsigned int i; while( a 。= 0){ for(定义一个延时xms毫秒的延时函数 void delay(unsigned int xms) …