FreeModbus移植到STM32F103(串行传输方式)
1.創(chuàng)建工程
?
2.將FreeModbus源碼,拷貝到工程目錄
?
3.將FreeModbus文件添加進(jìn)工程
添加好之后,編譯出現(xiàn)錯(cuò)誤
?
4.移植底層接口
先看第一個(gè)錯(cuò)誤,缺少port.h
借鑒AVR架構(gòu)的程序,將demo里面AVR中的port文件夾,拷貝到工程中
進(jìn)入port文件夾,刪除重復(fù)文件,mbcrc.c
添加好之后,重新編譯,出現(xiàn)錯(cuò)誤,port.h中包含了很多iar相關(guān)代碼
將這些代碼刪除或修改
重新編譯,錯(cuò)誤少了很多,剩下的錯(cuò)誤是,portserial和porttimer中包含avr相關(guān)代碼
將portserial和porttimer中,串口和定時(shí)器的驅(qū)動(dòng),改成STM32架構(gòu)的代碼
#include "port.h"/* ----------------------- Modbus includes ----------------------------------*/ #include "mb.h" #include "mbport.h"/* GPIO配置 */ static void gpio_config(void) {GPIO_InitTypeDef GPIO_InitStructure;/* 使能GPIOA時(shí)鐘 */RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);/* 設(shè)置PA2為復(fù)用推挽輸出 */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); /* 設(shè)置PA3為浮空輸入 */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); }/* 中斷配置 */ static void nvic_config(void) {NVIC_InitTypeDef NVIC_InitStructure;/* 設(shè)置串口1中斷的先占優(yōu)先級(jí)為2,從占優(yōu)先級(jí)為2 */NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure); }/* 串口配置 */ static void usart_config(uint32_t baudRate, uint16_t wordLength, uint16_t parity) {USART_InitTypeDef USART_InitStruct; /* 使能GPIOA時(shí)鐘和串口時(shí)鐘 */RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);/* 設(shè)置串口波特率115200、數(shù)據(jù)位8bit、停止位1bit、校驗(yàn)位無(wú)、無(wú)硬件流、接收發(fā)送 */if(wordLength == 9)USART_InitStruct.USART_WordLength = USART_WordLength_9b;elseUSART_InitStruct.USART_WordLength = USART_WordLength_8b;if(MB_PAR_NONE != parity)USART_InitStruct.USART_StopBits = USART_StopBits_1;elseUSART_InitStruct.USART_StopBits = USART_StopBits_2;if(MB_PAR_NONE == parity)USART_InitStruct.USART_Parity = USART_Parity_No;else if(MB_PAR_EVEN == parity)USART_InitStruct.USART_Parity = USART_Parity_Even;elseUSART_InitStruct.USART_Parity = USART_Parity_Odd;USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;USART_Init(USART1, &USART_InitStruct); }void vMBPortSerialEnable(BOOL xRxEnable, BOOL xTxEnable) {if(xRxEnable == FALSE && xTxEnable == FALSE)USART_Cmd(USART1, DISABLE);elseUSART_Cmd(USART1, ENABLE);if(xRxEnable == TRUE){USART_ClearITPendingBit(USART1, USART_IT_RXNE);USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);}elseUSART_ITConfig(USART1, USART_IT_RXNE, DISABLE);if(xTxEnable == TRUE){USART_ClearITPendingBit(USART1, USART_IT_TC);USART_ITConfig(USART1, USART_IT_TC, ENABLE);pxMBFrameCBTransmitterEmpty();}elseUSART_ITConfig(USART1, USART_IT_TC, DISABLE); }BOOL xMBPortSerialInit(UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits, eMBParity eParity) {(void)ucPORT;/* 串口配置 */usart_config(ulBaudRate, ucDataBits, eParity); /* GPIO配置 */gpio_config();/* 中斷配置 */nvic_config();vMBPortSerialEnable(FALSE, FALSE);return TRUE; }BOOL xMBPortSerialPutByte(CHAR ucByte) { USART_SendData(USART1, ucByte);return TRUE; }BOOL xMBPortSerialGetByte(CHAR *pucByte) {*pucByte = USART_ReceiveData(USART1);return TRUE; }void USART1_IRQHandler(void) { if(USART_GetITStatus(USART1, USART_IT_ORE) != RESET){ USART_ClearITPendingBit(USART1, USART_IT_ORE);pxMBFrameCBByteReceived();} if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET){ USART_ClearITPendingBit(USART1, USART_IT_RXNE);pxMBFrameCBByteReceived();} if(USART_GetITStatus(USART1, USART_IT_TC) != RESET){ USART_ClearITPendingBit(USART1, USART_IT_TC);pxMBFrameCBTransmitterEmpty();} } /* ----------------------- Platform includes --------------------------------*/ #include "port.h"/* ----------------------- Modbus includes ----------------------------------*/ #include "mb.h" #include "mbport.h"/* 功能: 定時(shí)器配置參數(shù): period 自動(dòng)重載值返回值: 無(wú) */ static void timer_config(uint16_t period) {TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;/* 允許TIM3的時(shí)鐘 */RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);/* 將定時(shí)器3寄存器設(shè)為初始值 */TIM_DeInit(TIM3);/* 設(shè)置定時(shí)器3由內(nèi)部時(shí)鐘 */TIM_InternalClockConfig(TIM3);/* 預(yù)分頻值 */TIM_TimeBaseStructure.TIM_Prescaler = 3600 - 1;/* 時(shí)鐘分割 */TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;/* 向上計(jì)數(shù) */TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;/* 自動(dòng)重載值 */TIM_TimeBaseStructure.TIM_Period = period - 1;/* 初始化定時(shí)器3 */TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);/* 清除溢出中斷標(biāo)志 */TIM_ClearFlag(TIM3, TIM_FLAG_Update);/* 禁止ARR預(yù)裝載緩沖器 */TIM_ARRPreloadConfig(TIM3, DISABLE); }/* 功能: 中斷配置參數(shù): 無(wú)返回值: 無(wú) */ static void nvic_config(void) {NVIC_InitTypeDef NVIC_InitStructure;/* 選擇TIM3的中斷通道 */NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;/* 搶占式中斷優(yōu)先級(jí)設(shè)置為2 */NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;/* 響應(yīng)式中斷優(yōu)先級(jí)設(shè)置為2 */NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;/* 使能中斷 */NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;/* 中斷初始化 */NVIC_Init(&NVIC_InitStructure); }BOOL xMBPortTimersInit(USHORT usTim1Timerout50us) {/* 設(shè)置定時(shí)器定時(shí)時(shí)間 */timer_config(usTim1Timerout50us);/* 中斷配置 */nvic_config();return TRUE; }void vMBPortTimersEnable(void) {/* 清空定時(shí)器3計(jì)數(shù)器 */TIM_SetCounter(TIM3, 0);/* 使能定時(shí)器3 */TIM_Cmd(TIM3, ENABLE);/* 使能TIM3的中斷 */TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE); }void vMBPortTimersDisable(void) {/* 禁止定時(shí)器3 */TIM_Cmd(TIM3, DISABLE);/* 關(guān)閉TIM3的中斷 */TIM_ITConfig(TIM3, TIM_IT_Update, DISABLE); }/* 定時(shí)器3中斷向量 */ void TIM3_IRQHandler(void) {/* 定時(shí)器3溢出標(biāo)志位 */if(TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET){/* 定時(shí)器3清除溢出標(biāo)志位 */TIM_ClearITPendingBit(TIM3 , TIM_FLAG_Update);/* 關(guān)閉TIM3的中斷 */TIM_ITConfig(TIM3, TIM_IT_Update, DISABLE);/* 關(guān)閉定時(shí)器3 */TIM_Cmd(TIM3, DISABLE);(void)pxMBPortCBTimerExpired();} }重新編譯,驅(qū)動(dòng)相關(guān)的錯(cuò)誤,已經(jīng)不存在。
報(bào)告eMBRegCoilsCB、eMBRegDiscreteCB、eMBRegHoldingCB和eMBRegInputCB沒(méi)有定義。
這四個(gè)接口是協(xié)議棧預(yù)留給用戶自己去實(shí)現(xiàn)的,分別創(chuàng)建user_mb_app.h和user_mb_app.c兩個(gè)文件
#ifndef _USER_MB_APP_H_ #define _USER_MB_APP_H_/* ----------------------- Modbus includes ----------------------------------*/ #include "mb.h" #include "mbconfig.h" #include "mbframe.h" #include "mbutils.h"/* -----------------------Slave Defines -------------------------------------*/ #define S_DISCRETE_INPUT_START 0 #define S_DISCRETE_INPUT_NDISCRETES 16 #define S_COIL_START 0 #define S_COIL_NCOILS 64 #define S_REG_INPUT_START 0 #define S_REG_INPUT_NREGS 100 #define S_REG_HOLDING_START 0 #define S_REG_HOLDING_NREGS 100 /* salve mode: holding register's all address */ #define S_HD_RESERVE 0 #define S_HD_CPU_USAGE_MAJOR 1 #define S_HD_CPU_USAGE_MINOR 2 /* salve mode: input register's all address */ #define S_IN_RESERVE 0 /* salve mode: coil's all address */ #define S_CO_RESERVE 0 /* salve mode: discrete's all address */ #define S_DI_RESERVE 0/* -----------------------Master Defines -------------------------------------*/ #define M_DISCRETE_INPUT_START 0 #define M_DISCRETE_INPUT_NDISCRETES 16 #define M_COIL_START 0 #define M_COIL_NCOILS 64 #define M_REG_INPUT_START 0 #define M_REG_INPUT_NREGS 100 #define M_REG_HOLDING_START 0 #define M_REG_HOLDING_NREGS 100 /* master mode: holding register's all address */ #define M_HD_RESERVE 0 /* master mode: input register's all address */ #define M_IN_RESERVE 0 /* master mode: coil's all address */ #define M_CO_RESERVE 0 /* master mode: discrete's all address */ #define M_DI_RESERVE 0#endif /** FreeModbus Libary: user callback functions and buffer define in slave mode* Copyright (C) 2013 Armink <armink.ztl@gmail.com>** This library is free software; you can redistribute it and/or* modify it under the terms of the GNU Lesser General Public* License as published by the Free Software Foundation; either* version 2.1 of the License, or (at your option) any later version.** This library is distributed in the hope that it will be useful,* but WITHOUT ANY WARRANTY; without even the implied warranty of* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU* Lesser General Public License for more details.** You should have received a copy of the GNU Lesser General Public* License along with this library; if not, write to the Free Software* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA** File: $Id: user_mb_app.c,v 1.60 2013/11/23 11:49:05 Armink $*/ #include "user_mb_app.h"/*------------------------Slave mode use these variables----------------------*/ //Slave mode:DiscreteInputs variables USHORT usSDiscInStart = S_DISCRETE_INPUT_START; #if S_DISCRETE_INPUT_NDISCRETES%8 UCHAR ucSDiscInBuf[S_DISCRETE_INPUT_NDISCRETES/8+1]; #else UCHAR ucSDiscInBuf[S_DISCRETE_INPUT_NDISCRETES/8] ; #endif //Slave mode:Coils variables USHORT usSCoilStart = S_COIL_START; #if S_COIL_NCOILS%8 UCHAR ucSCoilBuf[S_COIL_NCOILS/8+1] ; #else UCHAR ucSCoilBuf[S_COIL_NCOILS/8] ; #endif //Slave mode:InputRegister variables USHORT usSRegInStart = S_REG_INPUT_START; USHORT usSRegInBuf[S_REG_INPUT_NREGS] ; //Slave mode:HoldingRegister variables USHORT usSRegHoldStart = S_REG_HOLDING_START; USHORT usSRegHoldBuf[S_REG_HOLDING_NREGS] ;/*** Modbus slave input register callback function.** @param pucRegBuffer input register buffer* @param usAddress input register address* @param usNRegs input register number** @return result*/ eMBErrorCode eMBRegInputCB(UCHAR *pucRegBuffer, USHORT usAddress, USHORT usNRegs) {eMBErrorCode eStatus = MB_ENOERR;USHORT iRegIndex;USHORT * pusRegInputBuf;USHORT REG_INPUT_START;USHORT REG_INPUT_NREGS;USHORT usRegInStart;pusRegInputBuf = usSRegInBuf;REG_INPUT_START = S_REG_INPUT_START;REG_INPUT_NREGS = S_REG_INPUT_NREGS;usRegInStart = usSRegInStart;/* it already plus one in modbus function method. */usAddress--;if ((usAddress >= REG_INPUT_START)&& (usAddress + usNRegs <= REG_INPUT_START + REG_INPUT_NREGS)){iRegIndex = usAddress - usRegInStart;while (usNRegs > 0){*pucRegBuffer++ = (UCHAR) (pusRegInputBuf[iRegIndex] >> 8);*pucRegBuffer++ = (UCHAR) (pusRegInputBuf[iRegIndex] & 0xFF);iRegIndex++;usNRegs--;}}else{eStatus = MB_ENOREG;}return eStatus; }/*** Modbus slave holding register callback function.** @param pucRegBuffer holding register buffer* @param usAddress holding register address* @param usNRegs holding register number* @param eMode read or write** @return result*/ eMBErrorCode eMBRegHoldingCB(UCHAR *pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegisterMode eMode) {eMBErrorCode eStatus = MB_ENOERR;USHORT iRegIndex;USHORT * pusRegHoldingBuf;USHORT REG_HOLDING_START;USHORT REG_HOLDING_NREGS;USHORT usRegHoldStart;pusRegHoldingBuf = usSRegHoldBuf;REG_HOLDING_START = S_REG_HOLDING_START;REG_HOLDING_NREGS = S_REG_HOLDING_NREGS;usRegHoldStart = usSRegHoldStart;/* it already plus one in modbus function method. */usAddress--;if ((usAddress >= REG_HOLDING_START)&& (usAddress + usNRegs <= REG_HOLDING_START + REG_HOLDING_NREGS)){iRegIndex = usAddress - usRegHoldStart;switch (eMode){/* read current register values from the protocol stack. */case MB_REG_READ:while (usNRegs > 0){*pucRegBuffer++ = (UCHAR) (pusRegHoldingBuf[iRegIndex] >> 8);*pucRegBuffer++ = (UCHAR) (pusRegHoldingBuf[iRegIndex] & 0xFF);iRegIndex++;usNRegs--;}break;/* write current register values with new values from the protocol stack. */case MB_REG_WRITE:while (usNRegs > 0){pusRegHoldingBuf[iRegIndex] = *pucRegBuffer++ << 8;pusRegHoldingBuf[iRegIndex] |= *pucRegBuffer++;iRegIndex++;usNRegs--;}break;}}else{eStatus = MB_ENOREG;}return eStatus; }/*** Modbus slave coils callback function.** @param pucRegBuffer coils buffer* @param usAddress coils address* @param usNCoils coils number* @param eMode read or write** @return result*/ eMBErrorCode eMBRegCoilsCB(UCHAR *pucRegBuffer, USHORT usAddress, USHORT usNCoils, eMBRegisterMode eMode) {eMBErrorCode eStatus = MB_ENOERR;USHORT iRegIndex , iRegBitIndex , iNReg;UCHAR * pucCoilBuf;USHORT COIL_START;USHORT COIL_NCOILS;USHORT usCoilStart;iNReg = usNCoils / 8 + 1;pucCoilBuf = ucSCoilBuf;COIL_START = S_COIL_START;COIL_NCOILS = S_COIL_NCOILS;usCoilStart = usSCoilStart;/* it already plus one in modbus function method. */usAddress--;if( ( usAddress >= COIL_START ) &&( usAddress + usNCoils <= COIL_START + COIL_NCOILS ) ){iRegIndex = (USHORT) (usAddress - usCoilStart) / 8;iRegBitIndex = (USHORT) (usAddress - usCoilStart) % 8;switch ( eMode ){/* read current coil values from the protocol stack. */case MB_REG_READ:while (iNReg > 0){*pucRegBuffer++ = xMBUtilGetBits(&pucCoilBuf[iRegIndex++],iRegBitIndex, 8);iNReg--;}pucRegBuffer--;/* last coils */usNCoils = usNCoils % 8;/* filling zero to high bit */*pucRegBuffer = *pucRegBuffer << (8 - usNCoils);*pucRegBuffer = *pucRegBuffer >> (8 - usNCoils);break;/* write current coil values with new values from the protocol stack. */case MB_REG_WRITE:while (iNReg > 1){xMBUtilSetBits(&pucCoilBuf[iRegIndex++], iRegBitIndex, 8,*pucRegBuffer++);iNReg--;}/* last coils */usNCoils = usNCoils % 8;/* xMBUtilSetBits has bug when ucNBits is zero */if (usNCoils != 0){xMBUtilSetBits(&pucCoilBuf[iRegIndex++], iRegBitIndex, usNCoils,*pucRegBuffer++);}break;}}else{eStatus = MB_ENOREG;}return eStatus; }/*** Modbus slave discrete callback function.** @param pucRegBuffer discrete buffer* @param usAddress discrete address* @param usNDiscrete discrete number** @return result*/ eMBErrorCode eMBRegDiscreteCB(UCHAR *pucRegBuffer, USHORT usAddress, USHORT usNDiscrete) {eMBErrorCode eStatus = MB_ENOERR;USHORT iRegIndex , iRegBitIndex , iNReg;UCHAR * pucDiscreteInputBuf;USHORT DISCRETE_INPUT_START;USHORT DISCRETE_INPUT_NDISCRETES;USHORT usDiscreteInputStart;iNReg = usNDiscrete / 8 + 1;pucDiscreteInputBuf = ucSDiscInBuf;DISCRETE_INPUT_START = S_DISCRETE_INPUT_START;DISCRETE_INPUT_NDISCRETES = S_DISCRETE_INPUT_NDISCRETES;usDiscreteInputStart = usSDiscInStart;/* it already plus one in modbus function method. */usAddress--;if ((usAddress >= DISCRETE_INPUT_START)&& (usAddress + usNDiscrete <= DISCRETE_INPUT_START + DISCRETE_INPUT_NDISCRETES)){iRegIndex = (USHORT) (usAddress - usDiscreteInputStart) / 8;iRegBitIndex = (USHORT) (usAddress - usDiscreteInputStart) % 8;while (iNReg > 0){*pucRegBuffer++ = xMBUtilGetBits(&pucDiscreteInputBuf[iRegIndex++],iRegBitIndex, 8);iNReg--;}pucRegBuffer--;/* last discrete */usNDiscrete = usNDiscrete % 8;/* filling zero to high bit */*pucRegBuffer = *pucRegBuffer << (8 - usNDiscrete);*pucRegBuffer = *pucRegBuffer >> (8 - usNDiscrete);}else{eStatus = MB_ENOREG;}return eStatus; }重新編譯,0錯(cuò)誤,0警告
?
5.添加接口
分別創(chuàng)建rcc.h、rcc.c、nvic.h、nvic.c文件
/************************************** 文件名:rcc.h* 作者: stone* 版本: V0.1* 日期: 2018-3-29* 描述: 配置時(shí)鐘源************************************/ #ifndef __RCC_H_ #define __RCC_H_/* 功能: RCC時(shí)鐘配置參數(shù): 無(wú)返回值:無(wú)*/ void rcc_config(void);#endif /************************************** 文件名: rcc.c* 作者: stone* 版本: V0.1* 日期: 2018-3-29* 描述: 配置時(shí)鐘源************************************/ #include "stm32f10x.h" #include "stm32f10x_flash.h" #include "rcc.h"/* 功能: RCC時(shí)鐘配置參數(shù): 無(wú)返回值:無(wú)*/ void rcc_config(void) { ErrorStatus HSEStartUpStatus;/* RCC寄存器設(shè)置為默認(rèn)配置 */RCC_DeInit();/* 打開(kāi)外部高速時(shí)鐘 */RCC_HSEConfig(RCC_HSE_ON);/* 等待外部高速時(shí)鐘穩(wěn)定 */HSEStartUpStatus = RCC_WaitForHSEStartUp();if(HSEStartUpStatus == SUCCESS) { /* 設(shè)置HCLK = SYSCLK */RCC_HCLKConfig(RCC_SYSCLK_Div1);/* 設(shè)置PCLK2 = HCLK */RCC_PCLK2Config(RCC_HCLK_Div1);/* 設(shè)置PCLK1 = HCLK / 2 */RCC_PCLK1Config(RCC_HCLK_Div2);/* 設(shè)置FLASH代碼延時(shí) */FLASH_SetLatency(FLASH_Latency_2);/* 使能預(yù)取址緩存 */FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);/* 設(shè)置PLL時(shí)鐘源為HSE倍頻9 72MHz */RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);/* 使能PLL */RCC_PLLCmd(ENABLE);/* 等待PLL穩(wěn)定 */while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);/* 設(shè)置PLL為系統(tǒng)時(shí)鐘源 */RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);/* 等待系統(tǒng)時(shí)鐘源切換到PLL */while(RCC_GetSYSCLKSource() != 0x08);} } /************************************** 文件名: nvic.h* 作者: stone* 版本: V0.1* 日期: 2018-3-29* 描述: 設(shè)置中斷控制器************************************/ #ifndef __NVIC_H_ #define __NVIC_H_/* 功能: 中斷嵌套控制器配置參數(shù): 無(wú)返回值:無(wú)*/ void nvic_config(void);#endif /************************************** 文件名: nvic.c* 作者: stone* 版本: V0.1* 日期: 2018-3-29* 描述: 設(shè)置中斷控制器************************************/ #include "stm32f10x.h" #include "nvic.h"/* 功能: 中斷嵌套控制器配置參數(shù): 無(wú)返回值:無(wú)*/ void nvic_config(void) {/* 選擇中斷分組2 */NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); }?
8.協(xié)議棧移植工作完成。
#include "stm32f10x.h" #include "rcc.h" #include "nvic.h" #include "mb.h"int main(void) {/* RCC時(shí)鐘配置 */rcc_config();/* 中斷嵌套控制器配置 */nvic_config();/* 設(shè)置從節(jié)點(diǎn)ID */eMBSetSlaveID(1, TRUE, 0, 0);/* 初始化Modbus */eMBInit(MB_RTU, 1, 1, 115200, MB_PAR_NONE);/* 使能Modbus */eMBEnable();/* 主循環(huán) */while(1){/* 輪詢Modbus */eMBPoll();} }?
總結(jié)
以上是生活随笔為你收集整理的FreeModbus移植到STM32F103(串行传输方式)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 电路定理
- 下一篇: 17年数据分析经验告诉你大数据行业的门道