1. 程式人生 > 其它 >19-CubeMx+Keil+Proteus模擬STM32 - 直流電動機

19-CubeMx+Keil+Proteus模擬STM32 - 直流電動機

本文例子參考《STM32微控制器開發例項——基於Proteus虛擬模擬與HAL/LL庫》
原始碼:https://github.com/LanLinnet/STM33F103R6

專案要求

理解H橋電路的工作原理,結合前面幾個專案學習過的PWMEXTI串列埠通訊等,要求通過5個按鈕控制直流電動機的執行狀態,包括:電動機正轉、電動機反轉、電動機停止、電動機加速和電動機減速,其中電動機加速/減速以10%的PWM訊號寬度佔空比為遞增/遞減量。

硬體設計

  1. 第一節的基礎上,在Proteus中新增電路如下圖所示。其中我們添加了一個直流電動機H橋晶片L298,一個直流電動機MOTOR-DC

    此外,我們還添加了一個虛擬儀表:虛擬終端VIRTUAL TERMINAL

    ,將其波特率設定為19200bits/s。

  2. 直流電動機和H橋電路:直流電動機是一種常見的動力源,很多情況下需要用直流電動機帶動執行機構做各種複雜動作。直流電動機與H橋電路如下圖所示。

    • 當開關A、D閉合時,電動機左側接通驅動電源正極,右側接通驅動電源負極,直流電動機正轉;
    • 當開關B、C閉合時,電動機左側接通驅動電源負極,右側接通驅動電源正極,直流電動機反轉;
    • 當只有開關A、C閉合或只有開關B、D閉合時,電動機左、右側短路,直流電動機能耗制動,對於某些大功率直流電動機,還需要在短路迴路中串聯制動電阻,防止能耗制動過程中電流過大。
  3. 雙H橋晶片L298
    1)簡介:L298是意法半導體公司出品的雙H橋晶片,片內整合2個獨立的H橋,可同時驅動2個最大電壓為46V、最大電流為2A的直流電動機。
    2)引腳:L298控制訊號為5VTTL電平,驅動電壓為5-46V,故在使用STM32控制時應當選用具備“FT”特性的GPIO引腳,並將引腳設為開漏輸出模式,同時外接上拉電阻到5V電源正極。控制電路由VSS供電,驅動電路由VS供電,晶片引腳和常用電路如下圖所示。

    • ENx:H橋A/B的使能引腳,高電平有效,往往與PWM訊號相連,用於調節H橋A/B控制的直流電動機轉速。
    • ISENx:H橋A/B的驅動檢測引腳,用於進行過流檢測,並將檢測結果反饋給控制器以形成閉環控制,一般不用,可直接接地。
    • IN1-IN4:方向控制訊號輸入端,其中IN1、IN2控制H橋A,其中IN3、IN4控制H橋B,具體如下表所示。
    • OUT1-OUT4:2個H橋的輸出端,用來連線2個直流電動機,其中OUT1、OUT2用來連線Motor1,OUT3、OUT4用來連線Motor2。
    • D1-D8:8個整流二極體,由於直流電動機為感性負載,為了避免L298在電動機轉換方向時受到反向電流的衝擊,加入整流二極體進行洩流。
  4. 開啟CubeMX,建立工程。這一專案有很多設定都與前面涉及的專案相似,若不熟悉可以進行回顧。

    • 首先,設定具有“FT”功能的GPIO管腳PC8PC9GPIO_Output,設定GPIO mode為開漏輸出模式Output Open DrainGPIO Pull-up/Pull-down為不需要內部上拉和下拉電阻No pull-up and no pull-down,因為已經在電路中通過外部電阻上拉到+5V。
    • 隨後,設定PWM,可參考連結PWM,配置如下圖所示。
    • 然後,設定串列埠,可參考連結串列埠通訊,配置如下圖所示。
    • 最後,設定外部中斷,並將NVIC中的中斷使能都勾選上,可參考連結EXTI,配置如下圖所示。
  5. 點選“Generator Code”生成Keil工程。

軟體編寫

點選“Open Project”在Keil中開啟工程,開啟“main.c”,新增程式碼如下。

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stdio.h"		//引入標準輸入輸出庫標頭檔案
/* USER CODE END Includes */
/* USER CODE BEGIN PV */
uint16_t cmpv = 80;		//捕獲比較值,即CRR2的設定值
uint8_t rf = 0;		//中斷標誌位
/* USER CODE END PV */
/* USER CODE BEGIN 1 */
char str[4];		//用於存放CRR2值轉換的字串
/* USER CODE END 1 */
/* USER CODE BEGIN 2 */
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2);		//定時器3執行並在通道2輸出PWM函式
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, cmpv);		//給定時器3設定通道2的捕獲比較暫存器值(CRR2)
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, GPIO_PIN_RESET);		
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9, GPIO_PIN_RESET);
/* USER CODE END 2 */
/* USER CODE BEGIN WHILE */
while (1)
{
  if(rf == 1)
  {
    HAL_UART_Transmit(&huart1, (uint8_t *)&"PWM:", 4, 4);		//串列埠傳送字串(PWM比較暫存器值,值越大轉速越快)
    sprintf(str, "%d", cmpv);
    HAL_UART_Transmit(&huart1, (uint8_t *)str, 3, 3);
    HAL_UART_Transmit(&huart1, (uint8_t *)&"\n\r", 2, 2);
    rf = 0;		//標誌位清零
  }
/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
/* USER CODE BEGIN 4 */
//外部中斷回撥函式
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  if(GPIO_Pin == GPIO_PIN_0)		//正轉按鈕
  {
    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, GPIO_PIN_SET);
    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9, GPIO_PIN_RESET);
    rf = 1;
  }
  else if(GPIO_Pin == GPIO_PIN_1)		//反轉按鈕
  {
    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, GPIO_PIN_RESET);
    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9, GPIO_PIN_SET);
    rf = 1;
  }
  else if(GPIO_Pin == GPIO_PIN_2)		//停止按鈕
  {
    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8|GPIO_PIN_9, GPIO_PIN_RESET);
  }
  else if(GPIO_Pin == GPIO_PIN_3)		//加速按鈕(增加PWM訊號波形佔空比)
  {
    if(cmpv<100) cmpv+=10;
    __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, cmpv);		//給定時器3設定通道2的捕獲比較暫存器值(CRR2)
    rf = 1;
  }
  else if(GPIO_Pin == GPIO_PIN_4)		//減速按鈕(減小PWM訊號波形佔空比)
  {
    if(cmpv>0) cmpv-=10;
    __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, cmpv);		//給定時器3設定通道2的捕獲比較暫存器值(CRR2)
    rf = 1;
  }
}
/* USER CODE END 4 */

聯合除錯

  1. 點選執行,生成HEX檔案。
  2. 在Proteus中載入相應HEX檔案,點選執行。按下不同的按鍵,可以看到電動機轉速的變化,並且在虛擬終端中可以看到PWM佔空比的設定值。