FreeModbus從站設計(6)-讓串口和Modbus初始化的引數同步起來
關鍵詞:Modbus FreeModbus STM32F103C8T6 CubeMX 移植
1.基本原理
在這一篇文章中,孔丙火(微信公眾號:孔丙火)主要介紹協議堆疊初始化,以及與串口相關的代碼修改,串口的初始化函式是CubeMx自動生成的,其波特率等引數最好與freemodbus協議堆疊初始化引數保持一致,這樣方便程式的維護和功能擴展,例如,當需要修改通信的波特率的時候,只需要修改一處就可以了,不用先修改串口的初始化引數,再修改協議堆疊的引數,這是一個實戰例程與純教程的區別,
本文的總體思路:創建一些全域變數,用于存盤通信引數,串口、定時器、Freemodbus協議堆疊的初始化,都采用這些變數,需要更改的時候,只需改變這些變數的值即可,另外,這些通信引數后續計劃存盤在flash里面,定時器的引數會隨波特率的不同而改變,這些在后續的文章中會闡述,
2.代碼修改
2.1關于assert的說明
在Freemodbus的協議堆疊中,很多地方使用了assert,因此,在Cube生成工程的時候,孔丙火(微信公眾號:孔丙火)認為,最好使能enable assert選項,如果沒有使能,編譯的時候可能出錯,這個時候可以勾掉MicroLIB,因為MicroLIB不支持assert,
2.2宏的修改
(1)MB_RTU_ENABLED、MB_ASCII_ENABLED、MB_TCP_ENABLED
這里我們實作的是RTU,只需將MB_RTU_ENABLED定義為1即可,孔丙火(微信公眾號:孔丙火)順便說一句,在基于串口的Modbus中,RTU是必選項,ASCII是可選項,也就是說RTU是必須要實作的,
(2)ENTER_CRITICAL_SECTION( )和EXIT_CRITICAL_SECTION( )
這兩個函式是進入和退出關鍵行程,這里定義為__disable_irq()和__enable_irq(),后邊兩個函式是ARM內核函式,作用是禁止中斷和使能中斷,
#define ENTER_CRITICAL_SECTION( ) __disable_irq()
#define EXIT_CRITICAL_SECTION( ) __enable_irq()
2.3協議堆疊初始化
在main.c檔案中的while(1)之前,呼叫eMBInit( )完成協議堆疊的初始化,然后呼叫eMBEnable( )使能協議堆疊,eMBInit( )的定義如下:eMBErrorCode
eMBInit( eMBMode eMode, UCHAR ucSlaveAddress, UCHAR ucPort, ULONG ulBaudRate, eMBParity eParity ),共5個引數,eMode模式:RTU或ASCII,ucSlaveAddress從站地址,ucPort單片機的串口號,ulBaudRate波特率,eParity校驗方式,我們這里串口引數是在Cube生產的函式里初始化的,而且串口接識訓發送的資料HAL庫函式已經處理好了,因此,孔丙火(微信公眾號:孔丙火)認為,有用的引數只有eMode,ucSlaveAddress,ulBaudRate,其余兩個設錯了,其實也沒影響(僅限于本文的實作方法),
在modbus_app.c中定義如下全域變數:
uint8_t ucUsrSlaveAddress;//從站地址
uint32_t ulUsrBaudRate;//波特率
eMBParity eUsrParity;//校驗方式
uint8_t ucUsrStopBits;//停止位
新建modbus_app.h,在其中進行extern定義,一般在其他c檔案中使用,
最終,在main.c中做如下呼叫:
eMBInit( MB_RTU, ucUsrSlaveAddress, 1, ulUsrBaudRate, eUsrParity );
2.4串口引數初始化
在MX_USART2_UART_Init()中修改,此函式是Cube自動生成的,在usart.c中,
最終函式如下:
huart2.Instance = USART2;
huart2.Init.BaudRate = ulUsrBaudRate;
if(eUsrParity == MB_PAR_NONE)huart2.Init.WordLength = UART_WORDLENGTH_8B;
else huart2.Init.WordLength = UART_WORDLENGTH_9B;
if(ucUsrStopBits == 1)huart2.Init.StopBits = UART_STOPBITS_1;
else if(ucUsrStopBits == 2)huart2.Init.StopBits = UART_STOPBITS_2;
if(eUsrParity == MB_PAR_NONE)huart2.Init.Parity = UART_PARITY_NONE;
else if(eUsrParity == MB_PAR_EVEN)huart2.Init.Parity = UART_PARITY_EVEN;
else if(eUsrParity == MB_PAR_ODD)huart2.Init.Parity = UART_PARITY_ODD;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart2) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
波特率使用了全域變數,單片機的資料位個數和停止位根據全域變數確定,
3.總結
這種方法讓讓串口和Modbus初始化的引數同步起來了,也方便通信引數的在線修改,更接近實戰,
文章在公眾號(孔丙火)同步推出,歡迎查看更多系列文章.
單片機、ARM、現場總線、PLC、嵌入式軟硬體的設計經驗分享,秉承“點點滴滴皆智慧”的理念,以實際專案為單元闡述知識點,一起分享,共同交流單片機、ARM、現場總線、PLC、嵌入式軟硬體的設計經驗分享,秉承“點點滴滴皆智慧”的理念,以實際專案為單元闡述知識點,一起分享,共同交流,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/278388.html
標籤:其他
上一篇:初識HTML02
下一篇:CPU 空閑時在干嘛?
