在我們的項目需求中,有兩個序列槽應用需求,一個是與炭氫傳感器的通訊,另一個是與顯示屏的通訊。鑒于此,我們需要實驗串行通訊。
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
如下圖紅色方框中所示:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZwpmL2EDM4IDOzADNtcDMzADN3MTMyUjM5AzNxAjMtUTOyQjN18CX5AzNxAjMvwVN5IDN2UzLcd2bsJ2Lc12bj5ycn9Gbi52YucTMwIzcldWYtl2Lc9CX6MHc0RHaiojIsJye.jpg)
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中監控到的資料收發狀态:
下圖是在序列槽助手中發送指令及接收回報的截圖:
序列槽通訊方式測試完成,完全能符合我們的要求。
如果閱讀這篇文章讓您略有所得,還請點選下方的【好文要頂】按鈕。
當然,如果您想及時了解我的部落格更新,不妨點選下方的【關注我】按鈕。
如果您希望更友善且及時的閱讀相關文章,也可以掃描上方二維碼關注我的微信公衆号【木南創智】