📄 mbserial.c
字号:
@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 + -