?? mm_rab.lib
字號:
PARAMETER2: starting 0X coil number (zero based).
PARAMETER3: coils count (one based).
PARAMETER4: binary states (OFF == 0, ON == 1) buffer pointer.
RETURN VALUE: 0 (MM_BUSY) if busy, -1 (MM_OK) if success, or exception
code (from master if < -1 or from slave if > 0). See the MM_* and MS_*
definitions near the start of MM_RAB.LIB for the complete list.
END DESCRIPTION ******************************************************/
nodebug
int mmForceCoils(unsigned wAddr, unsigned wCoil, unsigned wCount,
void *pCoils)
{
auto int nErr;
nErr = MM_BUSY;
costate
{
mmCmdNew(wAddr, 0x0F); // Start New Command
mmCmdWord(wCoil); // Coil Address
mmCmdWord(wCount); // Coil Count
mmCmdByte((unsigned char) ((wCount>>3) & 0xFF)); // Byte Count
while(wCount--) // Coil Data
mmCmdByte(*((unsigned char *) pCoils)++);
waitfor(nErr = mmExec()); // Finish&Exec Packet
}
return nErr;
}
/*=========================================================================*\
[0x10] Preset Multiple Registers
\*=========================================================================*/
/*** BeginHeader mmPresetRegs */
int mmPresetRegs(unsigned,unsigned,unsigned,void *);
/*** EndHeader */
/* START FUNCTION DESCRIPTION *****************************************
mmPresetRegs <MM_RAB.LIB>
NOTE: MM_RAB.LIB functions are generally not reentrant.
SYNTAX: int mmPresetRegs(unsigned wAddr, unsigned wReg,
unsigned wCount, void *pRegs)
DESCRIPTION: Modbus Master query 0x10, Preset Multiple Registers.
Presets the contents of the selected registers (4X references) with
values from the buffer pointed to by *pRegs, 16-bits per register with
the starting register number at the beginning of the buffer. The buffer
size should be no less than 'wCount * 2' bytes. When broadcast, this
function presets the same register references in all attached slave
devices.
PARAMETER1: slave address, broadcast (0x00) is supported.
PARAMETER2: starting 4X register number (zero based).
PARAMETER3: registers count (one based).
PARAMETER4: preset values buffer pointer.
RETURN VALUE: 0 (MM_BUSY) if busy, -1 (MM_OK) if success, or exception
code (from master if < -1 or from slave if > 0). See the MM_* and MS_*
definitions near the start of MM_RAB.LIB for the complete list.
END DESCRIPTION ******************************************************/
nodebug
int mmPresetRegs(unsigned wAddr, unsigned wReg, unsigned wCount,
void *pRegs)
{
auto int nErr;
nErr = MM_BUSY;
costate
{
mmCmdNew(wAddr, 0x10); // Start New Command
waitfor(nErr = mmRegWr(wReg, wCount, pRegs)); // Finish & Exec Packet
}
return nErr;
}
/*=========================================================================*\
[0x16] Mask Write 4X Register
\*=========================================================================*/
/*** BeginHeader mmRegMask */
int mmRegMask(unsigned,unsigned,unsigned,unsigned);
/*** EndHeader */
/* START FUNCTION DESCRIPTION *****************************************
mmRegMask <MM_RAB.LIB>
NOTE: MM_RAB.LIB functions are generally not reentrant.
SYNTAX: int mmRegMask(unsigned wAddr, unsigned wReg, unsigned wAnd,
unsigned wOr)
DESCRIPTION: Modbus Master query 0x16, Mask Write 4X Register. Modifies
the contents of the specified holding register (4X reference) by the
following algorithm: 4X[wReg] = (4X[wReg] & wAnd) | (wOr & ~wAnd). If
the wOr value is zero then the result is: 4X[wReg] = 4X[wReg] & wAnd.
If the wAnd value is zero then the result is: 4X[wReg] = wOr. This
function is used to set or clear individual bits in the register,
without the possibility of corrupting other register bits that might be
solved in the slave device in the mean-time between a read register
query and a subsequent write register query.
PARAMETER1: slave address, broadcast (0x00) is not supported.
PARAMETER2: 4X register number (zero based).
PARAMETER3: AND mask value (16-bit binary).
PARAMETER4: OR mask value (16-bit binary).
RETURN VALUE: 0 (MM_BUSY) if busy, -1 (MM_OK) if success, or exception
code (from master if < -1 or from slave if > 0). See the MM_* and MS_*
definitions near the start of MM_RAB.LIB for the complete list.
END DESCRIPTION ******************************************************/
nodebug
int mmRegMask(unsigned wAddr, unsigned wReg, unsigned wAnd,
unsigned wOr)
{
auto int nErr;
if(!wAddr)
{
nErr = MM_NOBROAD; // Broadcast Not Supported
}
else
{
nErr = MM_BUSY;
costate
{
mmCmdNew(wAddr, 0x16); // Start New Command
mmCmdWord(wReg); // Register Address
mmCmdWord(wAnd); // And Mask
mmCmdWord(wOr); // Or Mask
waitfor(nErr = mmExec()); // Finish & Execute Packet
}
}
return nErr;
}
/*=========================================================================*\
[0x17] Read/Write 4X Registers
\*=========================================================================*/
/*** BeginHeader mmRegRdWr */
int mmRegRdWr(unsigned,unsigned,unsigned,void *,unsigned,unsigned,
void *);
/*** EndHeader */
/* START FUNCTION DESCRIPTION *****************************************
mmRegRdWr <MM_RAB.LIB>
NOTE: MM_RAB.LIB functions are generally not reentrant.
SYNTAX: int mmRegRdWr(unsigned wAddr, unsigned wRdReg, unsigned wRdCnt,
void *pRd, unsigned wWrReg, unsigned wWrCnt,
void *pWr)
DESCRIPTION: Modbus Master query 0x17, Read/Write 4X Registers.
Performs one registers read and one registers write operation (all 4X
references) in a single transaction. The function writes new contents
into one group of registers, then reads the contents of another group
of registers. Presets the contents of the selected write registers with
values from the buffer pointed to by *pWr, 16-bits per register with
the starting register number at the beginning of the write buffer. The
write buffer size should be no less than 'wWrCnt * 2' bytes. Places the
present contents of the selected read registers into the buffer pointed
to by *pRd, 16-bits per register with the starting register number at
the beginning of the read buffer. The read buffer size should be no
less than 'wRdCnt * 2' bytes.
PARAMETER1: slave address, broadcast (0x00) is not supported.
PARAMETER2: starting 4X read register number (zero based).
PARAMETER3: read registers count (one based).
PARAMETER4: read registers information buffer pointer.
PARAMETER5: starting 4X write register number (zero based).
PARAMETER6: write registers count (one based).
PARAMETER7: write registers values buffer pointer.
RETURN VALUE: 0 (MM_BUSY) if busy, -1 (MM_OK) if success, or exception
code (from master if < -1 or from slave if > 0). See the MM_* and MS_*
definitions near the start of MM_RAB.LIB for the complete list.
END DESCRIPTION ******************************************************/
nodebug
int mmRegRdWr(unsigned wAddr, unsigned wRdReg, unsigned wRdCnt,
void *pRd, unsigned wWrReg, unsigned wWrCnt,
void *pWr)
{
auto int nErr;
if(!wAddr)
{
nErr = MM_NOBROAD; // No Broadcast
}
else
{
nErr = MM_BUSY;
costate
{
mmCmdNew(wAddr, 0x17); // Start New Command
mmCmdWord(wRdReg); // Read Register Addr
mmCmdWord(wRdCnt); // Read Register Count
waitfor(nErr = mmRegWr(wWrReg, wWrCnt, pWr)); // Finish&Exec Packet
if(nErr == MM_OK) // Process Reply if OK
mmRegExt(pRd);
}
}
return nErr;
}
/***************************************************************************\
MODBus ASCII Master Packet Processing
\***************************************************************************/
/*** BeginHeader mmaInit */
void mmaInit();
// additional function prototypes for Modbus ASCII
unsigned mmLRC(unsigned char *,unsigned);
int mmExec();
/*** EndHeader */
/*=========================================================================*\
Compute Longitude Redundancy Check
\*=========================================================================*/
nodebug
unsigned mmLRC(unsigned char *pcMess, unsigned wLen)
{
auto unsigned char cSum;
for(cSum = 0; wLen--; cSum += *pcMess++);
return cSum;
}
/*=========================================================================*\
Assemble MODBus ASCII Packet & Process when Done
\*=========================================================================*/
#ifndef MM_BRTO
#define MM_BRTO 1000L // default ASCII Begin Reply Time Out (mS)
#endif
#ifndef MM_ERTO
#define MM_ERTO 1000L // default ASCII End Reply Time Out (mS)
#endif
const unsigned char acHex[] = "0123456789ABCDEF";
unsigned char acMMM[516];
nodebug
int mmExec()
{
auto unsigned char *pcHex;
auto unsigned char *pcCmd;
auto unsigned char *pcM;
static unsigned char *pcRep;
static unsigned wCnt;
auto unsigned wLRC;
static int nByte;
auto int nErr;
nErr = MM_BUSY;
costate
{
wLRC = -mmLRC(acMMCmd,pcMMCmd-acMMCmd) & 0xFF; // get ASCII LRC
// convert query to Modbus ASCII format with appended LRC
pcM = acMMM;
*pcM++ = ':';
for(pcCmd = acMMCmd; pcCmd < pcMMCmd; ++pcCmd)
{
*pcM++ = acHex[*pcCmd >> 4];
*pcM++ = acHex[*pcCmd & 15];
}
*pcM++ = acHex[wLRC >> 4];
*pcM++ = acHex[wLRC & 15];
*pcM++ = '\r';
*pcM++ = '\n';
*pcM = '\0';
while(mmRecv() != -1); // clean out receive buffer
mmSend(NULL, 0); // clean out transmit buffer
waitfor(mmSend(acMMM, pcM - acMMM)); // send Modbus ASCII query
// clear out response buffer (extra time for response to begin)
memset(acMMRep, 0, sizeof(acMMRep));
if(acMMCmd[0] == 0x00)
{
// broadcast command, no slave response expected
nErr = MM_OK;
abort;
}
// look for ASCII response's initial COLON
nByte = -1; // protect against immediate time out
do
{
waitfor(DelayMs(MM_BRTO) || ((nByte = mmRecv()) != -1));
} while((nByte != -1) && (nByte != ':'));
if(nByte == -1)
{
// no response
nErr = MM_TIMEOUT;
abort;
}
// collect ASCII response up to the CR
pcRep = acMMRep;
for(wCnt = 0; wCnt < sizeof(acMMRep); wCnt++)
{
// either response end CR or first byte of hex-digit pair
nByte = -1; // protect against immediate time out
waitfor(DelayMs(MM_ERTO) || ((nByte = mmRecv()) != -1));
if(nByte == '\r')
{
// go check for response end LF after CR
break;
}
if(nByte == -1)
{
// incomplete response
nErr = MM_TIMEOUT;
abort;
}
if(!(pcHex = strchr(acHex, nByte)))
{
// illegal character
nErr = MM_GARBAGE;
abort;
}
*pcRep = (pcHex - acHex) << 4;
// second byte of hex-digit pair
nByte = -1; // protect against immediate time out
waitfor(DelayMs(MM_ERTO) || ((nByte = mmRecv()) != -1));
if(nByte == -1)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -