收藏 分销(赏)

modbus移植说明.docx

上传人:pc****0 文档编号:6707729 上传时间:2024-12-20 格式:DOCX 页数:7 大小:30.39KB 下载积分:10 金币
下载 相关 举报
modbus移植说明.docx_第1页
第1页 / 共7页
modbus移植说明.docx_第2页
第2页 / 共7页


点击查看更多>>
资源描述
Modbus向MSP430F149上的移植步骤 FreeModbus 的MSP430 版本的demo 是在GCC 平台,现移植到IAR 上,版本5.3。 先说几点在GCC平台移植到IAR平台要改的几处地方 1.先按照如图所示在IAR中建立好工程文件以及工程目录 2.在system文件夹下建立DCO.C文件配置系统时钟,由于一般使用430单片机的外部8M晶振,因此此处我们自己写的函数只要和作者的留的接口对上即可。DCO.C文件代码如下: #include "../port/port.h" #include "dco.h" /* ----------------------- Start implementation -----------------------------*/ char cTISetDCO( int delta ) { char z,result; /*------选择主系统时钟为8MHZ -------*/ BCSCTL1 &= ~XT2OFF; //打开XT2高频振荡器 do { IFG1 &= ~OFIFG; //清除振荡器失效标志 for (z = 0xFF; z > 0; z--); //等待8MHZ晶振起振 } while ((IFG1 & OFIFG)); //判断晶振失效标志是否依然存在 BCSCTL2 |= SELM_2 + SELS; //MCLK和SMCLK选择高频振荡器 result = TI_DCO_NO_ERROR; return(result); }。前面说的与作者的留的接口对接,也就是返回值为char类型的TI_DCO_NO_ERROR即可。 3. 官方demo 使用的MCU 为MSP430F169,我用的开发板是F149 因此要更改相应的库函 数。 文件port.h. 更改为: /* ----------------------- Platform includes --------------------------------*/ #include <msp430x14x.h> #if defined (__GNUC__) #include <signal.h> #endif #undef CHAR Portserial.c 中usOldSR = _DINT( )程序,_DINT()是没有返回值的所以编译会报错, 将该部分程序更改为这样 文件:Portserial.c---EnterCriticalSection( void ) 更改为: void EnterCriticalSection( void ) { USHORT usOldSR; if( ucCriticalNesting == 0 ) { #if defined (__GNUC__) usOldSR = READ_SR; _DINT( ); #else // usOldSR = _DINT( ); #endif // ucGIEWasEnabled = usOldSR & GIE ? TRUE : FALSE; _DINT( ); ucGIEWasEnabled = TRUE; } ucCriticalNesting++; } 文件:Portserial.c--- ExitCriticalSection( void ) 更改为: void ExitCriticalSection( void ) { ucCriticalNesting--; if( ucCriticalNesting == 0 ) { if( ucGIEWasEnabled ) { ucGIEWasEnabled = FALSE; _EINT( ); } } } 更改中断服务函数,原程序的中断服务函数格式不能在IAR 中使用,因此要更改为IAR 格式 文件:portserial.c---prvvMBSerialRXIRQHandler( void ) 更改为: #pragma vector = USART0RX_VECTOR __interrupt void prvvMBSerialRXIRQHandler( void ) //__interrupt[USART0RX_VECTOR] { DEBUG_TOGGLE_RX( ); pxMBFrameCBByteReceived( ); } 文件:portserial.c--- prvvMBSerialTXIRQHandler ( void ) 更改为: #pragma vector = USART0TX_VECTOR __interrupt void prvvMBSerialTXIRQHandler( void ) // __interrupt[USART0TX_VECTOR] { DEBUG_TOGGLE_TX( ); pxMBFrameCBTransmitterEmpty( ); } 文件:porttimer.c--- prvvMBTimerIRQHandler ( void ) 更改为: #pragma vector = TIMERA0_VECTOR __interrupt void prvvMBTimerIRQHandler( void ) { ( void )pxMBPortCBTimerExpired( ); } main.c 中有4 个配置宏,REG_INPUT_START 定义输入寄存器的开始地址,这里我配置 成0;REG_INPUT_NREGS 定义输入寄存器的数目,我配置为4 个;REG_HOLDING_START 定 义保持寄存器的开始地址,这里我配置为0;REG_HOLDING_NREGS 定义保持寄存器的个数, 这里我定义为125。 文件:main.c 更改为:文件:main.c 更改为: /* ----------------------- Defines ------------------------------------------*/ #define REG_INPUT_START 0 #define REG_INPUT_NREGS 4 #define REG_HOLDING_START 0 #define REG_HOLDING_NREGS 125 这里配置modbus 支持的工作模式,有RTU、ASCII、TCP 三种模式。0 表示失能,1 表 示使能。这里我只开启RTU 模式,当然了你也可以选择都开启。 文件:mbconfig.h 更改为: /*! \brief If Modbus ASCII support is enabled. */ #define MB_ASCII_ENABLED ( 0 ) /*! \brief If Modbus RTU support is enabled. */ #define MB_RTU_ENABLED ( 1 ) /*! \brief If Modbus TCP support is enabled. */ #define MB_TCP_ENABLED ( 0 ) 到这一步新建的工程可以编译成功,接下来将测试功能是否正常,在测试之前先对 modbus 模块参数进行配置。 在main.c文件中我们如下配置: int main( void ) { eMBErrorCode eStatus; volatile USHORT usACLKCnt; /* Stop Watchdog Timer. */ WDTCTL = WDTPW + WDTHOLD; /* Delay for ACLK startup. */ for( usACLKCnt = 0xFFFF; usACLKCnt != 0; usACLKCnt-- ); if( cTISetDCO( TI_DCO_4MHZ ) == TI_DCO_NO_ERROR ) { _EINT( ); /* Initialize Protocol Stack. */ eStatus = eMBInit( MB_RTU, 0x01, 0, 9600, MB_PAR_EVEN ); if( (eStatus ) != MB_ENOERR ) { } /* Enable the Modbus Protocol Stack. */ else if( ( eStatus = eMBEnable( ) ) != MB_ENOERR ) { } else { for( ;; ) { ( void )eMBPoll( ); /* Here we simply count the number of poll cycles. */ usRegInputBuf[0]++; } } } for( ;; ); } 这里是对modbus 的串口参数以及地址的配置,这里我配置为MB_RTU, 0x01, 0, 9600, MB_PAR_EVEN,这时modbus 工作在RTU 模式,节点地址为01,使用的串行端口为0 也就 是USART0,波特率9600,偶校验。 4.还有一步很要的要修改的地方,那就是 文件:port.h 更改为: #define SMCLK ( 8000000UL ) #define ACLK ( 32768UL ) 这里定义系统时钟频率,我的开发板使用外部8MHz 晶振,在dco-IAR.c 中的cTISetDCO 函数中我将MCU 初始化为8MHz,因此SMCLK = 8000000 ,这个参数非常重要因为串口波 特率和以及定时器的计算均参考SMCLK 的设置。 5.到此处我们测试读写寄存器都可以通过了,但惟独测试读写线圈移植显示illegal data address,,,这个地方经过返回查找实际上是由于FREE MODBUS的作者有两个回调函数并没有写实际的内容,只是单纯的返回了出错标志,我们要达到完美的移植modbus到430f149上面去,我们就必须自己重写这两个函数,此处给出了自己写的程序。 eMBErrorCode eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils, eMBRegisterMode eMode ) { eMBErrorCode eStatus = MB_ENOERR; int iNCoils = ( int )usNCoils; int usBitOffset; if( ( (int)usAddress >= REG_COILS_START ) && ( usAddress + usNCoils <= REG_COILS_START + REG_COILS_SIZE ) ) { usBitOffset = ( int )( usAddress - REG_COILS_START ); switch ( eMode ) { case MB_REG_READ: while( iNCoils > 0 ) { *pucRegBuffer++ = xMBUtilGetBits( ucRegCoilsBuf, usBitOffset, ( unsigned int)( iNCoils > 8 ? 8 : iNCoils ) ); iNCoils -= 8; usBitOffset += 8; } break; case MB_REG_WRITE: while( iNCoils > 0 ) { xMBUtilSetBits( ucRegCoilsBuf, usBitOffset, ( unsigned int )( iNCoils > 8 ? 8 : iNCoils ),*pucRegBuffer++ ); iNCoils -= 8; usBitOffset += 8; } break; } } else { eStatus = MB_ENOREG; } return eStatus; } /*eMBErrorCode eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete ) { return MB_ENOREG; }*/ eMBErrorCode eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete ) { eMBErrorCode eStatus = MB_ENOERR; unsigned int iNDiscrete = ( unsigned int )usNDiscrete; unsigned int usBitOffset; if( ( (int)usAddress >= REG_DISCRETE_START ) &&( usAddress + usNDiscrete <= REG_DISCRETE_START + REG_DISCRETE_SIZE ) ) { usBitOffset = ( int )( usAddress - REG_DISCRETE_START ); while( iNDiscrete > 0 ) { *pucRegBuffer++ = xMBUtilGetBits( ucRegDiscreteBuf, usBitOffset, ( unsigned int )( iNDiscrete > 8 ? 8 : iNDiscrete ) ); iNDiscrete -= 8; usBitOffset += 8; } } else { eStatus = MB_ENOREG; } return eStatus; } 为了配置这两个函数当然了前面还要有若干个宏定义用来储存线圈的数组如下即可 /* ----------------------- Defines ------------------------------------------*/ #define REG_COILS_START 1 #define REG_COILS_SIZE 150 #define REG_DISCRETE_START 1 #define REG_DISCRETE_SIZE 150 /* ----------------------- Static variables ---------------------------------*/ static UCHAR ucRegCoilsBuf[REG_COILS_SIZE]; static UCHAR ucRegDiscreteBuf[REG_DISCRETE_SIZE]; 其次我们因为在上面的两个函数中调用了xMBUtilSetBits和xMBUtilGetBits两个函数,因为我们需要添加头文件:#include "../modbus/include/mbutils.h" 到此处我们的移植工作结束,此时移植的程序可以使用RTU/ASCII 读写寄存器和线圈,这样就可以满足一般的使用要求。 以上移植均通过modbus Poll实际测试。
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 包罗万象 > 大杂烩

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服