STM32定時器應用——輸出PWM給電機調速


源碼下載
分享鏈接PWM資料下載
密碼:123456


一、PWM簡介

簡單來說,存在一個計數器,計數值隨時間進行週期性變化。最小值和最大值之間存在一個自定的值,當計數器的值小於自定值時,I/O輸出低電平,大於自定值則產生高電平。通過設置不同的最大值和自定值,可以控制I/O口輸出不同時間寬度的高低電平。

圖1.1 來自百度百科

二、硬件部分

  • 摘要
    運用定時器調整PWM輸出值,使直流電機從慢到快,再從快到慢。

  • 硬件設備:

名稱 型號 數量
STM32開發板 STM32F407ZGT6 1
電機驅動 L298N 1
電機 普通直流 1
電池 9V鋰電池 1
導線 杜邦線 若干
  • 硬件連接
  1. (STM32) PA9-------IN1 (L298N)
  2. (STM32) PA10------IN2 (L298N)
  3. (STM32) PF9-------ENA (L298N)
  4. 直流電機------OUT1, OUT2 (L298N)
  5. 9V電池------12V、GND(L298N)

備註:

  1. 所有GND接口都應接在一起,不然會出現電機轉動異常。
  2. L298N的12V口接輸入電源(5V~12V均可)
  3. L298N的5V口接單片機5V口,用於給單片機供電
  4. 拔掉ENA上的帽子,本實驗中ENA接單片機的PWM輸出口PF9

預覽:
在這裏插入圖片描述

  • 現象
    打開電源,直流電機轉動速度由慢到快,再由快到慢週期變化。

三、軟件部分

1. PWM初始化 pwm.c

/**@file     pwm.c
* @brief     PWM初始化
* @author    BROSY
* @date      2020年4月19日
* @version   V1.0
* @copyright CSU | BROSY
*******************************************************************************
* @par 修改日誌:
* <table>
* <tr><th>Date        <th>Version  <th>Author    <th>Description
* <tr><td>2018/08/17  <td>1.0      <td>songqijin  <td>創建初始版本
* </table>
*******************************************************************************
*/

/*=============================== 頭文件包含 ================================*/
#include "pwm.h"

/*================================ 接口函數 =================================*/
/******************************************************************************
 * @brief   PWM初始化
 * @details 初始化定時器14,I/O口F9,PWM設置
 * @param   [in]arr   定時器分頻(u32)
 * @param   [in]psc   自動重裝載值(u32)
 * @return  void
 *****************************************************************************/
void TIM14_PWM_Init(u32 arr, u32 psc)
{
	GPIOF9_Init(); 		  ///< 初始化PWM輸出口GPIOF9
	TIM14_Init(arr, psc); ///< 初始化定時器TIM14
	PWM_Init(); 		  ///< 初始化PWM	
}

/******************************************************************************
 * @brief   GPIOF9初始化
 * @details 複用映射到TIM14,F9作爲PWM輸出口
 * @param   void
 * @return  void
 *****************************************************************************/
void GPIOF9_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure; ///< 定義GPIO初始化結構體
	
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE); ///<使能GPIOF時鐘
	
	/*!
	* GPIOF9初始化設置
	*/
	{
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;           ///< GPIOF9
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;        ///< 複用功能
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;	///< 速度100MHz
		GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;      ///< 推輓複用輸出
		GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;        ///< 上拉
		GPIO_Init(GPIOF,&GPIO_InitStructure);               ///< 初始化PF9
	}
	
	/*GPIOF9複用映射到定時器14*/
	GPIO_PinAFConfig(GPIOF, GPIO_PinSource9, GPIO_AF_TIM14);
}

/******************************************************************************
 * @brief   定時器14初始化
 * @param   [in]arr   定時器分頻(u32)
 * @param   [in]psc   自動重裝載值(u32)  
 * @return  void
 *****************************************************************************/
void TIM14_Init(u32 arr, u32 psc)
{
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure; ///< 定義定時器初始化結構體
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14, ENABLE); ///< 使能TIM14時鐘
	
	/*!
	* 初始化定時器TIM14
	*/
	{
		TIM_TimeBaseStructure.TIM_Prescaler=psc;  				  ///< 定時器分頻
		TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; ///< 向上計數模式
		TIM_TimeBaseStructure.TIM_Period=arr;   				  ///< 自動重裝載值
		TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; 	  ///< 分頻模式
		TIM_TimeBaseInit(TIM14,&TIM_TimeBaseStructure);			  ///< 初始化定時器14
	}
	
}

/******************************************************************************
 * @brief   PWM初始設置
 * @param   void
 * @return  void
 *****************************************************************************/
void PWM_Init()
{
	TIM_OCInitTypeDef TIM_OCInitStructure;

	/*!
	* 初始化PWM輸出通道
	*/
	{
		TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; 				///< PWM模式1,“小於”有效
		TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCPolarity_Low; 		///< 低電平有效
		TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; 	///< 輸出使能
		TIM_OC1Init(TIM14, &TIM_OCInitStructure); 						///< 初始化PWM輸出通道
	}
		
	/*!
	* 使能預裝載寄存器
	*/
	{
		TIM_OC1PreloadConfig(TIM14, TIM_OCPreload_Enable); ///< 使能TIM14在CCR1上的預裝載寄存器
		TIM_ARRPreloadConfig(TIM14,ENABLE); 			   ///< ARPE使能
	}
	
	TIM_Cmd(TIM14, ENABLE);  ///< 使能TIM14
}

2. PWM初始化pwm.h

/**@file     pwm.h
* @brief     PWM初始化
* @author    BROSY
* @date      2020年4月19日
* @version   V1.0
* @copyright CSU | BROSY
*******************************************************************************
* @par 修改日誌:
* <table>
* <tr><th>Date        <th>Version  <th>Author    <th>Description
* <tr><td>2018/08/17  <td>1.0      <td>songqijin  <td>創建初始版本
* </table>
*******************************************************************************
*/

#ifndef __PWM_
#define __PWM_

/*=============================== 頭文件包含 ================================*/
#include "sys.h"

/*===============================函數聲明 ===================================*/
void GPIOF9_Init(void); ///< 初始化GPIOF9
void TIM14_Init(u32 arr, u32 psc); ///< 初始化定時器TIM14
void PWM_Init(void); ///< PWM初始設置
void TIM14_PWM_Init(u32 arr, u32 psc); ///< 初始化PWM
#endif

3. 電機控制motor.c

/**@file     motor.c
* @brief     電機對應I/O口初始化
* @author    BROSY
* @date      2020年4月19日
* @version   V1.0
* @copyright CSU | BROSY
*******************************************************************************
* @par 修改日誌:
* <table>
* <tr><th>Date        <th>Version  <th>Author    <th>Description
* <tr><td>2018/08/17  <td>1.0      <td>songqijin  <td>創建初始版本
* </table>
*******************************************************************************
*/

/*=============================== 頭文件包含 ================================*/
#include "motor.h"
#include "sys.h"

/*================================ 接口函數 =================================*/
/******************************************************************************
 * @brief   PA9, PA10初始化
 * @details PA9輸出高電平,PA10輸出低電平。
 * @param   void
 * @return  void
 *****************************************************************************/
void MOTOR_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructrue; ///> 定義GPIO結構體
	
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); ///> 使能GPIOA時鐘
	
	/*!
	* 初始化GPIOA9, GPIOA10
	*/
	{
		GPIO_InitStructrue.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; ///> 初始化PA9, PA10
		GPIO_InitStructrue.GPIO_Mode = GPIO_Mode_OUT; 			///> 普通輸出模式
		GPIO_InitStructrue.GPIO_OType = GPIO_OType_PP; 			///> 推輓輸出
		GPIO_InitStructrue.GPIO_Speed = GPIO_Speed_100MHz; 		///> 輸出頻率爲100MHz
		GPIO_InitStructrue.GPIO_PuPd = GPIO_PuPd_UP; 			///> 上拉,輸出高電平
		GPIO_Init(GPIOA, &GPIO_InitStructrue); 					///> 初始化GPIO
	}
	
	GPIO_SetBits(GPIOA, GPIO_Pin_9); 	///> P9設置爲高電平
	GPIO_ResetBits(GPIOA, GPIO_Pin_10); ///> P10設置爲低電平
}

4. 電機控制motor.h

/**@file     motor.h
* @brief     電機對應I/O口初始化
* @author    BROSY
* @date      2020年4月19日
* @version   V1.0
* @copyright CSU | BROSY
*******************************************************************************
* @par 修改日誌:
* <table>
* <tr><th>Date        <th>Version  <th>Author    <th>Description
* <tr><td>2018/08/17  <td>1.0      <td>songqijin  <td>創建初始版本
* </table>
*******************************************************************************
*/
#ifndef __MOTOR_
#define __MOTOR_

/*===============================函數聲明 ======================================*/
void MOTOR_Init(void); ///< 初始化電機對應I/O口 PA9, PA10
#endif

5. 備註

  1. PWM頻率過高會導致電機發出蜂鳴聲
  2. 電機轉速較慢可能是因爲GND接口沒有接到一起
  3. 找不到頭文件可能是因爲沒有設置包含路徑

三、參考資料

B站視頻:【正點原子】stm32f4視頻教程(初級篇)
文字資料站:正點原子論壇


四、資料下載

分享鏈接PWM資料下載
密碼:123456


喜歡搞事情、DIY、學技術的同學可以關注下面這個的公衆號,瞭解更多有更趣的項目。
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章