⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mm_rab.lib

📁 modbus 运用事例
💻 LIB
📖 第 1 页 / 共 4 页
字号:
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 + -