文章目录
一、定时器的相关介绍
1.定时器的含义
定时器是SoC的常见外设
(1)定时器和计数器。计数器是用来计数的(每隔一个固定时间会计一个数);因为计数器的计数时间周期是固定的,因此到了一定时间只要用计数值x计数时间周期,就可以得到一个时间段,这个时间段就是我们定的时间(这就是定时器)。
(2)定时器/计数器作为SoC的外设,主要用来实现定时执行代码的功能。定时器相对于SoC来说,就好象闹钟相对于人来说意义一样。
2.定时器的作用
1)定时器可以让SoC在执行主程序的同时,具有计时功能(通过定时器),到了一定时间(计时结束)后,定时器会产生中断提醒CPU,CPU会去处理中断并执行定时器中断的ISR。从而去执行预先设定好的事件。
(2)定时器就好象是CPU的一个秘书一样,这个秘书专门管帮CPU来计时,并到时间后提醒CPU要做某件事情。所以CPU有了定时器之后,只需预先把自己xx时间之后必须要做的事情绑定到定时器中断ISR即可,到了时间之后定时器就会以中断的方式提醒CPU来处理这个事情。
3.定时器的原理
(1)定时器计时其实是通过计数来实现的。 定时器内部有一个计数器,这个计数器根据一个时钟(这个时钟源来自于ARM的APB总线 66MHz,然后经过时钟模块内部的分频器来分频得到)来工作。每隔一个时钟周期,计数器就计数一次,定时器的时间就是计数器计数值×时钟周期。
(2)定时器内部有1个寄存器TCNT,计时开始时我们会把一个总的计数值(初值)放入TCNT寄存器中,然后每隔一个时钟周期(假设为1ms)TCNT中的值会自动减1(硬件自动完成,不需要CPU软件去干预),直到TCNT中减为0的时候,TCNT就会触发定时器中断。
(3)定时时间是由2个东西共同决定的:一个是TCNT中的计数值,一个是时钟周期,两者的乘积即为最终定时的时间。
4.与定时器有关的器件
(1)PWM定时器
PWM(pulse wide modulation 脉宽调制)
PWM波形是一个周期性波形,周期为T,在每个周期内波形是完全相同的。每个周期内由一个高电平和一个低电平组成。
PWM波形有2个重要参数:一个是周期T,另一个是占空比 duty(占空比就是一个周期内高电平的时间除以周期时间的商)。
对于一个PWM波形,知道了周期 T和占空比duty,就可以算出这个波形的所有细节。譬如高电平时间为T x duty,低电平时间为T*(1-duty)。
PWM波形有很多用处,譬如通信上用PWM来进行脉宽调制对基波进行载波调制;在发光二极管LED照明领域可以用PWM波形来调制电流进行调光;用来驱动蜂鸣器等设备。
(2)系统定时器
(3)看门狗
其实是一个定时器,只不过定时器时间到了之后不只是中断,还可以复位CPU。
看门狗定时器和普通的定时器并无本质区别。定时器可以设定一个时间,在这个时间完成之前定时器不断计时,时间到的时候定时器会复位CPU(重启系统)。
普通设备重启不是问题,但是有些设备人工重启存在困难。这时候我们希望系统能够自己检验自己是否已经跑飞,并且在意识到自己跑飞的时候,可以很快的(几个ms或者更短)自我重启。这个功能就要靠看门狗定时器来实现。
我们在应用程序中打开看门狗设备,初始化好给它一个时间,然后应用程序使用一个线程来喂狗,这个线程的执行时间安全短于看门狗的复位时间。当系统(或者应用程序)异常后,喂狗线程自然就不工作了,然后到时候看门狗就会复位。
实战中有时候为了绝对的可靠,我们并不会用SoC中自带的看门狗,而是使用专门的外置的看门狗芯片来实现看门狗。
(4)实时时钟RTC(real time clock)
RTC是实时时钟,RTC是实时时钟,它和定时器的差别就好象闹钟(定时器)和钟表(RTC)的差别一样。
RTC是SoC中一个内部外设,RTC有自己独立的晶振提供RTC时钟源(32.768KHz),内部有一些寄存器用来记录时间(年月日时分秒星期)。一般情况下为了在系统关机时时间仍然在走,还会给RTC提供一个电池供电。
5.定时器的功能
(1)基本定时器(TIM6,TIM7)的主要功能:
只有最基本的定时功能,。基本定时器TIM6和TIM7各包含一个16位自动装载计数器,由各自的可编程预分频器驱动。
(2)通用定时器(TIM2~TIM5)的主要功能:
除了基本的定时器的功能外,还具有测量输入信号的脉冲长度( 输入捕获) 或者产生输出波形( 输出比较和PWM)
(3)高级定时器(TIM1,TIM8)的主要功能:
高级定时器不但具有基本,通用定时器的所有的功能,还具有控制交直流电动机所有的功能,你比如它可以输出6路互补带死区的信号,刹车功能等等。
二、实现LED等周期性闪烁(2s),同时实现串口发送“hello windows!”(5s)
1.STM32CubeMX工程创建
(1)打开STM32CubeMX主界面,点击“ACCESS TO MCU SELECTOR”,创建新项目
(2)在“Commerical Part Number”里面选择自己需要的芯片,点击信息栏中的具体芯片信息选中,再点击“Start Project”
(3)先点击System Core将其展开,再点击RCC,将HSE设置为Crystal/Ceramic Resonator
(4)点击SYS,将Debug设置为Serial Wire
(5)点击GPIO,将C15设置为GPIO_Output
(6)先点击Timers将其展开,再点击TIM2,将“Clock Source”设置为Internal Clock,然后点击“Parameter Settings”,按下图设置相关参数
(7)点击NVIC,勾选TIM2 global interrupt
(8)点击Code generation,勾选生成定时器2中断优先级配置代码和HAL库配置代码
(9)先点击Connectivity将其展开,再点击USART1,将Mode设置为Asynchronous
(10)点击Clock Configuration勾选PLLCLK和HSE,将晶振频率设置为最大值72MHz
(11)点击Project Manager→Project,配置好自己的项目名和项目存放路径,然后将IDE设置为MDK-ARM
(12)点击Code Generate界面,选择生成初始化文件.c/.h,之后再点击GENERATE CODE即可成功创建工程
2.程序编写
(1)在点击GENERATE CODE之后弹出来的界面点击Open Project即可跳转到Keil5进行程序编写
(2)打开main.c文件
◉在main函数中加入如下代码:
HAL_TIM_Base_Start_IT(&htim2);
“htim2”中“h”表示HAL库,“tim2”表示定时器2。所以这行代码的意思就是启动定时器2。
◉在while循环后面添加如下代码:
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
static uint32_t time_cnt =0;
if(htim->Instance == TIM2)
{
++time_cnt;
int flag=0;
if((time_cnt%400==0))
{
HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_15);
if(time_cnt>=1000)
{
time_cnt =0;
char data[]="hello windows!\n";
HAL_UART_Transmit(&huart1, (uint8_t *)data, 15, 0xffff);
}
}
}
}
该函数为定时器的中断回调函数,当产生定时中断的时候,会自动调用这个函数。在函数内部定义了一个静态变量:time_cnt。当它≥400的时候,才会执行if里面的代码。也就是说需要发生400次中断,才会让LED的状态翻转。前面已经算过了,一次定时中断的时间是0.005秒,所以400次中断的时间是0.005*400=2秒。也就是说每隔2秒,LED的状态翻转一次。
3.程序编译及hex文件创建
点击Rebuild编译程序,若没有错误即可成功创建hex文件
4.电路连接
USB转TTL | STM32F103C8T6 |
---|---|
GND | GND |
3v3 | 3v3 |
TXD | A10 |
RXD | A9 |
LED负极接STM32F103C8T6的C15管脚,正极接3.3v管脚。
5.程序烧录
置BOOT0为0,BOOT1为1
(1)打开mcuisp,选择串口为COM5,并选择生成的hex文件
(2)点击读器件信息,若显示一切正常则进行下一步
(3)点击开始编程,若显示一切正常则说明烧录成功
6.串口调试
打开野火串口调试助手,将端口设置为COM5,波特率设置为115200,数据位设置为8,停止位设置为1,校验位设置为None,然后点击打开串口
7.运行结果
由上面两个运行结果可以看到,LED呈2s的等周期性闪烁;并且串口调试助手接收区每隔5s发送一次“hello windows!”,说明实验成功!
三、总结
本次实验通过定时器Timer方式实现时间的精准控制,实现了每隔5秒从串口发送“hello windows!”;同时实现了让LED呈2秒的等周期性闪烁。在实验过程中,我遇到了一些问题,例如对定时器理解不够导致STM32CubMX中某些参数未设置或设置错误,连接电路时未注意管脚导致连线错误,编写程序时添加的代码位置错误等,这些问题都导致达不到预期实验效果,经过一遍遍地检查与调试,最终实现了LED的周期闪烁和串口通信。通过本次实验,我了解了定时器的相关知识及应用,也对串口通信有了进一步的理解,但未来仍需好好学习相关知识,加深理解。
四、参考链接
http://www.mcublog.cn/stm32/2021_01/stm32cubemx-dingshiqi-led/
https://blog.csdn.net/jack123345667/article/details/108100283
https://blog.csdn.net/aricchen77/article/details/112298126