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

📄 mmbl21xx.c

📁 modbus 运用事例
💻 C
字号:

/*  SAMPLE PROGRRAM **********************************************************

SAMPLE NAME:       		MM_BL21XX.C         

DESCRIPTION:				Modbus Master Sample program.  Written for use with
								the BL2100 series SBC's, Though it can be modified
								for any rabbit device with an RS232/RS485 channel.
								
								 

USER INSTRUCTIONS:		Run The MS_BL21XX.C sample program on the slave device.
								Setup to Match the slaves io and protocol settings
								with the user configuration area macros below.
								
								The Following sample is setup to read/write
								
								4 digital outputs
								4 digital inputs
								4 analog outputs	
								4 analog inputs
								
								The analog channels are setup to send/receive
								a floating point representation.  It will use
								2 registers per channel and convert from/to 
								floating point values.
								
								The Slave program is setup to use all of the BL21xx
								resources.  
								
								The following modbus registers are used for this
								sample;
								
								0x10001 	-> 0x10004	Output Coils
								0x20001	-> 0x20004  Input  Status
								0x30001	-> 0x30008  Analog Output Writing
														   2 regs per converted from float
								0x40001  -> 0x40008	Analog Input Status 
															2 regs per converted to (float)


END SAMPLE DESCRIPTION *******************************************************/




/*============================================================================*\
	
									USER CONFIGURATION AREA

\*============================================================================*/

//	Defines the Baudrate to use
#define	MODBUS_BAUDRATE	9600
// Defines the Protocol.  0 = ASCII, 1 = RTU
#define	MODBUS_PROTOCOL				1

// Defines the ms output delay between changes
#define	MODBUS_OUTPUT_DELAY	  		500

/*============================================================================*/




// Set the variable class to auto
#class	auto

// If not using separate I & D then move as much code into xmem as possible
#ifndef __SEPARATE_INST_DATA__
	#memmap xmem
#endif

// Modbus Master library
#use	"mmz_rab.lib"


// Setup serial port D in/out serial buffers.
#define	DINBUFSIZE	255
#define	DOUTBUFSIZE	255

// Defines the Serial port type. 0 = RS485, 1 = RS232
#define	MODBUS_SERIAL					0

// Defines the number of Digital outputs on the slaves
#define	MODBUS_DIGITAL_OUTPUTS		4

// Defines the Number of Digital inputs on the slaves
#define	MODBUS_DIGITAL_INPUTS		4

// Defines the number of analog inputs on the slaves
#define	MODBUS_ANALOG_INPUTS			4

// Defines the number of analog outputs on the slaves
#define	MODBUS_ANALOG_OUTPUTS		4

#define	MODBUS_SLAVES_COUNT			1

// for display purposes only
const char *onOff[] =
{
	"LOW ",
	"HIGH",
};

// Slave Data structure
typedef struct
{
 	// Slaves address	
	int	addr;
	// Slaves current digital output status
 	int	digOutShadow[MODBUS_DIGITAL_OUTPUTS+1];
 	// Slaves current digital input status 
	int	digInShadow[MODBUS_DIGITAL_INPUTS+1];  
	// Slaves current analog output status
	float	anaOutShadow[MODBUS_ANALOG_OUTPUTS+1];
	// Slaves current analog input status
	float	anaInShadow[MODBUS_ANALOG_INPUTS+1];	
	// Last error detected in the modbus transactions
	int	Errors;
} _mSlaves;

// 1 structure per slave
_mSlaves mSlaves[MODBUS_SLAVES_COUNT+1];

/*============================================================================*\
 			MODBUS FUNCTION (SEE FUNCTION DESCRIPTION FOR DETAILS)
\*============================================================================*/


nodebug
void	mmDrx  (void)
{
	while (serDwrUsed() || BitRdPortI(SDSR,2) || BitRdPortI(SDSR,3));
	ser485Rx();
	serDrdFlush();
}

nodebug
void mmDtx()
{
  ser485Tx();	 
}

nodebug
int mmDopen(unsigned long qBaud)
{
	if (serDopen(qBaud))
	{  	 
		serDparity(PARAM_EPARITY);
		serDdatabits(PARAM_8BIT); 
		serMode(0);  
		return 1;
	}
	return 0;   
}

/*==========================================================================*\
					Application specific functions with modbus functionality
\*==========================================================================*/

// For reading the status of the slaves digital outputs

int	readOutputs( _mSlaves *Slave )
{
	static int retval;
	static int outs;
	costate
	{
		retval = 0;
		// Send a Coil Read command, and wait for either a reply,
		// or a timeout err.
	  	waitfor( (Slave -> Errors = \
	  				 mmOutRd(Slave -> addr,	      
								0x0000,
								MODBUS_DIGITAL_OUTPUTS,
								&outs)					
								
				  	) != MM_BUSY );
		// if the reply from the slave was good, store the results		  	
	 	if (Slave -> Errors== MM_OK)	
	 	{
	 		// copying the results for the read to the shadow registers
	 		Slave -> digOutShadow[0] = bit(&outs,0);
	 		Slave -> digOutShadow[1] = bit(&outs,1); 
	 		Slave -> digOutShadow[2] = bit(&outs,2);
	 		Slave -> digOutShadow[3] = bit(&outs,3);     
	 		retval = 1;     
	 	}
	 	// if the reply was bad, return the bad reply code
	 	// (codes are located in the mm_rab.lib
	 	else retval = Slave -> Errors;  
	}
	return (retval);
}

// For reading the status of the slaves digital inputs
int	readInputs(_mSlaves *Slave ) 
{
	static int retval;
	static int ins;
	costate
	{
		retval = 0;
		// Send a Input Read command, and wait for either a reply,    
		// or a timeout err.
	  	waitfor( (Slave -> Errors = \
	  				 mmIn	( Slave -> addr,	      
							  0x0000,
							  MODBUS_DIGITAL_INPUTS,
							  &ins)             
							  
				  	) != MM_BUSY );
		// if the reply from the slave was good, store the results		    
	 	if (Slave ->  Errors == MM_OK)	
	 	{
	 		// copying the results for the read to the shadow registers     
	 	   Slave -> digInShadow[0] = bit(&ins,0);	    
	 		Slave -> digInShadow[1] = bit(&ins,1); 
	 		Slave -> digInShadow[2] = bit(&ins,2); 
	 		Slave -> digInShadow[3] = bit(&ins,3);
	 		retval = 1;     
	 	}
	 	else retval = Slave ->  Errors ;  
	}
	// if the reply was bad, return the bad reply code  
	// (codes are located in the mm_rab.lib
	return (retval);
}
// For reading the status of the slaves analog inputs
// Inputs will come in as two registers, and then converted to float values

int readAnaInputs( _mSlaves *Slave)
{
	static int retval;
	static int cnt;
	static unsigned int anaRegs[1+MODBUS_ANALOG_INPUTS * 2];  
	costate
	{
		retval = 0;
		// Send a Read Input Register command.
		waitfor( (Slave -> Errors = \    
					mmInput( Slave -> addr,	                
							  0x0000,
							  MODBUS_ANALOG_INPUTS * 2,
							  &anaRegs[0])          
				   ) != MM_BUSY );
	  if (Slave ->  Errors == MM_OK)	 
	  {
	 		cnt = 0;
	 		for (cnt = 0 ; cnt <MODBUS_ANALOG_INPUTS; cnt++)
	 		{     
	 			Slave ->anaInShadow[cnt] = *(float*)&anaRegs[(cnt*2)]; 		
	  		}
	  		retval = 1 ;    
	  }
	    
	  else retval = Slave ->  Errors ;        
	}
	return retval; 

}
// for writing to the digital outputs.
// 
int	writeOutputs(_mSlaves *Slave)
{
	static int retval;
	static long del;
	static char outs;  
	#GLOBAL_INIT {del = 0;}
	costate
	{
		retval = 0;
		if ( del < MS_TIMER)
		{
	  		if (Slave ->digOutShadow[0] == 1)
	  				outs = 0;
	  		else
	  		{	
	  		 		outs = 0xFF;	      
	  		}		
	 		waitfor( (Slave -> Errors = mmForceCoils(Slave -> addr,
	 				  				0x0000,
	 								MODBUS_DIGITAL_OUTPUTS,
	 								&outs		) )!= MM_BUSY);
	 		if (Slave ->  Errors == MM_OK)	retval = 1;						
	 		else retval = Slave ->  Errors ;
	 		del = MS_TIMER + MODBUS_OUTPUT_DELAY;	          
		}
		else
		{
			retval = 1;
		}
	}
	return retval;	
		
	

}

// For reading the status of the slaves analog outputs
// Output values are floats, and will be converted to two integer registers
// before sending to the slaves

writeAnaOut (_mSlaves *Slave)
{
	static int retval;
	static unsigned int anaRegs[2];   
	static int cnt;
	static long del;
	#GLOBAL_INIT {del = 0;}
	costate  
	{
	 	if (del < MS_TIMER)
	 	{	
			retval = 0;
			for (cnt = 0 ; cnt < MODBUS_ANALOG_OUTPUTS+1  ; cnt++)
			{
		  		if (Slave -> anaOutShadow[cnt] <  8.75 )    
		  			 Slave -> anaOutShadow[cnt] += 1.25;
		  			       
		 		else Slave -> anaOutShadow[cnt] = 0.00;
		  		*(float*) &anaRegs[0] = Slave -> anaOutShadow[cnt];
		  		waitfor( (Slave -> Errors = \       
						mmPresetRegs(Slave -> addr,
										0x0000 + (cnt * 2),
										2,
										anaRegs
										) ) != MM_BUSY);
		  		
			}           
			if (Slave ->  Errors == MM_OK)	 
	  		{
	 			retval = 1;     
	  		}
	    	else retval = Slave ->  Errors ;
	    	del = MS_TIMER + MODBUS_OUTPUT_DELAY;        
		}
		else 
		{
			retval = 1;
		}
	}
	return retval;
}
// The following are for display purposes only

void DispStr(int x, int y, char *s)
{
   x += 0x20;
   y += 0x20;
   printf ("\x1B=%c%c%s", x, y, s);
}

int	updateInputs(_mSlaves *Slave)
{
	char buff[100];
	sprintf(buff," %s        %s        %s        %s",
			 			onOff[Slave -> digInShadow[0]],
			 			onOff[Slave -> digInShadow[1]],
			 			onOff[Slave -> digInShadow[2]],
			 			onOff[Slave -> digInShadow[3]]);         
	DispStr(20,10,buff);
	return 1;

}

int	updateOutputs(_mSlaves *Slave)
{
	char buff[100];
	sprintf(buff," %s        %s        %s        %s",
			 			onOff[Slave -> digOutShadow[0]],
			 			onOff[Slave -> digOutShadow[1]],      
			 			onOff[Slave -> digOutShadow[2]],      
			 			onOff[Slave -> digOutShadow[3]]);         
	DispStr(20,14,buff);
	return 1;

}

int	updateAnaIns(_mSlaves *Slave)
{
	char buff[100];  
	sprintf(buff,"%5.2f       %5.2f        %5.2f      %5.2f",
			 			Slave ->anaInShadow[0],
			 			Slave ->anaInShadow[1],
			 			Slave ->anaInShadow[2],
			 			Slave ->anaInShadow[3]
			 			);           
	DispStr(20,18,buff);
	return 1;	

}


main ()
{

	brdInit();
	memset (mSlaves,0x00,sizeof(mSlaves) );	
#if (MODBUS_PROTOCOL)
	mmrDinit(MODBUS_BAUDRATE);  
#else
	mmaDinit(MODBUS_BAUDRATE);  
#endif
	// Set the Slave address 
	mSlaves[1].addr = 1;
	// display the title screen
	DispStr(20,2,"      MODBUS MASTER SAMPLE PROGRAM");
	DispStr(20,4," CHAN        CHAN        CHAN       CHAN");
	DispStr(20,5," 0            1           2          3  ");  
	DispStr(20,6,"----------------------------------------");
	
	DispStr(20,8,"             DIGITAL OUTPUTS          ");
	DispStr(20,9,"----------------------------------------");
	
	DispStr(20,12,"             DIGITAL INPUTS          ");  
	DispStr(20,13,"---------------------------------------");
	
	DispStr(20,16,"             ANALOG INPUTS          ");    
	DispStr(20,17,"---------------------------------------"); 
	
	for (;;)
	{
		costate
		{
			// Write to the output coils
			waitfor( writeOutputs(&mSlaves[1])); 
			// Write to the analog output channels
			waitfor( writeAnaOut(&mSlaves[1]));      
			// Read the output coil status
		 	waitfor( readOutputs(&mSlaves[1]));
			// Read the input status
		 	waitfor( readInputs(&mSlaves[1]));
			// Read the analog input channels
		 	waitfor( readAnaInputs(&mSlaves[1]));
			// Display the output status
		 	waitfor( updateOutputs(&mSlaves[1]));     
			// Display the input status
		 	waitfor( updateInputs(&mSlaves[1]));
			// Display the analog input status
		 	waitfor( updateAnaIns(&mSlaves[1]));     
		 	
		}
		
	}
}

⌨️ 快捷键说明

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