📄 mb_mst.c
字号:
buf[7] = (unsigned char)(checksum); //lo
//PreSet coil buffer with 0
memset(coils,0,quantity);
#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
byte_count = quantity / 8;
if(0!=(quantity % 8))
{
byte_count++;
}
if(MB_ERROR == mb_ser_recv_frame(buf,byte_count+5,timeout)) //3 byte header + 2 byte CRC + bit data
{
#ifdef MB_SER_DEBUG
printf("\r\nReceive failed");
#endif
return MB_ERROR;
}
//got an exception?
if(buf[1] & 0x80)
{
*exception = buf[2];
return MB_NO_ERROR;
}
//Fill user provided coil buffer with values read
for(i=shift=0,buf_index=3;i<quantity;i++)
{
if( (buf[buf_index] >> shift++) & 0x01)
{
coils[i] =0xFF;
}
if(shift==8)
{
shift=0;
buf_index++;
}
}
return MB_NO_ERROR;
}
/******************************************************************************
Send a "write multiple coils" (0x0F) 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 coil
coils : input, buffer provided by user with length: quantity
the user must provide each coil value in one byte of coils.
coils[0] must hold the value for the lowest address.
coils[quantity-1] must hold the value for the lowest address
coils[i]==0x00 means: value OFF, else 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_wr_coils( unsigned char slave_addr,
unsigned int start_address,
unsigned int quantity,
unsigned char * coils,
unsigned char * exception,
unsigned int timeout
)
{
unsigned int checksum,i,shift,bufindex;
unsigned char buf[MB_SER_MAX_BUF];
unsigned int byte_count;
#ifdef MB_SER_DEBUG
printf("\r\nRequest Write bit values, Code 0x0F: Start %d , Items %d"
,start_address,quantity);
#endif
*exception=0; //assume no exception
buf[0]=slave_addr; //set slave address
buf[1]=MB_FORCE_MULTIPLE_COIL; //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);
byte_count=quantity/8;
if(quantity%8)
{
byte_count++;
}
buf[6]=(unsigned char)byte_count; //byte_count, quantity *2
//PreSet send buffer from data offset 7 to end with zeros
memset(&buf[7],0,byte_count);
for(i=shift=0,bufindex=7;i<quantity;i++)
{
if(coils[i])
{
buf[bufindex]|=1<<shift;
}
shift++;
if(shift==8)
{
bufindex++;
shift=0;
}
}
//append crc
checksum=CRC16(buf,7 + byte_count);
buf[7 + byte_count] = (unsigned char)(checksum>>8);
buf[7 + byte_count+ 1] = (unsigned char)(checksum);
#ifdef MB_PRINT_FRAME
print_mb_frame("Sending ",buf,7 + byte_count + 2);
#endif
//Send the frame
if(MB_ERROR==mb_ser_send(buf,7 + byte_count + 2))
{
#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 from reply frame
}
return MB_NO_ERROR;
}
/***********************************************************************************
Send a "read multiple registers" request 03h or "read input register" request 04,
and receive reply from slave
Parameters:
slave_addr : input, slave address
function_code : input, function code 0x03 or 0x04
quantity : input, number of registers to read
start_address : input, address of first register
register_data : output, 16 bit buffer provided by user with min. length: quantity
after execution, register_data contains the read register values
from slave (if *exception code==0)
register_data[0] == value of lowest register address,
register_data[quantity-1] holds highest register value.
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_regs( unsigned char slave_addr,
unsigned char function_code,
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 Read multiple registers 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 registers to read
buf[5]=(unsigned char)(quantity);
//append crc
checksum=CRC16(buf,6);
buf[6] = (unsigned char)(checksum>>8);
buf[7] = (unsigned char)(checksum);
#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,5 + quantity*2,timeout))
{
#ifdef MB_SER_DEBUG
printf("\r\nReceive failed");
#endif
return MB_ERROR;
}
//got an exception?
if(buf[1] & 0x80)
{
*exception = buf[2];
return MB_NO_ERROR;
}
//write received register data into user provided int buffer
for(i=0,bufindex=3;i<quantity;i++)
{
register_data[i]=((unsigned int)buf[bufindex]<<8) + (unsigned int)buf[bufindex+1];
bufindex+=2;
}
return MB_NO_ERROR;
}
/***********************************************************************************
Send a "read device identification request 0x2B,
and receive reply from slave
Parameters:
slave_addr : input, slave address
id_code : input, read device id code (01 or 02)
obj_id : input, object id
obj_data : output, field of buffers provided by user
after execution, obj_data contains the list of objects as null terminated strings
from slave (if *exception code==0)
The buffer array must provided by the user
max_single_obj_length: Max. storage length of an obj_data array
more : output, contains after execution value 0xFF (more follows) or 0x00
,if no exception has occured
how_many :output. contains the number of received objects
next_id : output, contains next object id if more==0xFF
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_dev_id ( unsigned char slave_addr,
unsigned char id_code,
unsigned char obj_id,
unsigned char *more,
unsigned char *next_id,
unsigned char *how_many,
unsigned char *obj_data[],
unsigned int max_single_obj_length,
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 Read device identification ID code %d, Obj_ID %d"
,id_code,obj_id);
#endif
*more =
*next_id =
*how_many =
*exception= 0; //assume no exception
buf[0] = slave_addr; //set slave address
buf[1] = MB_RD_DEV_IDENT; //insert function code
buf[2] = 0x0E; //MEI type
buf[3] = id_code;
buf[4] = obj_id;
//append crc
checksum=CRC16(buf,5);
buf[5] = (unsigned char)(checksum>>8);
buf[6] = (unsigned char)(checksum);
#ifdef MB_PRINT_FRAME
print_mb_frame("Sending ",buf,7);
#endif
//Send the frame
if(MB_ERROR==mb_ser_send(buf,7))
{
#ifdef MB_SER_DEBUG
printf("\r\nSend failed");
#endif
return MB_ERROR;
}
//Receive reply
if(MB_ERROR == mb_ser_recv_frame(buf,MB_SER_MAX_BUF,timeout))
{
#ifdef MB_SER_DEBUG
printf("\r\nReceive failed");
#endif
return MB_ERROR;
}
//got an exception?
if(buf[1] & 0x80)
{
*exception = buf[3];
return MB_NO_ERROR;
}
*how_many= buf[7]; //number of objects
*more = buf[5]; //more follows flag
*next_id = buf[6]; //next obj id, if *more==0xFF
//Fill received data into obj_data
bufindex = 8;
for(i=0;i<*how_many;i++)
{
//copy object value into user provided string array
memcpy(obj_data[i],&buf[bufindex+2],
buf[bufindex+1]<max_single_obj_length?buf[bufindex+1]:max_single_obj_length-1);
obj_data[i][buf[bufindex+1]]='\0'; //terminate by zero
bufindex+=buf[bufindex+1]+2; //point to next object
}
return MB_NO_ERROR;
}
//*****************************************************************************
//end of file
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -