📄 mb_mst.c
字号:
Parameters:
port : serial port 0:Ext 1:COM port of SC12/SC13
baud : baudrate
parity : uart parity 0: None 1: Odd 2: Even
serial_mode : 0: RS232 with RTS/CTS flow 1: RS232 no flowctrl 2: RS485
Return 0 : sucess
-1: failed
*******************************************************************************/
int mb_ser_init(int port,
long baud,
int parity,
unsigned char serial_mode)
{
if(0x1954!=fossil_init(port))
{
return MB_ERROR;
}
if(-1==fossil_setbaud(port,baud,parity,8,1))
{
return MB_ERROR;
}
switch(serial_mode)
{
case MB_RS485:
fossil_set_rs485(port, FOSSIL_RS485_HIGHACTIVE);
rs485=1; //set flag
break;
case MB_RS232_HWFLOW:
fossil_set_flowcontrol (port, FOSSIL_FLOWCTRL_RTSCTS );
break;
}
/* Calculate the silent_interval
Please note: The modbus serial specification recommends a max. time interval
of 1.5 chars between two incoming bytes inside of frame, without defining
a tolerance of this interval. Without a very high expense (e.g. hardware timer 0),
it is not possible to measure exactly 1,5 chars time interval:
Because of this behaviour, we set fixed approximated silent_intervals in
dependency of the configured baudrate.
*/
switch(baudrate)
{
case 300: silent_interval = 40; //ms
break;
case 600: silent_interval = 20; //ms
break;
case 1200: silent_interval = 10; //ms
break;
case 2400: silent_interval = 5; //ms
break;
case 4800: silent_interval = 3; //ms
break;
default: silent_interval = 2; //ms
break;
}
frame_wait_interval = silent_interval *2;
return NO_ERROR;
}
/*******************************************************************************
DeInit serial port
Shall be called the end of application
Parameter:
port 0:Ext 1:COM port of SC12/SC13
********************************************************************************/
void mb_ser_deinit(int port)
{
fossil_deinit (port );
}
/***********************************************************************************
Send a "write multiple holding registers" request 10h, and receive reply from slave
Parameters:
slave_addr : input, slave address
start_address : input, address of first register
quantity : input, number of registers to change
register_data : input, user provided storage, contains register values to write
timeout : input, wait max. timeout ms for reply from slave
exception : output, contains after execution the possible occured
exception code or 0, if no exception has occured
Return 0 : Sucessful, *exception has value 0 or exception code (see modbus.h)
Return -1 : Communication error timeout
************************************************************************************/
int mb_ser_req_wr_holding_regs( unsigned char slave_addr,
unsigned int start_address,
unsigned int quantity,
unsigned int * register_data,
unsigned char * exception,
unsigned int timeout
)
{
unsigned int checksum,i,bufindex;
unsigned char buf[MB_SER_MAX_BUF];
#ifdef MB_SER_DEBUG
printf("\r\nRequest Write multiple holding registers, Code 0x10, Start %d, Quantity %d"
,start_address,quantity);
#endif
//assume no exception
*exception=0;
buf[0]=slave_addr; //set slave address
buf[1]=MB_WR_MULTIPLE_REG; //insert function code
buf[2]=(unsigned char)(start_address>>8); //Start address hi/lo
buf[3]=(unsigned char)start_address;
buf[4]=(unsigned char)(quantity>>8); //Quantity hi/lo
buf[5]=(unsigned char)(quantity);
buf[6]=(unsigned char)(quantity<<1); //no of byte (quantity*2)
for(i=0,bufindex=7;i<quantity;i++,bufindex+=2)//write register data into frame
{
buf[bufindex] =(unsigned char)(register_data[i]>>8); //hi
buf[bufindex+1]=(unsigned char)(register_data[i]); //lo
}
//append crc
checksum=CRC16(buf,bufindex);
buf[bufindex++]= (unsigned char)(checksum>>8); //hi
buf[bufindex] = (unsigned char)(checksum); //lo
#ifdef MB_PRINT_FRAME
print_mb_frame("Sending ",buf,bufindex+1);
#endif
//Send the frame
if(MB_ERROR==mb_ser_send(buf,bufindex+1))
{
#ifdef MB_SER_DEBUG
printf("\r\nSend failed");
#endif
return MB_ERROR;
}
//Receive reply
if(MB_ERROR == mb_ser_recv_frame(buf,8,timeout))
{
#ifdef MB_SER_DEBUG
printf("\r\nReceive failed");
#endif
return MB_ERROR;
}
//got an exception?
if(buf[1] & 0x80)
{
*exception = buf[2]; //take exception code frame reply frame
}
return MB_NO_ERROR;
}
/******************************************************************************
Send a "write single holding register" request 6 and receive reply from slave
Parameters:
slave_addr : input, slave address
start_address : input, address of first register
register_data : input, 16 bit value to write
timeout : input, wait max. timeout ms for reply from slave
exception : output, contains after execution the possible occured exception code
or 0 , if no exception has occured
Return 0 : Sucessful, *exception has value 0 or exception code (see modbus.h)
Return -1 : Communication error timeout
*******************************************************************************/
int mb_ser_req_wr_single_reg ( unsigned char slave_addr,
unsigned int start_address,
unsigned int register_data,
unsigned char * exception,
unsigned int timeout
)
{
unsigned int checksum;
unsigned char buf[MB_SER_MAX_BUF];
#ifdef MB_SER_DEBUG
printf("\r\nRequest Write single holding register, Code 6, Start %d, value %d"
,start_address,register_data);
#endif
*exception=0; //assume no exception
buf[0]=slave_addr; //set slave address
buf[1]=MB_WR_SINGLE_REG; //insert function code
buf[2]=(unsigned char)(start_address>>8); //Start address
buf[3]=(unsigned char)start_address;
buf[4]= (unsigned char)(register_data>>8);//register data
buf[5]= (unsigned char)(register_data);
//append crc
checksum=CRC16(buf,6);
buf[6] = (unsigned char)(checksum>>8); //hi
buf[7] = (unsigned char)(checksum); //lo
#ifdef MB_PRINT_FRAME
print_mb_frame("Sending ",buf,8);
#endif
//Send the frame
if(MB_ERROR==mb_ser_send(buf,8))
{
#ifdef MB_SER_DEBUG
printf("\r\nSend failed");
#endif
return MB_ERROR;
}
//Receive reply
if(MB_ERROR == mb_ser_recv_frame(buf,8,timeout))
{
#ifdef MB_SER_DEBUG
printf("\r\nReceive failed");
#endif
return MB_ERROR;
}
//got an exception?
if(buf[1] & 0x80)
{
*exception = buf[2]; //take exception code frame reply frame
}
return MB_NO_ERROR;
}
/******************************************************************************
Send a "write single coil" request 5 and receive reply from slave
Parameters:
slave_addr : input, slave address
start_address : input, address of first register
coil : input, bit value to write (coil==0x00: value OFF, else ON)
exception : output, contains after execution the possible occured exception code
or 0 , if no exception has occured
timeout : input, wait max. timeout ms for reply from slave
Return 0 : Sucessful, *exception has value 0 or exception code (see modbus.h)
Return -1 : Communication error timeout
*******************************************************************************/
int mb_ser_req_wr_single_coil ( unsigned char slave_addr,
unsigned int start_address,
unsigned char coil,
unsigned char * exception,
unsigned int timeout
)
{
unsigned int checksum;
unsigned char buf[MB_SER_MAX_BUF];
#ifdef MB_SER_DEBUG
printf("\r\nRequest Write single coil, Code 5: Start %d , value %02X"
,start_address,coil);
#endif
*exception=0; //assume no exception
buf[0]=slave_addr; //set slave address
buf[1]=MB_FORCE_SINGLE_COIL; //insert function code
buf[2]=(unsigned char)(start_address>>8); //Start address
buf[3]=(unsigned char)start_address;
buf[4]=(coil!=0)?0xFF:0x00; //coil value 0xFF00 or 0x0000
buf[5]=0x00;
//append crc
checksum=CRC16(buf,6);
buf[6] = (unsigned char)(checksum>>8); //hi
buf[7] = (unsigned char)(checksum); //lo
#ifdef MB_PRINT_FRAME
print_mb_frame("Sending ",buf,8);
#endif
//Send the frame
if(MB_ERROR==mb_ser_send(buf,8))
{
#ifdef MB_SER_DEBUG
printf("\r\nSend failed");
#endif
return MB_ERROR;
}
//Receive reply
if(MB_ERROR == mb_ser_recv_frame(buf,8,timeout))
{
#ifdef MB_SER_DEBUG
printf("\r\nReceive failed");
#endif
return MB_ERROR;
}
//got an exception?
if(buf[1] & 0x80)
{
*exception = buf[2]; //take exception code from reply frame
}
return MB_NO_ERROR;
}
/******************************************************************************
Send a "read coils" (01) or "read discrete input" (02) request
and receive reply from slave
Parameters:
slave_addr : input, slave address
function_code : input, function code 0x01 or 0x02
quantity : input, number of coils to read
start_address : input, address of first register
coils : output, buffer provided by user (required length: quantity)
after exectuion coils contains the bit values read from slave
coils[0] holds lowest bit value coils[quantity-1] holds highest bit value
coils[i]==0x00 means value OFF, coils[i]==0xFF means value ON
Buffer content is only valid if *exception==0!
exception : output, contains after execution the possible occured exception code
or 0 , if no exception has occured
timeout : input, wait max. timeout ms for reply from slave
Return 0 : Sucessful, *exception has value 0 or exception code (see modbus.h)
Return -1 : Communication error timeout
*******************************************************************************/
int mb_ser_req_rd_coils( unsigned char slave_addr,
unsigned char function_code, //01 or 02
unsigned int start_address,
unsigned int quantity,
unsigned char * coils,
unsigned char * exception,
unsigned int timeout
)
{
unsigned int checksum,i,shift;
unsigned int byte_count,buf_index;
unsigned char buf[MB_SER_MAX_BUF];
#ifdef MB_SER_DEBUG
printf("\r\nRequest Read bit values, Code %d, Start %d , Items %d"
,function_code,start_address,quantity);
#endif
*exception=0; //assume no exception
buf[0]=slave_addr; //set slave address
buf[1]= function_code; //insert function code
buf[2]=(unsigned char)(start_address>>8);//Start address
buf[3]=(unsigned char)start_address;
buf[4] = (unsigned char)(quantity>>8); //number of items
buf[5] = (unsigned char)(quantity);
//append crc
checksum=CRC16(buf,6);
buf[6] = (unsigned char)(checksum>>8); //hi
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -