STM32采用定时器Timer方式实现串口定时输出hello worlds及LED灯闪烁

本文章将会通过定时器Timer方式实现时间的精准控制,相当于给CPU上了一个闹钟,CPU平时处理其它任务,当定时时间到了以后,处理定时相关的任务。请设置一个5秒的定时器,每隔5秒从串口发送“hello windows!”;同时设置一个2秒的定时器,让LED等周期性地闪烁。

一、定时器的介绍

1.什么是定时器

定时器/计数器作为SoC的外设,主要用来实现定时执行代码的功能。定时器相对于SoC来说,就好像闹钟相对于人来说意义一样。单核的CPU是单线程的,只能干一件事情,干完这件事情完去干另一件事情需要定时器来提醒。
基本定时器框图如下:
在这里插入图片描述1. 时钟源(TIMxCLK)
定时器时钟 TIMxCLK,即内部时钟 CK_INT,经 APB1 预分频器后分频提供,如果APB1 预分频系数等于 1,则频率不变,否则频率乘以 2,库函数中 APB1 预分频的系数是 2,即 PCLK1=36M,所以定时器时钟 TIMxCLK=36*2=72M。
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 位的寄存器,这里面装着计数器能计数的最大数值。当计数到这个值的时候,如果使能了中断的话,定时器就产生溢出中断。

参考文章STM32—TIM(基本定时器)详解

2.定时器的分类

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

在这里插入图片描述

3.stm32中的定时器

就是用来定时的机器,是存在于STM32单片机中的一个外设。STM32总共有8个定时器,分别是2个高级定时器(TIM1、TIM8),4个通用定时器(TIM2、TIM3、TIM4、TIM5)和2个基本定时器(TIM5、TIM6),如下图所示:
在这里插入图片描述

4.定时器的作用

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

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

5.定时器的原理

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

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

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

6.定时器实现方法

定时器timer的实现方法有很多种:

1、最简单易懂的,可以直接usleep(1000)/select(0),这个等待的时间就觉得了定时器的最大精度,然后轮询是否是否到到的定时器,这种定时器无论使用了怎样的定时器任务,该定时任务都会占用比较大量的CPU资源。

2、使用linux的timerfd进行定时,每个定时器,使用一个fd,使用timerfd_create()创建fd,使用timerfd_settime()可以直接设置fd的超时时间,超时时间到了,这个fd就会变为可读的。只要在任务里面监视这些定时器fd是否可读,就可以进行超时判断。

3、使用mutex和condition变量,利用pthread_cond_timedwait()来实现定时。首先将定时器进行排序,取最小的时间,作为信号量的超时等待时间。如果定时器有变化(增加,删除、停止等等)的时候,直接发送信号,触发pthread_cond_timedwait()直接返回,然后重新获取最短等待时间。

4、其实不止pthread_cond_timedwait(),任何可以控制超时等待时间的函数,都可以用来实现定时器。

二、配置工程项目

1.创建项目

点击ACCEE TO MCU SELECTOR
在这里插入图片描述
选择芯片,点击star project
在这里插入图片描述

2.环境配置

(1)配置RCC和SYS

System Cor,选择RCC,在右侧弹出的菜单栏中选Crystal/Ceramic Resonator
在这里插入图片描述
选择调试接口,点System Cor,选择SYS。,在右侧弹出的菜单栏中选Serial Wire
在这里插入图片描述

(2)配置引脚

选择PC15作为LED灯的输出,将其选为GPIO-OUT:
在这里插入图片描述

(3)配置定时器

依次点击位置1,选中定时器2;位置2,配置定时器2的时钟源为内部时钟;位置3,分频系数为71,向上计数模式,计数周期为5000,使能自动重载模式。

在这里插入图片描述
分频系数那里虽然写的是71,但系统处理的时候会自动加上1,所以实际进行的是72分频。由于时钟我们一般会配置为72MHZ,所以72分频后得到1MHZ的时钟。1MHZ的时钟,计数5000次,得到时间5000/1000000=0.005秒。也就是每隔0.005秒定时器2会产生一次定时中断。

(4)配置中断

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

(5)配置USART1

选择Connectivity,点开USART1,Mode选择异步通信Asynchronous:
在这里插入图片描述

(6)配置时钟

如下图:
在这里插入图片描述

3.生成项目

设置项目名称在这里插入图片描述
勾选Generate … …在这里插入图片描述

三、在keil中设置代码

1.中断响应之后所需的代码

    HAL_TIM_Base_Start_IT(&htim2);

在这里插入图片描述
该函数表示启动相应的定时器,“h”表示HAL库,“tim2”表示定时器2。所以这行代码的意思就是启动定时器2。

2. 串口输出hello windows!

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

在这里插入图片描述

3.中断回调函数

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);
		}
			
	}
}

4.编译运行

在这里插入图片描述

编译成功,无错误

四、电路连接

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

五、烧录程序

在这里插入图片描述
烧录成功。

六、运行效果

串口接收helllo world!

3

灯定时亮

2

七、总结

通过这次实验,在STM32F103C8T6核心开发板下,通过使用定时器Timer方式,来实现串口定时输出及LED灯周期闪烁的操作步骤,初步认识了STM32定时器的相关理论知识,定时器中断相比软件延时更加准确,且不占用CPU资源,定时器中断实验中最重要还是要明白定时时间的计算原理和方法,定时器中断则是通过时钟定时计数达到设定值时触发中断,进行中断服务函数的处理任务。并将这个理论知识简单的运用到了实践中,是一次小小的实践。

八、参考资料

STM32CUBEMX_定时器控制LED闪烁
定时器详解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值