📄 ms_rab.lib
字号:
/***************************************************************************\
Dynamic C MODBus ASCII/RTU Slave
Copyright (c) 2002 Z-World, Inc.
Copyright (c) 1997, CFControls.
\***************************************************************************/
/*** BeginHeader */
#ifndef __MS_RAB_LIB
#define __MS_RAB_LIB
// Supported MODBus Exceptions
#define MS_BADFUNC 0x01 // Illegal Function
#define MS_BADADDR 0x02 // Illegal Data Address
#define MS_BADDATA 0x03 // Illegal Data Value
/*** EndHeader */
/***************************************************************************\
MODBus Packet Utilities & Globals
\***************************************************************************/
/*** BeginHeader msInit */
extern
shared char *pcMSCmd,*pcMSRep;
extern
char acMSCmd[256],acMSRep[256];
extern
unsigned wMSAddr;
unsigned msCmdWord ( unsigned wOff );
void msError ( void );
void msRecv ( int nByte );
int msSend ( char *pcMess,unsigned wLen );
void msRun ( void );
void msInit ( unsigned wAddr );
/*** EndHeader */
unsigned wMSAddr; // Network Address
unsigned wMSComm; // Communication Counters
unsigned wMSCmd; // Command Opcode
// Don't Change Order
shared char *pcMSCmd; // Command Pointer
char acMSCmd[256]; // Command Buffer
shared char *pcMSRep; // Reply Pointer
char acMSRep[256]; // Reply Buffer
/*=========================================================================*\
Extract Word (MSB First) from Command Body
\*=========================================================================*/
nodebug
unsigned msCmdWord(unsigned wOff)
{
return(acMSCmd[wOff] << 8) + acMSCmd[wOff + 1];
}
/*=========================================================================*\
Add Byte to Reply Body
\*=========================================================================*/
nodebug
int msRepByte(char cByte)
{
if(&acMSRep[sizeof(acMSRep) - 1] <= pcMSRep)
return 0;
*pcMSRep++ = cByte;
return 1;
}
/*=========================================================================*\
Add Word to Reply (MSB First)
\*=========================================================================*/
nodebug
int msRepWord(unsigned wWord)
{
return msRepByte(wWord >> 8) && msRepByte(wWord);
}
/*=========================================================================*\
Start New Reply
\*=========================================================================*/
nodebug
void msRepNew(unsigned wCmd)
{
pcMSRep = acMSRep; // Reset Reply Pointer
msRepByte ( wMSAddr ); // Slave Address
msRepByte ( wCmd ); // Command Opcode
}
/*=========================================================================*\
Complete Reply Body
\*=========================================================================*/
nodebug
int msRepDone()
{
++wMSComm; // Inc Comm Counter
return 1; // Success
}
/*=========================================================================*\
Compose Exception Reply
\*=========================================================================*/
nodebug
int msRepErr(unsigned wCode)
{
msRepNew ( 0x80|wMSCmd ); // Start Reply (Set Error Flag)
msRepByte ( wCode ); // Error Code
--wMSComm; // Adjust Comm Counter
return msRepDone (); // Complete Reply
}
/***************************************************************************\
MODBus I/O Utilities
\***************************************************************************/
/*=========================================================================*\
Read Coils (Output or Input)
\*=========================================================================*/
nodebug
int msCoilRd(int (*pxRd)())
{
unsigned wCoil, wCount;
int nState, nErr;
char cAcc, cMask;
if (!acMSCmd[0]) // Broadcast Not Supported
return 0;
wCoil = msCmdWord(2); // Starting Address
wCount = msCmdWord(4); // Count
msRepNew(wMSCmd); // Start Reply
msRepByte((wCount + 7) >> 3); // Byte Count
while (wCount) {
cAcc = 0; // Read Coils
for (cMask = 0x01; cMask && wCount; cMask <<= 1, wCount--) {
if (nErr = pxRd(wCoil++, &nState))
return msRepErr(nErr);
if (nState)
cAcc |= cMask;
}
msRepByte(cAcc); // Add Coil to Packet
}
return msRepDone(); // Complete & Send Reply
}
/*=========================================================================*\
Read Registers (Input or Holding)
\*=========================================================================*/
nodebug
int msRegRd(int (*pxRd)())
{
unsigned wAddr, wCount, wData;
int nErr;
if (!acMSCmd[0]) // Broadcast Not Supported
return 0;
wAddr = msCmdWord(2); // Starting Address
wCount = msCmdWord(4); // Count
msRepNew(wMSCmd); // Start Reply
msRepByte(2 * wCount); // Byte Count
while (wCount--) { // Read Registers
if (nErr = pxRd(wAddr++, &wData))
return msRepErr(nErr);
msRepWord(wData); // Add Word to Packet
}
return msRepDone(); // Complete & Send Reply
}
/*=========================================================================*\
Write Registers (No Reply)
\*=========================================================================*/
nodebug
int msRegWr(unsigned wOff)
{
unsigned wAddr, wCount;
int nErr;
wAddr = msCmdWord(wOff); // Register Address
wCount = msCmdWord(wOff += 2); // Register Count
++wOff; // Skip Byte Count
while (wCount--) { // Write Registers
if (nErr = msWrite(wAddr++, msCmdWord(wOff += 2))) {
msRepErr(nErr);
return 0;
}
}
return 1;
}
/***************************************************************************\
MODBus Command/Reply Processors
\***************************************************************************/
/*=========================================================================*\
[0x01] Read Output Coil Status
\*=========================================================================*/
nodebug
int
msCmdOutRd ( void
)
{
return msCoilRd ( msOutRd );
}
/*=========================================================================*\
[0x02] Read Input Coils
\*=========================================================================*/
nodebug
int
msCmdIn ( void
)
{
return msCoilRd ( msIn );
}
/*=========================================================================*\
[0x03] Read Holding Registers
\*=========================================================================*/
nodebug
int
msCmdRead ( void
)
{
return msRegRd ( msRead );
}
/*=========================================================================*\
[0x04] Read Input Registers
\*=========================================================================*/
nodebug
int
msCmdInput ( void
)
{
return msRegRd ( msInput );
}
/*=========================================================================*\
[0x05] Force Single Coil
\*=========================================================================*/
nodebug
int
msForceCoil ( void
)
{ unsigned wCoil,wData;
int nErr;
nErr = MS_BADDATA;
wCoil = msCmdWord ( 2 ); // Coil Number
wData = msCmdWord ( 4 ); // Coil State
switch ( wData ) {
case 0x0000 : // Force Coil Off
nErr = msOutWr ( wCoil,0 );
break;
case 0xFF00 : // Force Coil On
nErr = msOutWr ( wCoil,1 );
break;
}
if (nErr)
return msRepErr ( nErr );
msRepNew ( wMSCmd ); // Start Reply
msRepWord ( wCoil ); // Coil Number
msRepWord ( wData ); // Coil State
return msRepDone (); // Complete & Send Reply
}
/*=========================================================================*\
[0x06] Preset Single Register
\*=========================================================================*/
nodebug
int
msPresetReg ( void
)
{ unsigned wAddr,wData;
int nErr;
wAddr = msCmdWord ( 2 ); // Register Address
wData = msCmdWord ( 4 ); // Register Value
nErr = msWrite ( wAddr,wData ); // Write Register
if (nErr)
return msRepErr ( nErr );
msRepNew ( wMSCmd ); // Start Reply
msRepWord ( wAddr ); // Register Address
msRepWord ( wData ); // Register Data
return msRepDone (); // Complete & Send Reply
}
/*=========================================================================*\
[0x0B] Fetch Comm Event Counter
\*=========================================================================*/
nodebug
int
msFetchComm ( void
)
{
if (!acMSCmd[0]) // Broadcast Not Supported
return 0;
msRepNew ( wMSCmd ); // Start Reply
msRepWord ( 0x0000 ); // Slave Not Busy
msRepWord ( wMSComm ); // Comm Counter
return msRepDone (); // Complete & Send Reply
}
/*=========================================================================*\
[0x0F] Force Multiple Coils
\*=========================================================================*/
nodebug
int
msForceCoils ( void
)
{
unsigned wCoil,wCount,wState,wBit;
char *pcState;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -