📄 mb_slv.c
字号:
//************************************************************************
case MB_RD_COIL_STATE :
case MB_RD_DISCRETE_INP :
start_address = ((unsigned int)mb_request_buf[2] << 8)+(unsigned int)mb_request_buf[3];
quantity = ((unsigned int)mb_request_buf[4] << 8)+(unsigned int)mb_request_buf[5];
if(function_code==MB_RD_COIL_STATE)
{
//execute defined modbus device read coil operation
result = mb_read_coils(start_address,
quantity,
&byte_count,
&mb_response_buf[3]
);
}
else
{
//execute defined modbus device read discrete inputs operation
result = mb_read_discrete_inputs(start_address,
quantity,
&byte_count,
&mb_response_buf[3]
);
}
if(MB_NO_ERROR == result)
{
//success
mb_response_buf[2]=byte_count;
response_length += byte_count + 1;
}
break;
//************************************************************************
//Function code 0x05: Write coil
//************************************************************************
case MB_FORCE_SINGLE_COIL :
start_address = ((unsigned int)mb_request_buf[2] << 8)+(unsigned int)mb_request_buf[3];
//execute defined modbus device write coil operation
result = mb_write_coil_func(start_address, mb_request_buf[4]);
if(result == MB_NO_ERROR)
{
mb_response_buf[2] = mb_request_buf[2]; //address hi/lo
mb_response_buf[3] = mb_request_buf[3];
mb_response_buf[4] = mb_request_buf[4]; //output value
mb_response_buf[5] = 0;
response_length += 4;
}
break;
//************************************************************************
//Function code 0x0F: Write multiple coils
//************************************************************************
case MB_FORCE_MULTIPLE_COIL:
start_address = ((unsigned int)mb_request_buf[2] << 8)+(unsigned int)mb_request_buf[3];
quantity = ((unsigned int)mb_request_buf[4] << 8)+(unsigned int)mb_request_buf[5];
result = mb_write_multiple_coils(start_address,quantity,mb_request_buf[6],&mb_request_buf[7]);
if(result==MB_NO_ERROR)
{
mb_response_buf[2] = mb_request_buf[2]; //address hi/lo
mb_response_buf[3] = mb_request_buf[3];
mb_response_buf[4] = mb_request_buf[4]; //quantity
mb_response_buf[5] = mb_request_buf[5];
response_length += 4;
}
break;
//************************************************************************
//Function code 0x03,0x04: Read physical, holding registers
//************************************************************************
case MB_RD_HOLDING_REG :
case MB_RD_INPUT_REG :
start_address = ((unsigned int)mb_request_buf[2] << 8)+(unsigned int)mb_request_buf[3];
quantity = ((unsigned int)mb_request_buf[4] << 8)+(unsigned int)mb_request_buf[5];
if(function_code==MB_RD_HOLDING_REG)
{
result = mb_read_holding_registers(start_address,quantity,(unsigned int *)&mb_response_buf[3],&byte_count);
}
else
{
result = mb_read_input_registers(start_address,quantity,(unsigned int *)&mb_response_buf[3],&byte_count);
}
if(result==MB_NO_ERROR)
{
mb_response_buf[2] = byte_count;
response_length += byte_count + 1; //1 byte bytecount + values
}
break;
//************************************************************************
//Function code 0x06: Write single register
//************************************************************************
case MB_WR_SINGLE_REG :
start_address = ((unsigned int)mb_request_buf[2] << 8)+(unsigned int)mb_request_buf[3];
output_value = ((unsigned int)mb_request_buf[5] << 8)+(unsigned int)mb_request_buf[4];
result = mb_write_single_register(start_address, output_value);
if(result==MB_NO_ERROR)
{
mb_response_buf[2] = mb_request_buf[2]; //address hi/lo
mb_response_buf[3] = mb_request_buf[3];
mb_response_buf[4] = mb_request_buf[4]; //value
mb_response_buf[5] = mb_request_buf[5];
response_length += 4;
}
break;
//************************************************************************
//Function code 0x10: Write multiple contigous registers
//************************************************************************
case MB_WR_MULTIPLE_REG :
start_address = ((unsigned int)mb_request_buf[2] << 8)+(unsigned int)mb_request_buf[3];
quantity = ((unsigned int)mb_request_buf[4] << 8)+(unsigned int)mb_request_buf[5];
result = mb_write_multiple_registers(start_address,quantity,(unsigned int *)&mb_request_buf[7]);
if(result==MB_NO_ERROR)
{
mb_response_buf[2] = mb_request_buf[2]; //address hi/lo
mb_response_buf[3] = mb_request_buf[3];
mb_response_buf[4] = mb_request_buf[4]; //quantity
mb_response_buf[5] = mb_request_buf[5];
response_length += 4;
}
break;
case MB_RD_WR_HOLDING_REG:
//Not implemented yet
result = MB_ILLEGAL;
break;
//************************************************************************
//Function code 0x2B: Read device identification
//************************************************************************
case MB_RD_DEV_IDENT :
result = mb_read_device_ident(mb_request_buf[2], //MEI
mb_request_buf[3], //read device id code
mb_request_buf[4], //object id
&mb_response_buf[6], //object next
&mb_response_buf[7], //number of objects
&mb_response_buf[5], //more follows flag
&mb_response_buf[8], //start of object list buffer
&read_dev_id_length
);
mb_response_buf[2] = 0x0E; //MEI
if(result==MB_NO_ERROR)
{
mb_response_buf[4] = 0x02; //Set conformity level: regular
mb_response_buf[3] = mb_request_buf[3]; //read device code id
response_length += read_dev_id_length + 6; //list + 6 byte response header
}
else
{
mb_response_buf[1] |= 0x80; //or function code
mb_response_buf[3]=(unsigned char)result; //exception code
response_length++;
}
break;
//************************************************************************
// Unsupported function codes
//************************************************************************
default :result = MB_ILLEGAL; //illegal/unsupported function code
break;
}//switch(function_code)
if(result != MB_NO_ERROR)
{
if(function_code != MB_RD_DEV_IDENT)
{
mb_response_buf[1] |= 0x80; //or function code
//insert exception code (return value of modbus device function)
mb_response_buf[2] = (unsigned char)result;
}
response_length++;
}
//append crc
checksum=CRC16(mb_response_buf,response_length);
mb_response_buf[response_length++] = (unsigned char)(checksum>>8); //hi
mb_response_buf[response_length++] = (unsigned char)(checksum); //lo
#ifdef MB_SER_DEBUG
printf("\r\nmb_ser_request_process: Result %d Response length %d",result,response_length);
printf("\r\nSend Response: ");
for(i=0;i<response_length;i++)
{
printf(" %02X",mb_response_buf[i]);
}
#endif
//**************************
//send response
//**************************
return mb_ser_send(mb_response_buf, response_length);
}
//******************************************************************************
//Debug: Print a serial modbus frame
//******************************************************************************
#ifdef MB_SER_DEBUG
void print_mb_frame(char * msg, unsigned char * buf, int length)
{
int i;
printf("\r\n%s frame with length %d\r\n",msg,length);
for(i=0;i<length;i++)
{
printf("%02X ",buf[i]);
}
RTX_Sleep_Time(50);
}
#endif
/******************************************************************************
modbus rtu slave main process loop
******************************************************************************/
void main(int argc, char *argv[])
{
//*********************************************
//Check program serial modbus slave parameters
//*********************************************
if(0!=parse_args(argc,argv))
{
usage();
return;
}
printf("\r\nModbus slave running\r\n"
"Port %1d Address %d Baudrate %lu Parity %d Mode %d",
port,slave_address,baudrate,parity,serial_mode);
//*********************************************
//Init serial port
//*********************************************
if(MB_ERROR==mb_ser_init(port,baudrate,parity,serial_mode))
{
printf("\r\nError: Cannot initialize serial port");
return;
}
//*********************************************
//init modbus device
//*********************************************
if(MB_NO_ERROR!=mb_dev_init())
{
printf("\r\nModbus slave device init failed");
return;
}
//*********************************************
//Main process loop
//*********************************************
while(1)
{
/*******************************************************************/
//Wait for incoming modbus requests from client
/*******************************************************************/
if(MB_NO_ERROR==mb_ser_recv_frame(mb_ser_request_buf))
{
/*******************************************************************/
//Process request
/*******************************************************************/
mb_ser_process_request(mb_ser_request_buf, mb_ser_response_buf);
}
}
}
//------------------------------------------------------------------------------
//end of file
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -