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

📄 ms_rab.lib

📁 modbus 源码 modbus s yuanma
💻 LIB
📖 第 1 页 / 共 3 页
字号:
	int			nErr;

	wCoil = msCmdWord ( 2 );						//	Coil Address
	wCount = msCmdWord ( 4 );						//	Coil Count
	pcState = &acMSCmd[7];							//	State Field Pointer
	while (wCount) {									//	Force Coils
		wState = *pcState++;
		for (wBit=8;wBit-- && wCount;wState>>=1,wCount--)
			if (nErr = msOutWr ( wCoil++,wState&1 ))
				return msRepErr ( nErr );
	}
	msRepNew ( wMSCmd );								//	Start Reply
	msRepWord ( msCmdWord(2) );					//	Coil Address (Fix 12/7/98 S. Kolega)
	msRepWord ( msCmdWord(4) );					//	Coil Count
	return msRepDone ();								//	Complete & Send Reply
}

/*=========================================================================*\
	[0x10] Preset Multiple Registers
\*=========================================================================*/

nodebug
int
msPresetRegs	(	void
					)
					
{
	if (msRegWr ( 2 )) {					//	Decode & Write Registers
		msRepNew ( wMSCmd );				//	Start Reply
		msRepWord ( msCmdWord(2) );	//	Register Address
		msRepWord ( msCmdWord(4) );	//	Register Count
		msRepDone ();						//	Complete & Send Reply
	}
	return 1;
}

/*=========================================================================*\
	[0x16] Mask Write Register
\*=========================================================================*/

nodebug
int
msRegMask		(	void
					)
					
{	unsigned		wReg,wAnd,wOr,wData;
	int			nErr;

	if (!acMSCmd[0])									//	Broadcast Not Supported
		return 0;

	wReg = msCmdWord ( 2 );							//	Register Address
	wAnd = msCmdWord ( 4 );							//	And Mask
	wOr = msCmdWord ( 6 );							//	Or Mask
	if (nErr = msRead ( wReg,&wData ))
		return msRepErr ( nErr );
	wData = (wData & wAnd) | (wOr & ~wAnd);
	if (nErr = msWrite ( wReg,wData ))
		return msRepErr ( nErr );
	msRepNew ( wMSCmd );								//	Start Reply
	msRepWord ( wReg );								//	Register Address
	msRepWord ( wAnd );								//	And Mask
	msRepWord ( wOr );								//	Or Mask
	return msRepDone ();								//	Complete & Send Reply
}

/*=========================================================================*\
	[0x17] Read/Write Registers
\*=========================================================================*/

nodebug
int
msRegRdWr		(	void
					)
					
{
	if (!acMSCmd[0])			//	Broadcast Not Supported
		return 0;

	if (msRegWr ( 6 ))		//	Decode & Write Registers
		msRegRd ( msRead );	//	Read Regs & Reply
	return 1;
}

/***************************************************************************\
	MODBus High-Level Support Functions
\***************************************************************************/

/*=========================================================================*\
	Process & Execute Command
\*=========================================================================*/

nodebug
int
msExec			(	void
					)
					
{
	int		nErr;

	wMSCmd = acMSCmd[1];							//	Extract Command Opcode
	msStart ();										//	Start Packet Processing
	switch ( wMSCmd ) {							//	Dispatch Handler
		case	0x01	:								//	Read Coil Status
			nErr = msCmdOutRd ();
			break;
		case	0x02	:								//	Read Input Status
			nErr = msCmdIn ();
			break;
		case	0x03	:								//	Read Holding Registers
			nErr = msCmdRead ();
			break;
		case	0x04	:								//	Read Input Registers
			nErr = msCmdInput ();
			break;
		case	0x05	:								//	Force Single Coil
			nErr = msForceCoil ();
			break;
		case	0x06	:								//	Preset Single Register
			nErr = msPresetReg ();
			break;
		case	0x0B	:								//	Fetch Comm Event Counter
			nErr = msFetchComm ();
			break;
		case	0x0F	:								//	Force Multiple Coils
			nErr = msForceCoils ();
			break;
		case	0x10	:								//	Preset Multiple Registers
			nErr = msPresetRegs ();
			break;
		case	0x16	:								//	Mask Write Register
			nErr = msRegMask ();
			break;
		case	0x17	:								//	Read/Write Registers
			nErr = msRegRdWr ();
			break;

		case	0x07	:								//	Read Exception Status
		case	0x08	:								//	Diagnostics
		case	0x0C	:								//	Fetch Comm Event Log
		case	0x11	:								//	Report Slave ID
		case	0x14	:								//	Read General Reference
		case	0x15	:								//	Write General Reference
		case	0x18	:								//	Read FIFO Queue
		default		:								//	All Non-MODBus Opcodes
			nErr = msRepErr ( MS_BADFUNC );
	}
	msDone ();										// Packet Processing Done
	return nErr;
}

/*=========================================================================*\
	Initialize MODBus Driver
\*=========================================================================*/

nodebug
void
msInit			(	unsigned			wAddr
					)
					
{
	wMSAddr = wAddr;
}

/***************************************************************************\
	MODBus ASCII Packet Processing
\***************************************************************************/

/*** BeginHeader msaInit */
void msaInit ( unsigned wAddr );

extern shared char *pcMSAM;
extern char acMSAM[516];
/*** EndHeader */

shared char		*pcMSAM;							//	ASCII Message Pointer
char				acMSAM[516];					//	ASCII Message Buffer

#asm nodebug root

;=====================================================================
; msError : Handle Serial Error (Reset Packet Processing)
;
; INPUT  :
;          None
; OUTPUT :
;          None

msError::		ld		hl,acMSAM			; pcMSAM = acMSAM
					ld		(pcMSAM),hl
					ret							; Done

;=====================================================================
; msRecv : Next Byte Received from MODBus
;
; INPUT  :
;          HL = Byte Received
; OUTPUT :
;          None

msRecv::			ld		a,l					; A = Byte (Parity Masked)
					and	07Fh
					cp		a,':'					; A = ':'	=> Restart & Store ':'
					jr		z,msR0
					cp		a,00Dh				; A = <CR>	=> Store <CR>
					jr		z,msR1
					cp		a,00Ah				; A = <LF>	=> Store <LF>
					jr		z,msR1
					cp		a,'0'					; A < '0'	=> Restart
					jr		c,msError
					cp		a,'9'+1				; A <= '9'	=> Store '0'..'9'
					jr		c,msR1
					cp		a,'A'					; A < 'A'	=> Restart
					jr		c,msError
					cp		a,'F'+1				; A <= 'F'	=> Store 'A'..'F'
					jr		c,msR1
					jr		msError				; Done (No Legal Character)

msR0:				call	msError				; Reset Packet Processing
msR1:				push	de						; Protect DE
					ld		de,(pcMSAM)			; DE = Buffer Pointer
					ld		hl,acMSAM+516-1	; HL = End of Buffer
					or		a						; Done if Buffer Full
					sbc	hl,de
					jr		c,msR2
					ex		de,hl					; HL = Buffer Pointer
					ld		(hl),a				; Store Byte to Buffer
					inc	hl						; Bump Pointer
					ld		(pcMSAM),hl
msR2:				pop	de						; Restore DE
					ret							; Done
#endasm

/*=========================================================================*\
	Compute Longitude Redundancy Check
\*=========================================================================*/

nodebug
unsigned
msaLRC			(	char				*pcMess,
						unsigned			wLen
					)
					
{	char		cSum;

		for (cSum=0;wLen--;cSum+=*pcMess++);
		return cSum;
}

/*=========================================================================*\
	Assemble MODBus ASCII Packet & Process when Done
\*=========================================================================*/

nodebug
void
msRun				(	void
					)
					
{
	static char		*pcHex;
	const static char acHex[] = "0123456789ABCDEF";
	static int		nDelay;
	char				*pcCmd,*pcRep;
	char				*pcM;
	unsigned			wLRC;
	int				c;

	costate sMSRun always_on {
		msError();
		do {
			c = msXgetc();
			if (c != -1)	msRecv(c);
		} while (c != '\n');
		
		if ((pcMSAM > (acMSAM+2)) && (*(pcMSAM-1) == '\n') &&
							(*(pcMSAM-2) == '\r') && (acMSAM[0] == ':')) {

			for (pcM=acMSAM+1,pcCmd=acMSCmd;*pcM!='\r';++pcCmd) {
				if (!(pcHex = strchr ( acHex,*pcM++ )))
					break;
				*pcCmd = (pcHex-acHex) << 4;
				if (!(pcHex = strchr ( acHex,*pcM++ )))
					break;
				*pcCmd += (pcHex-acHex);
			}

			if (!msaLRC ( acMSCmd,pcCmd-acMSCmd )) {
				if (!acMSCmd[0] || (acMSCmd[0] == wMSAddr)) {
					if (msExec() && acMSCmd[0]) {
						wLRC = -msaLRC(acMSRep,pcMSRep-acMSRep) & 0xFF;
						pcM = acMSAM;
						*pcM++ = ':';
						for (pcRep=acMSRep;pcRep<pcMSRep;++pcRep) {
							*pcM++ = acHex[*pcRep>>4];
							*pcM++ = acHex[*pcRep&15];
						}
						*pcM++ = acHex[wLRC>>4];
						*pcM++ = acHex[wLRC&15];
						*pcM++ = '\r';
						*pcM++ = '\n';
						*pcM = 0;

						msSend ( NULL,0 );
						waitfor ( msSend ( acMSAM,pcM-acMSAM ) );
					}
				}
			}
		}
	}
}

/*=========================================================================*\
	Initialize MODBus ASCII Driver
\*=========================================================================*/

nodebug
void
msaInit			(	unsigned			wAddr
					)
					
{
	msError ();
	msInit ( wAddr );
}

/***************************************************************************\
	MODBus RTU Packet Processing
\***************************************************************************/

/*** BeginHeader msrInit */
void msrInit ( unsigned wAddr,unsigned wTO );
/*** EndHeader */

shared
unsigned			wMSRLast;					//	Time Stamp of Last Serial Char
unsigned			wMSRTO;						//	Timeout Period for RTU Sync

#asm nodebug root

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -