在我們的項目需求中,有兩個串口應用需求,一個是與炭氫傳感器的通訊,另一個是與顯示屏的通訊。鑒於此,我們需要實驗串行通訊。
1、硬件設計
串行通訊一個采用RS232接口,另一個直接采用TTL方式。我們在STM32L476RG開發板中,發現USART1和USART3的輸入輸出端口已經引出來,所以我們使用這兩個串口。
USART1_TX PA9 CN5-1
USART1_RX PA10 CN9-3
USART3_TX PC4 CN10-34
USART3_RX PC5 CN10-6
如下圖紅色方框中所示:
對於RS232接口我們采用了周立功RSM232模塊來做實驗,其推薦的連接方式如下圖:
在實驗過程中我們不需要這些保護措施,根據以上的分析我們可以對串口通訊做如下設計。RS232接口原理圖如下:
對於單總線TTL通訊,我們采用如下原理圖來實現:
2、軟件設計
完成硬件連接后我們可以開始軟件開發了,首先我們在STM32CubeMX中對硬件部分進行配置。其中USART1和USART3的配置如下圖所示:
而后對串口部分做參數配置,波特率等按要求配置好,很簡單在此不多說了。接下來編寫測試代碼。
static void Test_UART_Configuration(void) { huart1.Instance = USART1; huart1.Init.BaudRate = 115200; huart1.Init.WordLength = UART_WORDLENGTH_8B; huart1.Init.StopBits = UART_STOPBITS_1; huart1.Init.Parity = UART_PARITY_NONE; huart1.Init.Mode = UART_MODE_TX_RX; huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart1.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart1) != HAL_OK) { Error_Handler(); }
定義一個簡單的類Modbus通訊協議,采用中斷方式來實現數據接收。中斷處理函數如下:
void USART1_ReceiveDataHandle(void) { if(ozonatorRxLength>=RETURNING_DATA_LENGTH) { ozonatorRxLength=0; } /*接收寄存器為空,等待字節被對應的串口完全接收*/ if(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_RXNE)!=RESET) { uint8_t rData; /*獲取接收到的字節*/ HAL_UART_Receive(&huart1,&rData,1,1000); TestRxBuffer[ozonatorRxLength++] = rData; } }
對接收到的信息進行解析,並根據請求命令完成放回信息的編碼並回傳。
/*解析接收到的信息,並返回合成的回復信息和信息的字節長度,通過回調函數*/ uint16_t ParsingMasterAccessCommand(uint8_t *receivedMessage,uint8_t *respondBytes,uint16_t rxLength) { uint16_t respondLength=0; /*判斷是否是本站,如不是不處理*/ uint8_t slaveAddress=*receivedMessage; if(slaveAddress!=StationAddress) { return 0; } /*判斷功能碼是否有誤*/ FunctionCode fc=(FunctionCode)(*(receivedMessage+1)); if(CheckFunctionCode(fc)!=MB_OK) { return 0; } /*信息校驗,如不正確則為錯誤信息不用處理*/ uint16_t dataLength=8; if((fc==WriteMultipleCoil)||(fc==WriteMultipleRegister)) { dataLength=(uint16_t)(*(receivedMessage+6))+9; if(rxLength<dataLength)//尚未接收完整 { return 65535; } } bool chechMessageNoError=CheckRTUMessageIntegrity(receivedMessage,dataLength); if(!chechMessageNoError) { return 0; } uint16_t startAddress=(uint16_t)(*(receivedMessage+2)); startAddress=(startAddress<<8)+(uint16_t)(*(receivedMessage+3)); uint16_t quantity=(uint16_t)(*(receivedMessage+4)); quantity=(quantity<<8)+(uint16_t)(*(receivedMessage+5)); uint8_t index=(fc>0x08)?(fc-0x09):(fc-0x01); respondLength=HandleMasterCommand[index](startAddress,quantity,receivedMessage,respondBytes); return respondLength; }
3、測試結果
通過USB轉RS232接口的模塊接入電腦通過AccessPort和串口出手來對通訊進行測試。下圖是在AccessPort中監控到的數據收發狀態:
下圖是在串口助手中發送命令及接收反饋的截圖:
串口通訊方式測試完成,完全能符合我們的要求。