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

📄 msbl21xx.c

📁 modbus 运用事例
💻 C
📖 第 1 页 / 共 2 页
字号:
			0x00001 -> 	0x00016 (Digital Output 0 -> Digital Output 15)    
		 
\*=========================================================================*/

int msOutWr(unsigned wCoil, int bState)
{
	//  Check to see if a valid output channel is being called.  
	if ( wCoil > (OUTPUT_AMOUNT) )	return MS_BADADDR;
	//  update the shadow used in the msOutRd function.
	acShad[wCoil] = bState;
	// Update the digital outpu;
	digOut(wCoil,bState);
	return 0;
}

/*=========================================================================*\
	msIn:	(02:	Discrete Input Status)
		Used for reading the state of the individual digital inputs.
		
	  registers used;	   
	 		0x10001 -> 	0x10024 (Digital Input 0 -> Digital Input 23) 
	 			   
\*=========================================================================*/

int msIn(unsigned wCoil, int *pnState)
{
	//  Check to see if a valid input channel is being called.    
	if (wCoil > INPUT_AMOUNT)	return MS_BADADDR;
	//  Read the input and store it.
	*pnState = digIn(wCoil);
	return 0;
}

/*=========================================================================*\
	msInput:	(04:	Reading from a Input Register)  
		   
		For reading the individual CALIBRATED values of each adc inputs.
		Since Modbus deals with unsigned ints (words), and our VDC input
		function returns a float, the function will need to store the value
		as two registers type casted into unsigned ints for the Modbus 
		protocol to accept properly.  How this is done must be the same for
		both the Master and the slave.  This example shows one way to 
		accomplish that.  The Master must use the same method for decoding
		the two unsigned ints and convert it back to a float.  A sample of
		this is the msWrite function that converts 2 unsigned ints into a
		float for use with the DAC outputs.
		
		registers used;
		  	0x30001 -> 0x30002 = Float val of ADC 0    
			0x30003 -> 0x30004 = Float val of ADC 1  
			0x30005 -> 0x30006 = Float val of ADC 2  
			0x30007 -> 0x30008 = Float val of ADC 3  
			0x30009 -> 0x30010 = Float val of ADC 4    
			0x30011 -> 0x30012 = Float val of ADC 5  
			0x30013 -> 0x30014 = Float val of ADC 6  
			0x30015 -> 0x30016 = Float val of ADC 7  
			0x30017 -> 0x30018 = Float val of ADC 8  
			0x30019 -> 0x30020 = Float val of ADC 9  
			0x30021 -> 0x30022 = Float val of ADC 10 
		    
\*=========================================================================*/

int msInput(unsigned wReg, unsigned *pwValue)
{
	static float calVal;
	static unsigned int  uiVal[2];
	// Since it will take two registers per input, you must double the 
	// amount of register neccessary.
	if (wReg > (ADC_AMOUNT * 2) )	return MS_BADADDR;
	
	// if the input is odd the get the new adc value
	if ( !(wReg % 2) )
	{
  		// You must divide the wReg value by 2 when getting the proper channel	
		calVal = anaInVolts(wReg/2);    
		// move the adc float value int a holding array of 4 bytes
		*(float *) & uiVal[0] = calVal;
		// copy the first 2 bytes of the holding array into the register value
		*pwValue = uiVal[0];    
	}
	// if the register is even
	else
	{
		// copy the last 2 bytes of the holding array into the register value.
		// DO NOT recalculate the input value.
		*pwValue = uiVal[1];	   
	}
	return 0;
}

/*=========================================================================*\
	msWrite:	(03:	Writing to Holding Registers)  
		   
		Will write to the DAC channels (0-3)  This function will take a
		converted float valued (from 2 unsigned int  values) and update the
		DAC output values (in Volts 0-10VDC).  It also will update the 
		analog output shadow register aoShad[analog output] used in the
		msRead function.
		
		registers used;
			0x40001 -> 0x40002 = Float val for DAC 0
			0x40003 -> 0x40004 = Float val for DAC 1  
			0x40005 -> 0x40006 = Float val for DAC 2 
			0x40007 -> 0x40008 = Float val for DAC 0 
		
\*=========================================================================*/

nodebug
int msWrite(unsigned wReg, unsigned wValue)
{
	static unsigned int uiVal[2];
	static float fVal;
	if (wReg > (DAC_AMOUNT * 2) )	return MS_BADADDR;
	// Will store the first of the register pairs starting with the odd number  
	if ( !(wReg % 2) )  
	{
	  	uiVal[0] = wValue;
 	}
	// if the register is even
	else
	{
		
		// store the next register value
 		uiVal[1] = wValue;   
 		// typecast the two stored values and save it as a float value.
		fVal = 	* (float *) &uiVal[0];    
		if (fVal <= MAX_DAC_VOLTS)
		{
			// update the new analog output value.
 			anaOutVolts(wReg/2, fVal);
 			// store the new updated value into its shadow register.
			aoShad[wReg/2] = fVal;
		}
		else return MS_BADDATA;    
	} 
	return 0;
}

/*=========================================================================*\
	msRead:	(03:	Reading Holding Registers)
		Will read the DAC channels shadow register value.  
		
		The Data being sent comes from the shadow registers that are being
		updated by msWrite.
		
		registers used;
			0x40001 -> 0x40002 		float value of DAC channel 0
			0x40003 -> 0x40004		float value of DAC channel 1   
			0x40005 -> 0x40006		float value of DAC channel 2   
			0x40007 -> 0x40008		float value of DAC channel 3     

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

int msRead (unsigned wReg, unsigned *pwValue)
{
	static unsigned int  uiVal[2];
	// Since it will take two registers per input, you must double the 
	// amount of register neccessary.
	if (wReg > (DAC_AMOUNT * 2) )	return MS_BADADDR;
	
	
	if ( !(wReg % 2) )
	{
  		// copy the first 2 bytes of the holding array into the register value
		*(float *) & uiVal[0] = aoShad[wReg/2];    
		*pwValue = uiVal[0];    
	}
	// if the register is even
	else
	{
		// copy the last 2 bytes of the holding array into the register value.
		*pwValue = uiVal[1];	 
 	}
	return 0;	
}


/******************* End of Modbus Functions  ******************************/


/******************* Main Function *****************************************\

	Basic setup of the controller.  Once Modbus is setup, a call to msRun()
	needs to be called continually called.  Other functionalities can be
	added as long as they do not block. (i.e while loops for loops etc.).

\***************************************************************************/

void main(void)
{
	auto int loop;
	// Clear the output shadow arrays at startup of this sample
	memset(acShad, 0, sizeof(acShad));	
	memset(aoShad, 0, sizeof(aoShad));
		  
	// initialize the SBC
	brdInit();
	// initializing the outputs to be Sourcing.
	digOutConfig(0xFFFF);
	
#if	(!MODBUS_TYPE)	 
	// Open Serial port D in ASCII mode 
	msaDinit(SLAVE_ADDRESS, MODBUS_BAUDRATE);
#else
	// Open Serial port D in RTU mode
	msrDinit(SLAVE_ADDRESS, MODBUS_BAUDRATE);  
#endif

	// If there are analog inputs required, get the cal. constants from the
	// eeprom.
	
	if (ADC_AMOUNT > 0 )
	{
		// read in the cal. constants.    
		for (loop = 0 ; loop < ADC_AMOUNT ; loop++) anaInEERd(loop);    
	}
	
	// If there are analog outputs required, get the cal. constants from the  
	// eeprom.
	
	if (DAC_AMOUNT > 0 )  
	{
		// read in the cal. constants.    
		for (loop = 0 ; loop < DAC_AMOUNT ; loop++) anaOutEERd(loop);    
	}
	 
	for( ;; )								
	{
 		// Modbus slave handler function.  It must be in a continous loop.
		msRun();     
		//	Other Costates Here!!! (Make sure your code does not block.)
	}
}

⌨️ 快捷键说明

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