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

📄 mbserial.c

📁 485串行通讯
💻 C
📖 第 1 页 / 共 3 页
字号:
  @brief	get PDU part from ADU data
  @param	buf		output buffer
  @param	adu		ADU data with error check code
  @param	len		length of the adu data
  @return	the length of PDU data
 */
/*---------------------------------------------------------------------------*/
int	MBSerialGetPDU( u8 *buf, u8 *adu, int len)
{
	return MBGetPDU( buf, adu, len);
}

/*---------------------------------------------------------------------------*/
/**
  @brief	set serial port mode for RS232/RS422/RS485
  @param	port		port number
  @param	mode		serial port mode
		{RS232_MODE/RS485_2WIRE_MODE/RS422_MODE/RS485_4WIRE_MODE}
  @return	return MB_OK for success, on error return error code
 */
/*---------------------------------------------------------------------------*/
int     MBSerialSetMode( int port, unsigned int mode)
{
	int ret= SerialSetMode( port, mode);

	if( ret <= 0)
		return MB_OK;

	return MB_ERROR_MODE;
}

/*---------------------------------------------------------------------------*/
/**
  @brief	set serial speed and make changes now
  @param	port		port number
  @param	speed		unsigned integer for new speed
  @return	return SERIAL_OK for success, on error return error code
 */
/*---------------------------------------------------------------------------*/
int	MBSerialSetSpeed( int port, unsigned int speed)
{
	return SerialSetSpeed( port, speed);
}

/* Modbus master function */
/*---------------------------------------------------------------------------*/
/**
  @brief	send Read Decrete Inputs request and get response(0x02)
  @param	port		which port to use
  @param	address		slave device address
  @param	startdec	starting decrete inputs register number
  @param	no		number of registers, between 1 ~ 2000
  @param	value		registers status slave returned
  @return	number of status bytes, on error return error code
 */
/*---------------------------------------------------------------------------*/
int	MBSerialReadDecreteInputs(int port, u8 address, u16 startdec, u16 no, u8 *value)
{
	u8 adu[ MB_ASCII_ADU_MAX_LENGTH], pdu[ MAX_BUFFER_SIZE];
	int pdu_len= 0, adu_len= 0, ret= 0;
	u8 ret_no;

	pdu_len= MBReadDecreteInputs( pdu, startdec, no);	///< make PDU

	adu_len= MBSerialSendAndWaitResponse( port, adu, pdu, pdu_len, address);

	if( adu_len < 0)
		return adu_len;

	pdu_len= MBGetPDU( pdu, adu, adu_len);
	ret= MBGetResponseReadDecreteInputs( pdu, &ret_no, value);
	if( ret < 0)
		return ret;
	return ret_no;
}

/*---------------------------------------------------------------------------*/
/**
  @brief	send Read Coils request and get response(0x01)
  @param	port		which port to use
  @param	address		slave device address
  @param	startcoils	starting coil register numbere
  @param	no		number of registers, between 1 ~ 2000
  @param	value		coils status slave returned
  @return	number of status bytes, on error return error code
 */
/*---------------------------------------------------------------------------*/
int	MBSerialReadCoils(int port, u8 address, u16 startcoils, u16 no, u8 *value)
{
	u8 adu[ MB_ASCII_ADU_MAX_LENGTH], pdu[ MAX_BUFFER_SIZE];
	int pdu_len= 0, adu_len= 0, ret= 0;
	u8 ret_no;

	pdu_len= MBReadCoils( pdu, startcoils, no);		///< make PDU

	adu_len= MBSerialSendAndWaitResponse( port, adu, pdu, pdu_len, address);

	if( adu_len < 0)
		return adu_len;

	pdu_len= MBGetPDU( pdu, adu, adu_len);
	ret= MBGetResponseReadCoils( pdu, &ret_no, value);
	if( ret < 0)
		return ret;
	return ret_no;
}

/*---------------------------------------------------------------------------*/
/**
  @brief	send Write Single Coil request and get response(0x05)
  @param	port		which port to use
  @param	address		slave device address
  @param	coilreg		coil register number
  @param	onoff		0xFF00 for on,0x0000 for off.
  @return	return MB_OK for success, on error return error code
 */
/*---------------------------------------------------------------------------*/
int	MBSerialWriteSingleCoil(int port, u8 address, u16 coilreg, u16 onoff)
{
	u8 adu[ MB_ASCII_ADU_MAX_LENGTH], pdu[ MAX_BUFFER_SIZE];
	int pdu_len= 0, adu_len= 0, ret= 0;
	u16 ret_addr, ret_value;

	pdu_len= MBWriteSingleCoil( pdu, coilreg, onoff);	///< make PDU

	adu_len= MBSerialSendAndWaitResponse( port, adu, pdu, pdu_len, address);

	if( adu_len < 0)
		return adu_len;

	pdu_len= MBGetPDU( pdu, adu, adu_len);
	ret= MBGetResponseWriteSingleCoil( pdu, &ret_addr, &ret_value);
	if( ret < 0)
		return ret;
	if( ( ret_addr != coilreg) || ( ret_value != onoff))
		return MB_ERROR_EXECPTION;
	return MB_OK;
}

/*---------------------------------------------------------------------------*/
/**
  @brief	send Write Multiple Coils request and get response(0x0F)
  @param	port		which port to use
  @param	address		slave device address
  @param	startcoils	starting coil register number
  @param	no		number of registers, between 1 ~ 2000
  @param	value		value to write
  @return	return MB_OK for success, on error return error code
 */
/*---------------------------------------------------------------------------*/
int	MBSerialWriteMultipleCoils(int port, u8 address, u16 startcoils, u16 no, u8 *value)
{
	u8 adu[ MB_ASCII_ADU_MAX_LENGTH], pdu[ MAX_BUFFER_SIZE];
	int pdu_len= 0, adu_len= 0, ret= 0;
	u16 count;
	u16 ret_addr, ret_value;

	count= (u8)no/8;
	if( count*8 < no)
		count++;

	/// make PDU
	pdu_len= MBWriteMultipleCoils( pdu, startcoils, no, count, value);

	adu_len= MBSerialSendAndWaitResponse( port, adu, pdu, pdu_len, address);

	if( adu_len < 0)
		return adu_len;

	pdu_len= MBGetPDU( pdu, adu, adu_len);
	ret= MBGetResponseWriteMultipleCoils( pdu, &ret_addr, &ret_value);
	if( ret < 0)
		return ret;
	if( ( ret_addr != startcoils) || ( ret_value != no))
		return MB_ERROR_EXECPTION;
	return MB_OK;
}

/*---------------------------------------------------------------------------*/
/**
  @brief	send Read Input Registers request and get response(0x04)
  @param	port		which port to use
  @param	address		slave device address
  @param	startreg	starting coil register number
  @param	no		number of registers, between 1 ~ 125
  @param	value		register status slave returned
  @return	number of registers for success, on error return error code
 */
/*---------------------------------------------------------------------------*/
int	MBSerialReadInputRegisters(int port, u8 address, u16 startreg, u16 no, u16 *value)
{
	u8 adu[ MB_ASCII_ADU_MAX_LENGTH], pdu[ MAX_BUFFER_SIZE];
	int pdu_len= 0, adu_len= 0, ret= 0;
	u8 ret_no;

	/// make PDU
	pdu_len= MBReadInputRegisters( pdu, startreg, no);

	adu_len= MBSerialSendAndWaitResponse( port, adu, pdu, pdu_len, address);

	if( adu_len < 0)
		return adu_len;

	pdu_len= MBGetPDU( pdu, adu, adu_len);
	ret= MBGetResponseReadInputRegisters( pdu, &ret_no, value);
	if( ret < 0)
		return ret;
	return ret_no;
}

/*---------------------------------------------------------------------------*/
/**
  @brief	send Read Holding Registers request and get response(0x03)
  @param	port		which port to use
  @param	address		slave device address
  @param	startreg	starting coil register number
  @param	no		number of registers, between 1 ~ 125
  @param	value		register status slave returned
  @return	number of registers for success, on error return error code
 */
/*---------------------------------------------------------------------------*/
int	MBSerialReadHoldingRegisters(int port, u8 address, u16 startreg, u16 no, u16 *value)
{
	u8 adu[ MB_ASCII_ADU_MAX_LENGTH], pdu[ MAX_BUFFER_SIZE];
	int pdu_len= 0, adu_len= 0, ret= 0;
	u8 ret_no;

	/// make PDU
	pdu_len= MBReadHoldingRegisters( pdu, startreg, no);

	adu_len= MBSerialSendAndWaitResponse( port, adu, pdu, pdu_len, address);

	if( adu_len < 0)
		return adu_len;

	pdu_len= MBGetPDU( pdu, adu, adu_len);
	ret= MBGetResponseReadHoldingRegisters( pdu, &ret_no, value);
	if( ret < 0)
		return ret;
	return ret_no;
}

/*---------------------------------------------------------------------------*/
/**
  @brief	send Write Single Register request and get response(0x06)
  @param	port		which port to use
  @param	address		slave device address
  @param	devicereg	register number
  @param	value		register status slave returned
  @return	MB_OK for success, on error return error code
 */
/*---------------------------------------------------------------------------*/
int	MBSerialWriteSingleRegister(int port, u8 address, u16 devicereg, u16 value)
{
	u8 adu[ MB_ASCII_ADU_MAX_LENGTH], pdu[ MAX_BUFFER_SIZE];
	int pdu_len= 0, adu_len= 0, ret= 0;
	u16 ret_addr, ret_value;

	/// make PDU
	pdu_len= MBWriteSingleRegister( pdu, devicereg, value);

	adu_len= MBSerialSendAndWaitResponse( port, adu, pdu, pdu_len, address);

	if( adu_len < 0)
		return adu_len;

	pdu_len= MBGetPDU( pdu, adu, adu_len);
	ret= MBGetResponseWriteSingleRegister( pdu, &ret_addr, &ret_value);
	if( ret < 0)
		return ret;
	if( ( ret_addr != devicereg) || ( ret_value != value))
		return MB_ERROR_EXECPTION;
	return MB_OK;
}

/*---------------------------------------------------------------------------*/
/**
  @brief	send Write Multiple Registers request and get response(0x10)
  @param	port		which port to use
  @param	address		slave device address
  @param	startdevreg	starting register number
  @param	noreg		number of registers, between 1 ~ 120
  @param	count		value counter
  @param	value		register status slave returned
  @return	MB_OK for success, on error return error code
 */
/*---------------------------------------------------------------------------*/
int	MBSerialWriteMultipleRegisters(int port, u8 address, u16 startdevreg, u16 noreg, u8 count, u16 *value)
{
	u8 adu[ MB_ASCII_ADU_MAX_LENGTH], pdu[ MAX_BUFFER_SIZE];
	int pdu_len= 0, adu_len= 0, ret= 0;
	u16 ret_addr, ret_value;

	/// make PDU
	pdu_len= MBWriteMultipleRegisters( pdu, startdevreg, noreg, count, value);		// make PDU

	adu_len= MBSerialSendAndWaitResponse( port, adu, pdu, pdu_len, address);

	if( adu_len < 0)
		return adu_len;

	pdu_len= MBGetPDU( pdu, adu, adu_len);
	ret= MBGetResponseWriteMultipleRegisters( pdu, &ret_addr, &ret_value);
	if( ret < 0)
		return ret;
	if( ( ret_addr != startdevreg) || ( ret_value != noreg))
		return MB_ERROR_EXECPTION;
	return MB_OK;
}

/*---------------------------------------------------------------------------*/
/**
  @brief	send Read Write Multiple Registers request and get response(0x17)
  @param	port		which port to use
  @param	address		slave device address
  @param	rsreg		starting register number to read
  @param	rno		number of registers ro read, between 1 ~ 120
  @param	rv		registers value slave returned
  @param	wsreg		starting register number to write
  @param	wno		number of registers ro write, between 1 ~ 120
  @param	count		value counter
  @param	wv		value to write
  @return	MB_OK for success, on error return error code
 */
/*---------------------------------------------------------------------------*/
int	MBSerialReadWriteMultipleRegisters(int port, u8 address, u16 rsreg, u16 rno, u16 *rv, u16 wsreg, u16 wno, u8 count, u16 *wv)
{
	u8 adu[ MB_ASCII_ADU_MAX_LENGTH], pdu[ MAX_BUFFER_SIZE];
	int pdu_len= 0, adu_len= 0, ret= 0;
	u8 ret_no;

	/// make PDU
	pdu_len= MBReadWriteMultipleRegisters( pdu, rsreg, rno, wsreg, wno, count, wv);		// make PDU

	adu_len= MBSerialSendAndWaitResponse( port, adu, pdu, pdu_len, address);

	if( adu_len < 0)
		return adu_len;

	pdu_len= MBGetPDU( pdu, adu, adu_len);
	ret= MBGetResponseReadWriteMultipleRegisters( pdu, (u8 *)&ret_no, wv);

	if( ret < 0)
		return ret;
	if( ret_no != rno*2)
		return MB_ERROR_EXECPTION;
	return MB_OK;
}

/*---------------------------------------------------------------------------*/
/**
  @brief	send Mask Write Register request and get response(0x16)
  @param	port		which port to use
  @param	address		slave device address
  @param	reg		register number
  @param	andmask		and mask
  @param	ormask		or mask
  @return	MB_OK for success, on error return error code
 */
/*---------------------------------------------------------------------------*/
int	MBSerialMaskWriteRegister(int port, u8 address, u16 reg, u16 andmask, u16 ormask)
{
	u8 adu[ MB_ASCII_ADU_MAX_LENGTH], pdu[ MAX_BUFFER_SIZE];
	int pdu_len= 0, adu_len= 0, ret= 0;
	u16 ret_reg, ret_and, ret_or;

	/// make PDU
	pdu_len= MBMaskWriteRegister( pdu, reg, andmask, ormask);

	adu_len= MBSerialSendAndWaitResponse( port, adu, pdu, pdu_len, address);

	if( adu_len < 0)
		return adu_len;

	pdu_len= MBGetPDU( pdu, adu, adu_len);
	ret= MBGetResponseMaskWriteRegister( pdu, &ret_reg, &ret_and, &ret_or);

	if( ret < 0)
		return ret;
	if( ( ret_reg != reg) || ( ret_and != andmask) || ( ret_or != ormask))
		return MB_ERROR_EXECPTION;
	return MB_OK;
}

/*---------------------------------------------------------------------------*/
/**
  @brief	send Read FIFO Queue request and get response(0x18)
  @param	port		which port to use
  @param	address		slave device address
  @param	FIFOAddr	FIFO address
  @param	FIFOCount	FIFO value buffer size(<=31)
  @param	FIFOValue	values of FIFO register
  @return	MB_OK for success, on error return error code
 */
/*---------------------------------------------------------------------------*/
int	MBSerialReadFIFOQueue(int port, u8 address, u16 FIFOAddr, u16 *FIFOCount, u16 *FIFOValue)
{
	u8 adu[ MB_ASCII_ADU_MAX_LENGTH], pdu[ MAX_BUFFER_SIZE];
	int pdu_len= 0, adu_len= 0, ret= 0;

	/// make PDU
	pdu_len= MBReadFIFOQueue( pdu, FIFOAddr);

	adu_len= MBSerialSendAndWaitResponse( port, adu, pdu, pdu_len, address);

	if( adu_len < 0)
		return adu_len;

	pdu_len= MBGetPDU( pdu, adu, adu_len);
	ret= MBGetResponseReadFIFOQueue( pdu, FIFOCount, FIFOValue);

	if( ret < 0)
		return ret;

	return MB_OK;
}

/* Modbus master function over serial only */
/*---------------------------------------------------------------------------*/
/**
  @brief	send Read Exception Status request and get response(0x07)
  @param	port		which port to use
  @param	address		slave device address
  @param	status		eight exception status in one byte
  @return	MB_OK for success, on error return error code
 */
/*---------------------------------------------------------------------------*/
int	MBSerialReadExceptionStatus(int port, u8 address, u8 *status)
{
	u8 adu[ MB_ASCII_ADU_MAX_LENGTH], pdu[ MAX_BUFFER_SIZE];
	int pdu_len= 0, adu_len= 0, ret= 0;

	/// make PDU
	pdu_len= MBReadExceptionStatus( pdu);

	adu_len= MBSerialSendAndWaitResponse( port, adu, pdu, pdu_len, address);

	if( adu_len < 0)
		return adu_len;

	pdu_len= MBGetPDU( pdu, adu, adu_len);
	ret= MBGetResponseReadExceptionStatus( pdu, status);

	if( ret < 0)
		return ret;

	return MB_OK;
}

/*---------------------------------------------------------------------------*/

⌨️ 快捷键说明

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