chenwh78
楼主
2009/7/8 12:58:31
Modbus通讯库函数的测试程序
// #############################################################################
// *****************************************************************************
// Copyright (c) 2003-2004, Bocon Automation Corp.
// THIS IS AN UNPUBLISHED WORK CONTAINING CONFIDENTIAL AND PROPRIETARY
// INFORMATION WHICH IS THE PROPERTY OF E-GUAGE AUTOMATION CORP.
//
// ANY DISCLOSURE, USE, OR REPRODUCTION, WITHOUT WRITTEN AUTHORIZATION FROM
// E-GUAGE AUTOMATION CORP., IS STRICTLY PROHIBITED.
// *****************************************************************************
// #############################################################################
//************************* DEBUGGING MACROS ***********************************
#define BLUE_TEXT "\x1b[34m" // foreground colors for printf
#define RED_TEXT "\x1b[31m" // foreground colors for printf
#define BLACK_TEXT "\x1b[30m" // foreground colors for printf
#define BINBUFSIZE 255
#define BOUTBUFSIZE 255
#use "Modbus.lib"
#use "TCP-IP.lib"
#define MODBUS_RTU_MASTER 0x10
#define MODBUS_RTU_SLAVE 0x20
#define MODBUS_ASCII_MASTER 0x30
#define MODBUS_ASCII_SLAVE 0x40
#define MODBUS_TCP_MASTER 0x50
#define MODBUS_TCP_SLAVE 0x60
#define TRANSACTION_TIMEOUT 2000L
#define MODBUS_MASTER_POLLING_PERIOD 2000L
// *****************************************************************************
// Design Notes: 非阻塞方式读取键盘输入
// -----------------------------------------------------------------------------
char PeekChar()
{
auto char Key;
if (!kbhit())
{
return 0;
}
dkGetCharFromStdio();
Key = dkCharData;
asm push ip
asm ipset 1
dkCharReady--;
asm pop ip
return Key;
}
// *****************************************************************************
// Design Notes: 打印测试信息
// -----------------------------------------------------------------------------
void PrintTestInfo()
{
printf( RED_TEXT );
printf( "+++Test the Modbus RTU/ASCII/TCP protocol:\n" );
printf( "\t 1: Modbus-RTU Maser\n" );
printf( "\t 2: Modbus-RTU Slave\n" );
printf( "\t 3: Modbus-ASCII Master\n" );
printf( "\t 4: Modbus-ASCII Slave\n" );
printf( "\t 5: Modbus-TCP Master\n" );
printf( "\t 6: Modbus-TCP Slave\n" );
printf( BLUE_TEXT );
printf( "Press 'Q' to exit the program\n" );
}
// *****************************************************************************
// Design Notes: Print out the buffer contents
// -----------------------------------------------------------------------------
void DumpAsciiBuffer( char * pBuffer, int iStrlen )
{
int i;
printf( "\n==>The buffer length is %d\n", iStrlen );
for ( i = 0; i < iStrlen; i++ )
{
printf( "%c ", pBuffer );
}
printf( "\n" );
}
// *****************************************************************************
// Design Notes: Print out the buffer contents
// -----------------------------------------------------------------------------
void DumpHexBuffer( char * pBuffer, int iStrlen )
{
int i;
printf( "\n==>The buffer length is %d\n", iStrlen );
for ( i = 0; i < iStrlen; i++ )
{
printf( "0x%02X ", pBuffer );
}
printf( "\n" );
}
// *****************************************************************************
// Design Notes:
// -----------------------------------------------------------------------------
void main()
{
char key;
char mode;
int iRetVal;
unsigned long dwStartTime;
char srcMsg[256];
char dstMsg[256];
unsigned short srcMsgLen;
unsigned short dstMsgLen;
struct MBSerial mbSer;
struct MBSerial * pMBSer;
struct MBTCP mbTCP;
struct MBTCP * pMBTCP;
// The server socket for passive calling
tcp_Socket serverSock;
struct TCPContext server;
struct TCPContext * pServer;
// The client socket for active calling
tcp_Socket clientSock;
struct TCPContext client;
struct TCPContext * pClient;
// Initialize memory for the server-node context
pServer = &server;
memset( pServer, 0x00, sizeof( struct TCPContext ) );
pServer->m_pSocket = &serverSock;
// Initialize memory for the client-node context
pClient = &client;
memset( pClient, 0x00, sizeof( struct TCPContext ) );
pClient->m_pSocket = &clientSock;
// Initialize the TCP/IP stack
sock_init();
// Initialize the network interface
ifconfig(
IF_ETH0,
IFS_DOWN,
IFS_IPADDR, aton( "172.21.66.25" ),
IFS_NETMASK, 0xFFFFFF00uL,
IFS_ROUTER_SET, aton( "172.21.66.1" ),
IFS_NAMESERVER_SET, aton( "172.21.66.100" ),
IFS_NAMESERVER_ADD, aton( "172.21.66.144" ),
IFS_UP,
IFS_END );
// Make sure the interface exits pending status
if ( ifpending( IF_ETH0 ) % 2 )
{
printf( "The cable is plugged out!\n" );
}
// Make sure the interface is up
if ( !ifstatus( IF_ETH0 ) )
{
// Display some hardware-error information and reset the system
forceSoftReset();
}
// Initialize Modbus Master node
pClient->m_bIsTCPServer = 0;
pClient->m_dwIPAddr = aton( "172.21.66.154" );
pClient->m_usPort = 502;
pClient->m_usMaxSockRetries = 5;
pClient->m_usMaxSessionRetries = 3;
// Reset the Modbus Master socket
ResetTCPSocket( pClient );
// Initialize the Modbus Slave node
pServer->m_bIsTCPServer = 1;
pServer->m_dwIPAddr = gethostid();
pServer->m_usPort = 502;
pServer->m_usMaxSockRetries = 5;
pServer->m_usMaxSessionRetries = 3;
// Reset the Modbus Slave socket
ResetTCPSocket( pServer );
serBopen( 2400 );
serBparity( PARAM_NOPARITY );
serBdatabits( PARAM_8BIT );
// Print out the manipulation information
PrintTestInfo();
pMBSer = &mbSer;
pMBTCP = &mbTCP;
memset( pMBSer, 0x00, sizeof( struct MBSerial ) );
memset( pMBTCP, 0x00, sizeof( struct MBTCP ) );
mode = 0xFF; // Invalid mode
while ( 1 )
{
// Thread 1st: The user input dispatch
costate
{
key = PeekChar();
switch ( key )
{
case '1':
{
mode = MODBUS_RTU_MASTER;
printf( RED_TEXT );
printf( "System now runs in Modbus RTU Maser mode\n" );
printf( BLUE_TEXT );
}
break;
case '2':
{
mode = MODBUS_RTU_SLAVE;
printf( RED_TEXT );
printf( "System now runs in Modbus RTU Slave mode\n" );
printf( BLUE_TEXT );
}
break;
case '3':
{
mode = MODBUS_ASCII_MASTER;
printf( RED_TEXT );
printf( "System now runs in Modbus ASCII Master mode\n" );
printf( BLUE_TEXT );
}
break;
case '4':
{
mode = MODBUS_ASCII_SLAVE;
printf( RED_TEXT );
printf( "System now runs in Modbus ASCII Slave mode\n" );
printf( BLUE_TEXT );
}
break;
case '5':
{
mode = MODBUS_TCP_MASTER;
printf( RED_TEXT );
printf( "System now runs in Modbus TCP Master mode\n" );
printf( BLUE_TEXT );
ResetTCPSocket( pServer );
}
break;
case '6':
{
mode = MODBUS_TCP_SLAVE;
printf( RED_TEXT );
printf( "System now runs in Modbus TCP Slve mode\n" );
printf( BLUE_TEXT );
ResetTCPSocket( pClient );
}
break;
default:
{
}
break;
}
}
// Thread 2nd: Modbus-RTU Master
costate
{
if ( mode != MODBUS_RTU_MASTER )
{
abort;
}
waitfor ( DelayMs( MODBUS_MASTER_POLLING_PERIOD ) );
// Instantiate a modbus request
pMBSer->m_ucNodeID = 23;
pMBSer->m_MBReqeust.m_ucCMD = 3;
pMBSer->m_MBReqeust.m_usStartAddr = 1234;
pMBSer->m_MBReqeust.m_usRegNum = 19;
// Initialize the modbus request string
memset( srcMsg, 0x00, sizeof( srcMsg ) );
ConstructModbusRTUMsg( pMBSer, srcMsg );
// Dump the Modbus RTU request message
DumpHexBuffer( srcMsg, 8 );
// Issue out the Modbus requst
serBwrite( srcMsg, 8 );
waitfor ( DelayMs( TRANSACTION_TIMEOUT ) );
// Receive the Modbus response from the Modbus Slave
memset( srcMsg, 0x00, sizeof( srcMsg ) );
srcMsgLen = 0;
dwStartTime = MS_TIMER;
while ( MS_TIMER - dwStartTime < TRANSACTION_TIMEOUT )
{
iRetVal = serBread( srcMsg + srcMsgLen, sizeof( srcMsg ), 0 );
srcMsgLen += iRetVal;
}
if ( srcMsgLen > 0 )
{
DumpHexBuffer( srcMsg, srcMsgLen );
}
}
// Thread 3rd: Modbus-RTU Slave
costate
{
if ( mode != MODBUS_RTU_SLAVE )
{
abort;
}
// Read Modbus request from the serial port
memset( srcMsg, 0x00, sizeof( srcMsg ) );
srcMsgLen = serBread( srcMsg, sizeof( srcMsg ), 100 );
if ( srcMsgLen > 0 )
{
// Dump the buffer contents of the modbus request
DumpHexBuffer( srcMsg, srcMsgLen );
// Process the Modbus request, generate the Modbus respone message
ProcessModbusRTUMsg( srcMsg, srcMsgLen, dstMsg, &dstMsgLen );
// Send Modbus response message to the Modbus master node
serBwrite( dstMsg, dstMsgLen );
}
}
// Thread 4th: Modbus-ASCII Master
costate
{
if ( mode != MODBUS_ASCII_MASTER )
{
abort;
}
waitfor ( DelayMs( MODBUS_MASTER_POLLING_PERIOD ) );
// Instantiate a modbus request
pMBSer->m_ucNodeID = 23;
pMBSer->m_MBReqeust.m_ucCMD = 3;
pMBSer->m_MBReqeust.m_usStartAddr = 1234;
pMBSer->m_MBReqeust.m_usRegNum = 19;
// Initialize the modbus request string
memset( srcMsg, 0x00, sizeof( srcMsg ) );
ConstructModbusAsciiMsg( pMBSer, srcMsg );
// Dump the modbus requst message
DumpAsciiBuffer( srcMsg, 17 );
// Issue out the Modbus request message
serBwrite( srcMsg, 17 );
// Receive the response from the Modbus slave
memset( srcMsg, 0x00, sizeof( srcMsg ) );
srcMsgLen = 0;
dwStartTime = MS_TIMER;
while ( MS_TIMER - dwStartTime < TRANSACTION_TIMEOUT )
{
iRetVal = serBread( srcMsg + srcMsgLen, sizeof( srcMsg ), 0 );
srcMsgLen += iRetVal;
}
if ( srcMsgLen > 0 )
{
DumpAsciiBuffer( srcMsg, srcMsgLen );
}
}
// Thread 5th: Modbus-ASCII Slave
costate
{
if ( mode != MODBUS_ASCII_SLAVE )
{
abort;
}
// Read Modbus request from the serial port
memset( srcMsg, 0x00, sizeof( srcMsg ) );
srcMsgLen = serBread( srcMsg, sizeof( srcMsg ), 100 );
if ( srcMsgLen > 0 )
{
// Dump the buffer contents of the modbus request
DumpAsciiBuffer( srcMsg, srcMsgLen );
ProcessModbusAsciiMsg( srcMsg, srcMsgLen, dstMsg, &dstMsgLen );
// Dump the contents of the modbus response
DumpAsciiBuffer( dstMsg, dstMsgLen );
// Send response message to the modbus master node
serBwrite( dstMsg, dstMsgLen );
}
}
// Thread 6th: Modbus-TCP Master
costate
{
if ( mode != MODBUS_TCP_MASTER )
{
abort;
}
waitfor ( DelayMs( 500 ) );
RefreshTCPSocketStatus( pClient );
if ( pClient->m_bIsConnected )
{
pMBTCP->m_MBHeader.m_usProtoID = 0;
pMBTCP->m_MBHeader.m_usMsgLen = 6;
pMBTCP->m_MBHeader.m_ucUnitID = 29;
pMBTCP->m_MBReqeust.m_ucCMD = 3;
pMBTCP->m_MBReqeust.m_usStartAddr = 1234;
pMBTCP->m_MBReqeust.m_usRegNum = 50;
memset( srcMsg, 0x00, sizeof( srcMsg ) );
ConstructModbusTCPMsg( pMBTCP, srcMsg );
sock_fastwrite( pClient->m_pSocket, srcMsg, 12 );
memset( srcMsg, 0x00, sizeof( srcMsg ) );
srcMsgLen = 0;
dwStartTime = MS_TIMER;
while ( MS_TIMER - dwStartTime < TRANSACTION_TIMEOUT )
{
tcp_tick( pClient->m_pSocket );
iRetVal = sock_fastread( pClient->m_pSocket, srcMsg + srcMsgLen, sizeof( srcMsg ) );
srcMsgLen += iRetVal;
}
if ( srcMsgLen != 0 )
{
DumpHexBuffer( srcMsg, srcMsgLen );
}
}
}
// Thread 7th: Modbus-TCP Slave
costate
{
if ( mode != MODBUS_TCP_SLAVE )
{
abort;
}
waitfor ( DelayMs( 500 ) );
RefreshTCPSocketStatus( pServer );
if ( pServer->m_bIsConnected )
{
memset( srcMsg, 0x00, sizeof( srcMsg ) );
srcMsgLen = sock_fastread( pServer->m_pSocket, srcMsg, sizeof( srcMsg ) );
if ( srcMsgLen != 0 )
{
DumpHexBuffer( srcMsg, srcMsgLen );
memset( dstMsg, 0x00, sizeof( dstMsg ) );
ProcessModbusTCPMsg( srcMsg, srcMsgLen, dstMsg, &dstMsgLen );
if ( dstMsgLen != 0 )
{
sock_fastwrite( pServer->m_pSocket, dstMsg, dstMsgLen );
DumpHexBuffer( dstMsg, dstMsgLen );
}
}
}
}
}
}