UART傳輸

前言

因這邊需要寫一個UI介面去操控STM32 進而控制sensor,因此這邊開始去了解STM32UART傳輸

但本身也不是很喜歡使用UART去控制元件,原因在於傳輸不好寫,寫不好容易有data last或造成MCU流程卡死問題

因此這邊傳輸長度是已知接收長度也是已知的狀態下去Coding UART傳輸,針對不定長度接收會放下最底下欄位供參考

設定步驟

  1. STM32CUBEMX設定UART,關鍵是要打開UART中斷,以及打開TX/RX的DMA

Enable UART IRQ

Enable UART DMA channels

PS:這邊會選擇DMA開啟的原因為避免Data lost與程式因為中斷而卡死,因如果單用IT中斷來說在中段接收時候如果程式運行太快

會導致資料lost,但DMA的缺點為你必須知道資料長度不然會無法順利執行下一步(因這邊UI與MCU撰寫都是由我編輯因此長度都是已知不會有例外)

涵式庫差異

傳輸
使用輪詢-> HAL_UART_Transmit
使用中斷—> HAL_UART_Transmit_IT
使用DMA-> HAL_UART_Transmit_DMA
接收
使用輪詢-> HAL_UART_Receive
使用中斷—> HAL_UART_Receive_IT
使用DMA-> HAL_UART_Receive_DMA
  1. 輪詢(Polling):就是阻塞式詢問,CPU都不幹別的事了,就整天在那邊問你說:「現在有沒有要傳資料啊?」沒有要傳我就繼續等,總是在那邊詢問、等待。這種方最土法煉鋼、這就是輪詢的缺點,效率太低,占用cpu時間。
  2. 中斷(Interrupt):沒有收到數據時,執行其他的程序,收到數據後,進入中斷處理通訊。與輪詢相對來說,不用循環查詢狀態暫存器,可以有更多的時間運行其他程序。
  3. DMA(Direct Memory Access):直接記憶體存取。串列數據的接收與發送由DMA處理,DMA說:「我把接收、傳送的資料放在記憶體的某個位置,你如果需要就自己去那個位置提取」。DMA也可以分為輪詢與中斷方式。資料的發送與接收都不用CPU干預,通過DMA進行。 CPU有更多的時間運行其他程序。

Coding sample

這邊照上面步驟CubeMX在宣告部分會多這3個

UART_HandleTypeDef huart2;
DMA_HandleTypeDef hdma_usart2_rx;
DMA_HandleTypeDef hdma_usart2_tx;

初始化

static void MX_DMA_Init(void);
static void MX_USART2_UART_Init(void);

這邊選用的接收為HAL_UARTEx_ReceiveToIdle_DMA(&huart2, &uRx_Data1,14),主要原因為HAL_UARTEx_ReceiveToIdle_DMA,算是裡面比較進階的函數。他會在收滿資料,或是UART IDLE一個字元以後呼叫callback

if( HAL_UARTEx_ReceiveToIdle_DMA(&huart2, &uRx_Data1,14) == HAL_OK)
	  {
		 if( uRx_Data1[0]=='a')
			 {flagstat=1;
		       i=0;}
		 else if(uRx_Data1[0]=='b')
			 {flagstat=2;
			 i=0;}
		 else if(uRx_Data1[0]=='c')
			 {flagstat=3;
			 i=0;}
		 else if(uRx_Data1[0]=='d')
		 	 {flagstat=4;
		 	 i=0;}
		 else if(uRx_Data1[0] >= '0' && uRx_Data1[0] <= '9')
			 flagstat=5;
		 else if(uRx_Data1[0]=='e')
		 	flagstat=0;


		 printf("\n\r");

	  }

這邊&uRx_Data1是宣告unsigned char uRx_Data1[14];去接收資料,因這邊傳輸近來資料為ASCII 非int 宣告成int接收部分需要在自己轉換

PS:轉換再UI端實現轉換或在STM32 MCU內都可以

這邊因為已知傳輸data格式為:x,x,xx……中間以逗號做為區隔分號為最後一碼確認結束且第一碼是分辨哪種模式

因此這邊接收到資料會先做第一碼判別,確認模式

字串連結

這邊因為使用”,”做為每個數字分隔”;”作為最後字元接收,過程中都是數字。這邊要注意因為進來的DATA為ASCII所以一定要扣除 ‘0’

去使其轉變成INT格式

這邊輸出部分因為寫入下列範例printf資料UI部分就可以接收到了因此這邊沒再額外撰寫

int _write(int file, char *ptr,int len)
{
	HAL_UART_Transmit(&huart2,(uint8_t *)ptr,len,1000);
	return len;
}

1 thought on “UART傳輸使用STM32 HAL實作TX/RX(STM32F401RE)”

  1. Pingback: LDM_Module_RPS800(TOF Measuring) - AMS and STM32

Leave a Comment

Your email address will not be published. Required fields are marked *

Shopping Cart