【一】工程配置與電機控制part1


前言

關於電機的選擇。
學校發的無刷電機:

我們准備的有刷電機:

帶霍爾編碼器!

電機參數:
名稱:馳名電機(直流減速電機)

型號: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波大約2kHz

配置HCLK=100MHz(F411最大HCLK),PSC=50-1,ARR=1000-1。

由頻率計算公式可得:

\[f=\frac{freq(HCLK)}{(PSC+1)*(ARR+1)}=\frac{100,000,000}{50*1000}=2kHz \]

其余默認配置即可。
(注:因為是PWM輸出,所以沒必要使能NVIC中斷)

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

\[f=\frac{freq(HCLK)}{(PSC+1)*(ARR+1)}=\frac{100,000,000}{1000*1000}=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 > 1000)pwm = 1000;

    if(pwm < -1000)pwm = -1000;

    //轉速控制
    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(500);

OK本期就到這里。往后還有電機控制part2、3,分別分享PID、編碼器相關。還有MPU6050移植從入坑到入墳。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM