在移植Modbus到STM32F103(2):移植FreeModbus到usart3並運行示例代碼裏,爲了方便,沒有移植數據位和校驗位。這兩個實際上是很容易移植的。函數
先說數據位,官方宣稱STM32F103支持8位和9位數據位,但由於其把校驗位也算爲數據位,因此其實能支持的是帶校驗位的7位、8位數據位和不帶校驗位的8位、9位數據位。因此只要在串口初始化中作以下判斷便可:.net
if ( ( ucDataBits == 7 ) && ( eParity != MB_PAR_NONE ) ) { USART_InitStructure.USART_WordLength = USART_WordLength_8b; is_7databits = 1; } else if ( ( ucDataBits == 8 ) && ( eParity == MB_PAR_NONE ) ) { USART_InitStructure.USART_WordLength = USART_WordLength_8b; is_7databits = 0; } else if ( ( ucDataBits == 8 ) && ( eParity != MB_PAR_NONE ) ) { USART_InitStructure.USART_WordLength = USART_WordLength_9b; is_7databits = 0; }
這裏多了一個靜態全局變量is_7databits,由於當STM32F103的串口工做在帶校驗位的7位數據位時,DR寄存器的最高位依然會被庫函數讀出,這樣可能會形成數據錯誤。因此要把讀取串口的代碼也修改一下:code
static is_7databits = 0; BOOL xMBPortSerialGetByte( CHAR * pucByte ) { /* Return the byte in the UARTs receive buffer. This function is called * by the protocol stack after pxMBFrameCBByteReceived( ) has been called. */ char temp; temp = USART_ReceiveData(USART3); *pucByte = is_7databits ? ( temp & 0x7F ) : temp ; return TRUE; }
校驗位更簡單,只要用一個帶參數的宏便可:blog
/* ----------------------- Modbus parity to stm32 parity --------------------*/ #define usartParity(eParity) ( ( eParity == MB_PAR_NONE ) ? USART_Parity_No : ( ( eParity == MB_PAR_EVEN ) ? USART_Parity_Even : USART_Parity_Odd ) )
修改demo.c、mbascii.c和mbrtu.c,而後用Modbus Poll驗證一下,應該沒問題了。ci