系列文章目录


【STM32学习笔记】一:基础时钟配置、GPIO输入输出、点亮LED


文章目录


前言

        定时器是单片机学习的重中之重,不论计时、计数、PWM生成、中断等等,都离不开定时器。定时器是什么就不在这里展开赘述了,可以在本站查阅到大量相关资料。本文着重对使用CubeMX进行定时器配置,定时器中断、PWM频率、占空比配置及如何利用PWM方波驱动电机进行讲解。


一、前期准备

        本文以STM32F412RET6芯片为例。首先查阅开发板手册或原理图,找到可以生成PWM的相应引脚。

二、定时器相关函数介绍

HAL_StatusTypeDef HAL_TIM_PWM_Start(TIM_HandleTypeDef *htim, uint32_t Channel);

功能:开启定时器PWM产生。

实例:HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_3);

HAL_StatusTypeDef HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim);

功能:启动定时器中断。

实例:HAL_TIM_Base_Start_IT(&htim1);  

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);

功能:定时器中断回调函数。定时器中断触发后会进入该函数执行。

实例:void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);
{
	if(htim == &htim1)  //判断中断是否来自于定时器1
   {
	    HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_2);
   }
}

 三、PWM输出配置

3.1 时钟配置

        样例工程仍然基于第一章内容。首先配置RCC,高速时钟选择外部时钟。具体方法参考第一章中时钟配置过程:【STM32学习笔记】Cube MX、HAL库——基础时钟配置、GPIO输入输出、点亮LED-CSDN博客

 3.2 定时器配置

1)引脚选择

        查阅自己开发板原理图,找到可以生成PWM信号的引脚。这里我使用了PB10和PC7,图中以PB10一个引脚为例。

2)参数设置

图1 

3)PWM频率计算方式

        例如:配置10kHz的PWM频率。要通过配置预分频和计数周期来计算这个频率。

        之前配置的内部时钟周期配置的是100MHz,而我们要1kHz,那么Prescaler设置成(100-1),Counter Period设置为(1000-1)。设置的这两个数字可以根据实际需求来凑即可,只要算出来是1khz即可。

计算公式:

频率(f)
时间(T)
预分频(Prescaler)
计数周期(Counter Period)
f = timer_clock  / (Prescaler+1) / (Counter_Period+1)  //timer在计算的时候会自动将值+1

计算如下:
Prescaler = 100-1
Counter_Period = 1000-1
f = 100MHz / (100-1+1) / (1000-1+1) = 1000Hz
T = 1/1000 = 1ms

占空比计算:
占空比(Duty Cycle)
比较脉冲值(Pulse)
Duty Cycle = Pulse / (Counter Period+1)

占空比 = 200 / (1000-1+1) = 0.2

        因此,根据图1中参数设定,则会生成频率1kHz、占空比20%的PWM信号。

Keil代码

        在上图所示位置加入下面代码,即可实现PB10引脚上产生 PWM信号。

HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_3);

        使用下文代码使 PB10引脚停止产生PWM信号。

HAL_TIM_PWM_Stop(&htim2,TIM_CHANNEL_3);

四、定时器中断配置

图2

        仍然基于前面的工程文件,选择一个没有用到的TIM,这里选择了TIM1,时钟选择内部时钟,参数设置同上面PWM频率配置。如图2参数配置后,定时器中断间隔为100 000000 / 10000 / 20000 = 0.5Hz,即周期2s。

        在中断设置中使能中断。

Keil代码

1)定时器中断启动

        在上图所示位置加入下面代码,即可启动定时器中断。

HAL_TIM_Base_Start_IT(&htim1);  

2)中断回调函数 

        在图示位置加入下面中断回调函数,每当定时器触发中断后,就会到该函数内执行函数内容。 

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    //中断发生后会进入当前函数
	if(htim == &htim1)  //判断中断是否来自于定时器1
   {
		 HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_2);    //引脚电平反转
   }
}

五、电机控制

        通常利用PWM信号占空比控制电机转速,通过调节PWM信号的占空比,可以改变电机接收到的平均电压。当占空比增加时,电机平均电压也增加,导致电机转速增加。反之,当占空比减小时,电机平均电压减小,电机转速减小。

        查看开发板原理图,确认开发板有没有可直接驱动电机的外设。如H桥、电机控制IC等,不论什么外设,确认其有无使能端。我所使用的开发板上集成了两路H桥,它需要两路IO输出控制其电流输出方向。在这里我使用了PC10和PC11引脚,通过在代码中变换两路IO的状态实现电机转向的控制。

Keil测试代码

void Extend_Linear_actuators(void)		//电推杆伸出
{
	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_10, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_11, GPIO_PIN_SET);
}
void Retracts_Linear_actuators(void)	//电推杆退回
{
	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_10, GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_11, GPIO_PIN_RESET);
}
void Stop_Linear_actuators(void)		//电推杆停止
{
	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_10, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_11, GPIO_PIN_RESET);
}

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐