前言
關於電機的選擇。
學校發的無刷電機:
我們準備的有刷電機:
帶霍爾編碼器!
電機引數:
名稱:馳名電機(直流減速電機)型號:JGA25-370
電壓:12V
轉數:1360r/min
既然做雲臺,那麼核心是PID控制。PID以後再講。本期先講電機的部分內容。
無刷or有刷?
無刷電機需要foc控制與SVPWM調製,演算法較為繁瑣。搗鼓期間也遇到不少bug,故舍棄無刷電機,選擇有刷電機。為啥?程式碼簡單唄!
(補充:若無刷電機用PWM而不是SVPWM,則會很燙很燙,燒起來也說不定~)
一、硬體準備
- stm32F401/411開發版(SAST)
- J-LINK/ST-LINK下載器
- 直流有刷電機JGA25-370(帶編碼器)
- 電機驅動板L298N/TB6612
- 12V鋰電池
二、工程配置
新建stm32工程,這裡採用的是cubmx+keil5方式。(不會還用人用標準庫吧:-))
我用的是F411。
1、嘗龜配置
使用外部高速晶振、Debug選Serial Wire。(我用的是J-LINK下載器)時鐘樹開HCLK為100MHz。(F411最大HCLK)
2、設定PWM輸出
TIM5設定為內部時鐘—CH3—PWM Generation。命名為PWM。
一般而言,給電機的PWM波大約20kHz。
配置HCLK
=100MHz(F411最大HCLK
),PSC
=50-1,ARR
=100-1。
由頻率計算公式可得:
其餘預設配置即可。
別忘了在NVIC Settings使能中斷。
3、設定兩個IO口輸出
用於控制電機轉動方向,命名為DIR1和DIR2。
設定PA3—Output與PA4—Output。其餘預設配置即可。
4、設定編碼器模式
關於編碼器模式,很多人可能不李姐。詳細的會在以後的文章裡寫。這裡先粗略寫一下。
電機工作時,通過霍爾編碼器輸出AB相脈衝,微控制器讀取脈衝數以得到轉速與角度等資訊,我們還要對採集到的資料進行處理。而stm32定時器正好有個編碼器模式,我們只需讀取定時器計數值就能知道脈衝數為多少。
TIM2—Combined Channels—Encoder Mode
下面的都不用設定。
把圖中的三個(TIM2_CH1和TIM2_CH2和PWM)Signal Pinning一下。
5、設定中斷
開啟一個定時器更新中斷,在這個中斷裡我們處理編碼器的資料以得到轉速、角度等資訊,並進行PID控制。
TIM4設定為內部時鐘即可。
配置HCLK
=100MHz(F411最大HCLK
),PSC
=1000-1,ARR
=1000-1。
中斷一般為100Hz。
別忘了在NVIC Settings使能中斷。
6、開啟一個串列埠
用於除錯。
嘗龜設定,設定設定MODE為非同步通訊(Asynchronous)。其餘的預設即可。(波特率為115200)
別忘了在keil裡寫串列埠重定向。
7、生成keil工程
嘗龜配置。
設定工程名稱、路徑(不要有中午路徑),
配置IDE為MDK-ARM。程式碼生成配置勾選圖中紅框處。
點選GENERATE CODE生成工程!
8、keil配置
開啟工程配置,勾選“use MicroLIB”,Debug選擇J-LINK,並在Settings-Flash-Download勾選“Reset and Run”,然後編譯一次。
接下來加上串列埠重定向:
先包含標頭檔案#include<stdio.h>
,在/* USER CODE BEGIN 4 // USER CODE END 4 */之間新增以下程式碼:
int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
return ch;
}
int fgetc(FILE *f)
{
uint8_t ch = 0;
HAL_UART_Receive(&huart1, &ch, 1, 0xffff);
return ch;
}
工程基本配置ok!
三、驅動板L298N/TB6612
電機驅動需要驅動板,直接用微控制器驅動是不行的。我們比賽時用的是L298N。
1、L298N
L298N驅動模組,可以驅動2個直流電機,可分別實現正轉,反轉功能。
供電:L298N的12V和5V都接5V供電,GND不但要接驅動電源的GND。這裡要和微控制器連線在一起,要從這裡再引出一根GND和微控制器的GND相連(共地)。
OUT1、OUT2和OUT3、OUT4分別接兩個直流電機Motor1兩腳、Motor2兩腳,IN1、IN2、IN3、IN4引腳從微控制器接入控制電平,控制電機的正反轉,ENA、ENB接控制使能端,控制電機調速,L298N控制邏輯關係圖如下:
對於ENA通道使能引腳,若不考慮電機的轉速,可接為高電平或低電平控制接通還是關斷。
若需要控制電機的轉速,則需要拔掉跳線帽,將其連線在微控制器PWM輸出上,通過調節PWM的佔空比,以此來達到控制轉速的目的。
轉速控制原理:利用STM32 的IO輸出不同佔空比的脈衝訊號來達到調速的過程,當佔空比大的時候就表明在一個脈衝週期內高電平的時間越長,而脈衝訊號輸出頻率極快,高電平的時間越長就表明在一段時間內IO口輸出的控制電壓越高,控制電壓越高使得L298N輸出的電壓越高,這樣就使得車輪的轉速越快。
接線:
這裡我們因為只要一個電機轉,故OUT3、OUT4接電機的兩腳,IN3、IN4分別接PA3、PA4控制轉動方向,ENB接PA2輸出PWM,12V供電腳和GND接12V鋰電池,GND和微控制器共地。
2、TB6612
原理、接線類似於L298N。此處不再贅述。
接下來是程式碼部分。
首先我們讓電機轉起來!
四、PWM控制
先寫定時器PWM輸出啟動函式:
/* USER CODE BEGIN 2 */
HAL_TIM_PWM_Start(&htim5, TIM_CHANNEL_3);
/* USER CODE END 2 */
然後寫一個PWM調製函式void set_pwm(int pwm);
int型變數pwm的範圍應在-100~100之間(ARR設定的值為100),將它賦值給CRR(通過調節CRR的值來調節PWM波佔空比,進而實現轉速控制)。pwm的正負表示轉動方向,分別使PA3和PA4輸出不同電平來控制方向(見邏輯表)。
/* USER CODE BEGIN 4 */
void set_pwm(int pwm)
{
//限定pwm範圍
if(pwm > 100)pwm = 100;
if(pwm < -100)pwm = -100;
//轉速控制
if(pwm < 0)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, 1);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 0);
}
if(pwm > 0)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, 0);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 1);
}
//寫CRR的值調節佔空比
TIM5->CCR3 = (int)fabs((float)pwm); //記得#include<math.h>
}
/* USER CODE END 4 */
比如,輸出一個佔空比50%的PWM波控制電機正轉:
set_pwm(50);
OK本期就到這裡。往後還有電機控制part2、3,分別分享PID、編碼器相關。還有MPU6050移植從入坑到入墳。