??大家好,我是小政,本篇文章我將針對PWM控制電機與編碼器讀取電機轉速的STM32CubeMX配置程序進行詳細的講解,讓準備學習HAL庫的小伙伴能夠更好的理解STM32CubeMX如何配置,
有小伙伴對于電機驅動和編碼器不懂的話請看:
電機驅動講解:【平衡小車制作】(二)電機驅動(超詳解)
編碼器講解:【平衡小車制作】(三)編碼器講解(超詳解)
??下一篇文章會推出利用PID演算法倍訓控制電機轉速(HAL庫),
??話不多說,開始今天的學習吧!
1、硬體準備
(1)所需硬體
- 芯片:STM32F103RCT6
- 驅動:電機驅動板或TB6612(電機驅動芯片)
- 電池:12V Libo電池
- 電機:帶編碼器電機
- 輪子:我用的是麥克納姆輪
(2)硬體連接:
- PA8 —— 電機驅動板PWM1
- GND —— 電機驅動板PWM2
(這里若要反轉則PWM1接地,PWM2接PA8;如果在小車中兩者都需接PWM引腳,正轉:PWM1給一定占空比,PWM2占空比為0) - PA9(USART1_RX) —— 接串口TX
- PA10(USART1_TX) —— 接串口RX
- PB6 —— 編碼器A
- PB7 —— 編碼器B
2、STM32CubeMX配置:
1.1 所用工具:
- 芯片:STM32F103RCT6
- IDE:MDK-Keil軟體
- STM32F1xxHAL庫
1.2 知識概括:
- STM32CubeMX創建TIMx、USART例程
- Keil軟體程式撰寫
1.3 工程創建
1、芯片選擇
??芯片:STM32F103RCT6(根據自己的板子來進行選擇)

2、設定RCC
??設定高速外部時鐘HSE 選擇外部時鐘源

3、LED1配置
??我使用的板子LED1引腳為PD2,初始電平為高電平,目的是通過觀察小燈的亮滅判斷是否進入定時器中斷

4、USART1配置
??異步收發,波特率默認:115200 Bit/s

5、PWM配置
??使用定時器1通道1和通道4(TIM1_CH1和TIM1_CH4),頻率10KHz

6、定時器中斷配置
??使用定時器2(TIM2),周期設為10ms,即10ms進一次定時器中斷

??打開更新定時器中斷

7、編碼器配置
??STM32自帶編碼器配置,使用定時器4(TIM4_CH1和TIM4_CH2),打開更新定時器中斷

8、中斷優先級配置
??因為編碼器中斷要發生在定時10ms中斷內,故編碼器中斷的搶占優先級要大于定時10ms

9、配置時鐘
??F1系列芯片系統時鐘為72MHzs

10、專案創建最后步驟
- 設定專案名稱
- 選擇所用IDE

11、輸出檔案
- ②處:復制所用檔案的.c和.h
- ③處:每個功能生產獨立的.c和.h檔案

12、創建工程檔案
??點擊GENERATE CODE 創建工程
13、配置下載工具
??這里我們需要勾選上下載后直接運行,然后進行一次編譯

3、STM32源代碼:
(1)下面的代碼之前有用過hal庫的小伙伴應該都很容易理解,小政就不過多解釋,有不懂的地方歡迎在評論區下方提問,在main.c加上:
/* USER CODE BEGIN Includes */
#include "stdio.h"
#include "math.h"
/* USER CODE END Includes */
/* USER CODE BEGIN PV */
unsigned int MotorSpeed; // 電機當前速度數值,從編碼器中獲取
int MotorOutput; // 電機輸出
/* USER CODE END PV */
/* USER CODE BEGIN 0 */
int fputc(int ch, FILE *p)
{
while(!(USART1->SR & (1<<7)));
USART1->DR = ch;
return ch;
}
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1); // TIM1_CH1(pwm)
HAL_TIM_Encoder_Start(&htim4, TIM_CHANNEL_1); // 開啟編碼器A
HAL_TIM_Encoder_Start(&htim4, TIM_CHANNEL_2); // 開啟編碼器B
HAL_TIM_Base_Start_IT(&htim2); // 使能定時器2中斷
/* USER CODE END 2 */
/* USER CODE BEGIN 4 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
static unsigned char i = 0;
if (htim == (&htim2))
{
//1.獲取電機速度
MotorSpeed = (short)(__HAL_TIM_GET_COUNTER(&htim4)/18);
// TIM4計數器獲得電機脈沖,該電機在10ms采樣的脈沖/18則為實際轉速的rpm
__HAL_TIM_SET_COUNTER(&htim4,0); // 計數器清零
//2.將占空比匯入至電機控制函式
MotorOutput=3600; // 3600即為50%的占空比
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, MotorOutput);
MotorOutput=MotorOutput*100/7200;
// 占空比(按最高100%計算,串口列印)
i++;
if(i>100)
{
// 通過觀察小燈亮滅來判斷是否正確進入定時器中斷
HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_2);
// 列印定時器4的計數值,short(-32768——32767)
printf("Encoder = %d moto = %d \r\n",MotorSpeed,MotorOutput);
i=0;
}
}
}
/* USER CODE END 4 */
(2)燒入STM32中,串口展示:

(3)實物展示:

4、下載
(1)程式下載地址:https://pan.baidu.com/s/1mXYS8lQKaMX6XNA961UuJw
提取碼:z3ax
(2)串口助手下載地址:https://pan.baidu.com/s/11xBkoLBMVcIv7QNALpOeeg
提取碼:yzx3
5、總結
??以上就PWM控制電機轉速與編碼器讀取電機速度的HAL庫配置與keil編程,后續會推出利用PID演算法倍訓控制電機轉速(HAL庫),若文章中出現錯誤或者小伙伴對以上內容有所疑問,歡迎大家在評論區留言,小政看到后會盡快回復大家!我們下期再見!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/263911.html
標籤:其他
