系列文章目录
STM32CubeIDE(CUBE-MX hal库)----初尝点亮小灯
STM32CubeIDE(CUBE-MX hal库)----按键控制
STM32CubeIDE(CUBE-MX hal库)----串口通信
文章目录
- 系列文章目录
- 前言
- 一、定时器
- 二、使用步骤
- 三、HAL库实验代码
- 三、标准库代码
前言
STM32定时器是一种多功能外设,可以为嵌入式系统提供各种定时和计数功能。通过合理配置,它可以适应各种应用场景,提供精准的定时和计数功能,使嵌入式系统更加灵活和可控。
一、定时器
功能:定时、捕获脉冲、计算PWM占空比、输出PWM波形、编码器计数。
如何进行计数:如果时钟输入频率是72MHZ,则计数器计数到72000000用了一秒钟。但是计数器寄存器的位数16bit只能计数65536/72000000次/秒=0.0009秒。所以需要一个预分频器(顾名思义是将频率进行降低计算公式 频率/(分频数+1)不分频就设为0)也是一个16位的寄存器,可进行65536次分频。则定时器最多可定时65536×65536/72000000=59.65s
二、使用步骤
设置串口一用于打印调试信息
打开串口中断
将高速外部时钟源设为晶振可以提高定时精度
时钟设置
定时器设置
定时器参数设置,下面的设置实现了1s的定时,如果想要0.5s的定时则将分频系数设为7199,计数值设为4999。计算过程72000000/(7199+1)/(4999+1)=2Hz 赫兹(Hz)是频率的单位,表示每秒的周期数。要将赫兹转换为秒 1/2=0.5s
定时器中断设置
三、HAL库实验代码
实验一:观察计数器的数值是如何变化的,只需要在已有的代码中加入以下代码头文件包含
/* USER CODE BEGIN Includes */
#include <string.h>
#include <string.h>
/* USER CODE END Includes */
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start(&htim4);
int counter=0;
char message[20];
/* USER CODE END 2 */
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_TIM4_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start(&htim4);
int counter=0;
char message[20];
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
counter=__HAL_TIM_GET_COUNTER(&htim4);//获取计数�?
sprintf(message,"counter: %d",counter);
HAL_UART_Transmit_IT(&huart1, (uint8_t *)message, sizeof(message));
HAL_Delay(99);//延时100ms
}
/* USER CODE END 3 */
}
__HAL_TIM_SET_COUNTER 设置计数器的值
__HAL_TIM_GET_COUNTER 获取计数器的值
__HAL_TIM_SET_AUTORELOAD 设置重装载计数器的值
__HAL_TIM_GET_AUTORELOAD 获取重装载计数器的值
__HAL_TIM_SET_PRESCALER 设置预分频器的值
实验现象
实验二:利用定时器中断实现计时功能,通过重写HAL_TIM_PeriodElapsedCallback函数,实现每隔1s触发一次中断,num自增一向串口助手传num的值。
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) 函数是在使用STM32的HAL(Hardware Abstraction Layer)库时,用于处理定时器(TIM)定时周期到达事件的回调函数。该函数在定时器的中断服务子程序(ISR)中被调用,用于用户定义的处理。
参数 TIM_HandleTypeDef *htim 是一个指向定时器处理结构体的指针,其中包含了有关定时器的信息,如定时器的基地址、计数器值、定时器配置等。
uint8_t num=0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim==&htim4){
num++;
HAL_UART_Transmit_IT(&huart1, &num, 1);
}
}
实验现象
三、标准库代码
定时器初始化
void Timer_Init(void)
{
//开启时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);
//选择时基单元的时钟 选择内部时钟 默认使用内部时钟可以不写
TIM_InternalClockConfig(TIM4);
//配置时基单元
TIM_TimeBaseInitTypeDef TimeBaseInitStructure;
TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;//时钟分频 不进行分频
TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;//计数方式 向上计数
TimeBaseInitStructure.TIM_Period=10000-1 ; //自动重装载的值
TimeBaseInitStructure.TIM_Prescaler=7200-1;//预分频系数
TimeBaseInitStructure.TIM_RepetitionCounter=0;//重复计数器高级定时器里面才有
TIM_TimeBaseInit(TIM4,&TimeBaseInitStructure);//时基初始化
TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE);//使能定时器中断
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn; //TIM3中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //先占优先级2级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //从优先级1级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure); //初始化NVIC寄存器
TIM_Cmd(TIM4,ENABLE);//开启定时器
}
中断服务函数
void EXTI4_IRQHandler(void)
{
if(TIM_GetITStatus(TIM4,TIM_IT_Update)==SET) //检查定时器中断标志位是否置位
{
num++;
TIM_ClearITPendingBit(TIM4,TIM_IT_Update);
}
}
hal库和标准库函数对比
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)--------->void EXTI4_IRQHandler(void)(标准库)
HAL_StatusTypeDef HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim)和TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE);功能类似开启定时器中断
。