STM32使用定时器进行串口通信和点灯及输出PWM完成呼吸灯
一、定时器的基本介绍
1、定时器概念
STM32定时器具有多个定时/计数通道,可以高精度地计算时间,并可配置为不同的模式以满足各种应用需求。它不仅可以作为独立的时间测量工具,还可以与其他外设模块(如ADC、DAC、GPIO等)进行协作,提供丰富的功能。
2、定时器分类
STM32定时器主要分为以下几类:
-
高级定时器:功能最全,如STM32的TIM1和TIM8,挂载在APB2总线上。它们增加了重复计数器、死区生成、互补输出、刹车输入等功能,适用于需要高精度和高可靠性的应用。
-
通用定时器:最常用,如STM32的TIM2、TIM3、TIM4、TIM5,挂载在APB1总线上。它们具有内外时钟源选择、输入捕获、输出比较、编码器接口、主从触发模式等功能,适用于各种通用应用。
-
基本定时器:功能最简单,如STM32的TIM6和TIM7,挂载在APB1总线上。它们只有定时中断和DAC功能,适用于基本的传感器应用。
-
3、定时器模式
STM32定时器可以配置为多种模式,以满足不同的应用需求。以下是一些常见的模式:
-
向上计数模式:计数器从0计数到自动加载值(TIMx_ARR),然后重新从0开始计数,并产生一个计数器溢出事件。
-
向下计数模式:计数器从自动装入的值(TIMx_ARR)开始向下计数到0,然后从自动装入的值重新开始,并产生一个计数器向下溢出事件。
-
中央对齐模式:计数器从0开始计数到自动装入的值-1,产生一个计数器溢出事件,然后向下计数到1并且产生一个计数器溢出事件;然后再从0开始重新计数。
-
此外,STM32定时器还支持输入捕获模式、PWM输出模式等。
4、定时器计算方法
STM32定时器的定时时间可以通过以下公式计算:
定时时间=(Prescaler+1)×(Counter Period+1)×1/定时器时钟频率
其中,Prescaler是预分频器的值,Counter Period是自动重装载寄存器的值(也称为计数周期),定时器时钟频率是定时器的时钟信号频率。
5、定时器工作过程
STM32定时器的工作过程如下:
-
时钟信号输入:定时器接收来自内部或外部的时钟信号。
-
预分频器处理:时钟信号经过预分频器进行分频处理,得到较低的频率信号。
-
计数器计数:分频后的信号送入计数器进行计数。计数器可以向上、向下或中央对齐模式进行计数。
-
产生中断或DMA请求:当计数器达到预设的计数周期(即自动重装载寄存器的值)时,产生计数器溢出事件,进而触发中断或DMA请求。
-
处理中断或DMA请求:CPU响应中断或DMA请求,执行相应的中断服务程序或DMA传输操作。
二、使用定时器进行串口通信和点灯
1、工程建立
(1)创建项目,点击ACCEE TO MCU SELECTOR
(2)配置RCC
(3)配置SYS
(4)配置USART1
(5)设置输出引脚(此处笔者设置的PA1)
(6)配置定时器
这里我们使用定时器2和定时器3来实现定时的功能。如图所示,依次点击位置1,选中定时器2;位置2,配置定时器2的时钟源为内部时钟;位置3,分频系数为71,向上计数模式,计数周期为5000,使能自动重载模式。
TIM3与TIM2几乎相同,只有圈中所示位置不同
注意;分频系数那里虽然写的是71,但系统处理的时候会自动加上1,所以实际进行的是72分频。由于时钟我们一般会配置为72MHZ,所以72分频后得到1MHZ的时钟。1MHZ的时钟,计数5000次,得到时间5000/1000000=0.005秒。也就是每隔0.005秒定时器2会产生一次定时中断。
(7)配置NVIC中的中断
(8)时钟配置
如下图所示配置即可
(9)配置项目相关配置
(10)生成项目
2、代码编写
(1)启动定时器
HAL_TIM_Base_Start_IT(&htim2);
HAL_TIM_Base_Start_IT(&htim3);
(2)串口通信
首先在main.c中定义STM32需要给上位机发送的消息
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_1);
}
}
if(htim->Instance == TIM3)
{
if(++time_cnt3 >= 1000)
{
time_cnt3 =0;
HAL_UART_Transmit(&huart1,hello,20,100000);
}
}
}
该函数为定时器的中断回调函数,当产生定时中断的时候,会自动调用这个函数。在函数内部定义了定时器的一个静态变量:time_cnt与定时器3 的time_cnt3。
例如time_cnt,当它大于等于100的时候,才会执行if里面的代码。也就是说需要发生400次中断,才会让LED的状态翻转。前面已经算过了,一次定时中断的时间是0.005秒,所以400次中断的时间是0.005400=2秒。也就是说每隔2秒,LED的状态翻转一次。
例如time_cnt3,当它大于等于1000的时候,才会执行if里面的代码。也就是说需要发生1000次中断,才会让串口发一次消息。0.0051000=5秒,符合题目要求。
结果展示
三、PWM基本介绍
定义
PWM是通过编程控制输出方波的频率和占空比(高低电平的比例)来模拟模拟信号的一种技术。
基本原理
PWM的基本原理是利用微处理器的数字输出来对模拟电路进行控制。在一个PWM周期内,信号处于高电平(或有效电平)的时间与整个周期时间的比例被称为占空比。通过改变占空比,可以控制模拟电路的输出功率。
优点
应用范围
PWM已经广泛应用在各种需要模拟结果的数字控制环境中,如:
主要参数
PWM的产生
在STM32中,PWM是通过配置内部定时器来实现的。定时器的精确计数能力可以用来定义PWM信号的周期和占空比,从而生成非常精确的PWM波形。
PWM工作原理
PWM的工作原理基于定时器和比较寄存器的配合。定时器从0开始计数,当计数器的值达到比较寄存器的值时,输出电平发生翻转。通过不断改变比较寄存器的值,可以控制PWM波的占空比。在一个周期内,定时器的值从0计数到自动重装载值(ARR),然后溢出并重新开始计数。这个过程中,PWM波的频率由定时器的时钟频率、预分频器(PSC)和自动重装载值(ARR)共同决定。
PWM输出的模式区别
STM32中的PWM输出模式有多种,如PWM模式1和PWM模式2等。这些模式的主要区别在于输出电平的翻转时机和占空比的计算方式。例如,在PWM模式1中,当计数器的值小于比较寄存器的值时,输出高电平;而在PWM模式2中,则相反。
PWM的计数模式
STM32的定时器支持多种计数模式,如向上计数模式、向下计数模式和中心对齐模式等。这些计数模式决定了PWM波的波形和对称性。例如,在向上计数模式下,定时器的值从0开始递增到ARR值;而在向下计数模式下,则相反。中心对齐模式则是向上和向下计数模式的结合,生成一个对称的PWM波形。
PWM相关配置寄存器
在STM32中,PWM的相关配置主要通过以下几个寄存器来实现:
四、输出PWM完成呼吸灯
1、创建项目
其他设置基本与前一个实验相同,不用设置中断与USART1,这次我们选择的是TIM3与TIM4,配置方法相同。
设置完毕后便生成项目
2、代码编写
(1)在int main添加如下代码
uint16_t pwmVal = 0; //占空比大小(CCRx的大小)
uint8_t direction = 1; //呼吸灯方向: 1. 越来越亮 2. 越来越暗
HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_1);
(2)在while(1)下添加以下代码
HAL_Delay(3); //控制呼吸灯呼吸速率
//控制占空比大小,即修改CCRx的大小
if(direction){
pwmVal++;
}else{
pwmVal--;
}
//设置了ARR为499,因此每计数500为一个周期
if(pwmVal > 500){
direction = 0; //改变呼吸灯方向
}else if(pwmVal == 0){
direction = 1; //改变呼吸灯方向
}
//修改定时器4通道三的PWM的占空比
__HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_1,pwmVal);
__HAL_TIM_SetCompare(&htim4,TIM_CHANNEL_1,pwmVal);
四.硬件连接
1.线路连接
根据查询数据手册可发现定时器3,4的一通道分别对应引脚PA6
PB6
,然后题目要求还需要直接驱动PC13
(最小开发板上已焊接的LED(固定接在 PC13 GPIO端口)),故而我们将对应PWM波作为输入,连接其对应引脚即可实现所需完成功能。
结果图
五,利用keil仿真并观察波形
点击魔术棒,在Debug选项卡中按照下图的方式进行配置。
然后点击快捷工作栏的Debug选项 ,在下图列表中找到逻辑分析仪
或者在快捷工作栏找到。
然后再弹出的逻辑分析仪窗口的左上角找到Set up选项,在其中添加USART1_SR,如下图所示。
点击colse保存关闭后,就能得到如下的波形,可以看到波形随时间有明显变化。
六,总结
在本次STM32的实验中,笔者深入学习了如何使用定时器实现时间的精准控制,并通过PWM波形驱动LED实现呼吸灯效果。这两个实验不仅让笔者对STM32的定时器功能有了更深入的了解,也让笔者在实践中掌握了多任务并发运行的基本思想。
在第一个实验中,笔者通过配置TIM2和TIM3定时器,分别实现了5秒串口通信和2秒LED闪烁的功能。在配置定时器时,笔者深刻体会到了定时器分频系数、计数周期等参数对定时时间的影响。通过不断调试和优化,笔者成功实现了每隔5秒从串口发送“hello windows!”字符串,并且LED每隔2秒闪烁一次。这个过程不仅锻炼了笔者的动手能力,也让笔者更加理解了定时器的工作原理。
在第二个实验中,笔者使用了TIM3和TIM4定时器输出PWM波形,通过改变PWM的占空比实现了两个LED的呼吸灯效果。在配置PWM时,笔者遇到了一些挑战,如如何选择合适的PWM频率和占空比以实现平滑的呼吸效果。通过查阅资料和不断尝试,笔者最终成功实现了两个LED的呼吸灯效果,并且效果非常理想。
通过这次实验,笔者不仅掌握了STM32定时器和PWM的基本使用方法,还学会了如何根据实际需求进行参数配置和调试。同时,笔者也深刻体会到了理论与实践相结合的重要性。在未来的学习和工作中,笔者将继续运用所学知识,不断探索和实践,努力提高自己的专业技能和实践能力。
作者:Budong..