STM32F103 通过定时器Timer方式实现时间的精准控制,实现串口通信并让LED等周期性地闪烁

本文介绍如何使用STM32的定时器功能实现精确的时间控制,包括配置定时器实现周期性的LED闪烁及串口通信发送消息。通过详细步骤说明了定时器的工作原理及其在实际项目中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、任务背景

通过定时器Timer方式实现时间的精准控制。
设置一个5秒的定时器,每隔5秒从串口发送“hello windows!”;同时设置一个2秒的定时器,让LED等周期性地闪烁。

2、什么是定时器

定时器/计数器作为SoC的外设,主要用来实现定时执行代码的功能。定时器相对于SoC来说,就好像闹钟相对于人来说意义一样。单核的CPU是单线程的,只能干一件事情,干完这件事情完去干另一件事情需要定时器来提醒。
2. 计数器时钟(CK_CNT)
定时器时钟经过 PSC 预分频器之后,即 CK_CNT,用来驱动计数器计数。PSC 是一个16 位的预分频器,可以对定时器时钟 TIMxCLK 进行 1~65536 之间的任何一个数进行分频。具体计算方式为:CK_CNT=TIMxCLK/(PSC+1)。
3. 计数器(CNT)
计数器 CNT 是一个 16 位的计数器,只能往上计数,最大计数值为 65535。当计数达到自动重装载寄存器的时候产生更新事件,并清零从头开始计数。
4. 自动重装载寄存器(ARR)
自动重装载寄存器 ARR 是一个 16 位的寄存器,这里面装着计数器能计数的最大数值。当计数到这个值的时候,如果使能了中断的话,定时器就产生溢出中断。

分类
定时器可分为3类:

1、基本定时器:功能最少,只能充当基本的时基,甚至都没有外部引脚
2、通用定时器:拥有基本定时器的全部功能,同时有输入捕获模式,用以接收外部的PWM,脉冲之类的信息
3、高级定时器:又有通用定时器的全部功能,又有互补输出模式,功能最为强大

作用

(1)定时器可以让SoC在执行主程序的同时,可以(通过定时器)具有计时功能,到了一定时间(计时结束)后,定时器会产生中断提醒CPU,CPU会去处理中断并执行定时器的ISR。从而去执行预先设定好的事件。

(2)定时器就好像是CPU的一个秘书一样,这个秘书专门管帮CPU来计时,并到时间后提醒CPU要做某件事情。所以CPU有了定时器之后,只需要预先把自己XX时间之后必须要做的事情绑定到定时器中断ISR即可,到了时间之后定时器就会以中断的方式提醒CPU来处理这个事情。

原理

(1)定时器计时其实是通过计数来实现的。定时器内部有一个计数器,这个计数器根据一个时钟(这个时钟来自于ARM的APB总线,然后经过时钟模块内部的分频器来分频得到)来工作。每隔一个时钟周期,计数器就就计数一次,定时器的时间就是计数器计数值x时钟周期。

(2)定时器内部有1个寄存器TCNT,计时开始时我们会把一个总的计数值(譬如说300)放入TCNT寄存器中,然后每隔一个时钟周期(假设为1ms)TCNT中的值会自动减1(硬件自动完成,不需要CPU软件去干预),知道TCNT中减为0的时候,TCNT就会触发定时器中断。最后的计时时间就是300ms。

(3)定时时间是由2个东西共同决定的:一个是TCNT中的计数值,一个是时钟周期。譬如上例中,定时周期就为300x1ms=300ms。

3、项目创建

①、RCC配置

在这里插入图片描述

②、SYS配置

在这里插入图片描述

③、设置端口输出

这里是将PC15作为LED灯的输出,将其选为GPIO_Output
在这里插入图片描述

④、配置定时器

在这里插入图片描述
分频系数为71,向上计数模式,计数周期为5000,使能自动重载模式。

⑤、配置中断

开启时钟2的中断
在这里插入图片描述
生成定时器2中断优先级配置代码。
在这里插入图片描述

⑥、配置USART1

选择异步通信Asynchronous
在这里插入图片描述

⑦、设置时钟

在这里插入图片描述

⑧、配置项目

在这里插入图片描述

在这里插入图片描述

4、编写代码

在Keil中打开工程,修改main.c文件,添加如下代码:

  HAL_TIM_Base_Start_IT(&htim2);

然后再定义一个全局变量用于存储输出信息

char hello[20]="hello windows!\r\n";

在main函数的下面重写回调中断函数

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	static uint32_t time_cnt =0;
	static uint32_t time_cnt3 =0;
	if(htim->Instance == TIM2)
	{
		if(++time_cnt >= 400)
		{
			time_cnt =0;
			HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);
		}
	}
	if(htim->Instance == TIM3)
	{
		if(++time_cnt3 >= 1000)
		{
			time_cnt3 =0;
    HAL_UART_Transmit(&huart1,hello,20,100000);
		}
			
	}
}

5、电路连接

LED灯短脚 —> C15
LED灯长脚 —> 3V3
在这里插入图片描述

6、烧录

7、运行结果

在这里插入图片描述
LED灯以每两秒的间隔进行闪烁
在这里插入图片描述
输出以每五秒的间隔进行输出

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值