📄 mb_dev.c
字号:
memset(input_status,0,*byte_count);
for(i=shift=byte_count_tmp=0;i<number_of_inputs;i++)
{
retval = mb_read_discrete_inputs_func(start_address + i,&input_tmp);
if(retval == MB_NO_ERROR)
{
if(input_tmp)
{
input_status[byte_count_tmp]|= 1<<shift;
}
shift++;
if(shift==8)
{
byte_count_tmp++;
shift=0;
}
}
else
{
break;
}
}
//Enable interupts or release semaphore here, if they were used above the read loop
#ifdef MB_DEV_DEBUG
printf("\r\nRead discrete inputs: Return %d ",retval);
if(retval==MB_NO_ERROR)
{
printf("\r\nInput_status: ");
for(i=0;i<*byte_count;i++)
{
printf("%02X ",input_status[i]);
}
}
#endif
return retval;
}
/******************************************************************************
Bit access: Called if modbus function code == 0x0F
Handle a "write multiple coils" request (function code 0x0F)
Input parameters:
start_address Address of the first coil
number_of_coils Quantity of coils to write
byte_count quantity of outputs / 8 (+1 if reminader!=0)
outputs_value the provided storage outputs_value holds coil bit output values
in the order as described at the
"Modbus application protocol specification V1.1" from modbus.org
Return 0: sucessful, else errorcode (see modbus.h)
******************************************************************************/
#pragma argsused
int mb_write_multiple_coils(unsigned int start_address,
unsigned int number_of_coils,
unsigned char byte_count,
unsigned char * outputs_value)
{
int i,coil_idx,shift;
int retval;
#ifdef MB_DEV_DEBUG
printf("\r\nWrite multiple coils: start %d quantity %d",start_address, number_of_coils);
printf("\r\nOutputs: ");
for(i=0;i<number_of_coils;i++)
{
printf(" %04X",swap_int(outputs_value[i]));
}
#endif
/*
Write outputs_value bits to the device
If the application requires no interruption during the following write coil loop,
insert here semaphore protection or disable interrupts
*/
for(i=shift=coil_idx=0;i<number_of_coils;i++)
{
retval = mb_write_coil_func(start_address + i,(outputs_value[coil_idx]>>shift) & 0x01);
if(retval == MB_NO_ERROR)
{
shift++;
if(shift==8)
{
coil_idx++;
shift=0;
}
}
else
{
break;
}
}
//Enable interupts or release semaphores here, if they were used above the write loop
return retval;
}
/******************************************************************************
16 Bit access: called if modbus function code == 0x03
Handle a "read holding registers" request
Input parameters:
start_address : address of first register
number_of_regs : Quantity of registers to read
Return 0: sucessful , byte_count = number_of_regs * 2
the provided storage reg_value contains the read register values
else errorcode (see modbus.h)
******************************************************************************/
int mb_read_holding_registers(unsigned int start_address,
unsigned int number_of_regs,
unsigned int * reg_value,
unsigned char * byte_count)
{
int i;
int retval;
#ifdef MB_DEV_DEBUG
printf("\r\nRead holding registers: start %d quantity %d",start_address, number_of_regs);
#endif
/*
Read register values into the provided storage reg_value
If the application requires no interruption during the following write coil loop,
insert here semaphore protection or disable interrupts
*/
*byte_count=number_of_regs*2;
for(i=0;i<number_of_regs;i++)
{
retval = mb_read_holding_register_func(start_address + i,®_value[i]);
if(retval != MB_NO_ERROR)
{
break;
}
reg_value[i] = swap_int(reg_value[i]);
}
//Enable interupts or release semaphores here, if they were used above the write loop
#ifdef MB_DEV_DEBUG
printf("\r\nRead holding registers: retval %d",retval);
if(retval==MB_NO_ERROR)
{
printf("\r\nRegister values: ");
for(i=0;i<number_of_regs;i++)
{
printf(" %04X",reg_value[i]);
}
}
#endif
return retval;
}
/******************************************************************************
16 Bit access: called if modbus function code == 0x04
Handle a "read input registers" request
Input parameters:
start_address : address of first register
number_of_regs : Quantity of input registers to read
Return 0: sucessful , byte_count = number_of_regs * 2
the provided storage reg_value contains the read register values
else errorcode (see modbus.h)
******************************************************************************/
int mb_read_input_registers(unsigned int start_address,
unsigned int number_of_regs,
unsigned int * reg_value,
unsigned char * byte_count)
{
int i;
int retval;
#ifdef MB_DEV_DEBUG
printf("\r\nRead input registers: start %d quantity %d",start_address, number_of_regs);
#endif
/*
Read register values into the provided storage reg_value
If the application requires no interruption during the following write coil loop,
insert here semaphore protection or disable interrupts
*/
*byte_count=number_of_regs*2;
for(i=0;i<number_of_regs;i++)
{
retval = mb_read_input_register_func(start_address + i,®_value[i]);
if(retval != MB_NO_ERROR)
{
break;
}
reg_value[i] = swap_int(reg_value[i]);
}
//Enable interupts or release semaphores here, if they were used above the write loop
#ifdef MB_DEV_DEBUG
printf("\r\nRead input registers: retval %d",retval);
if(retval==MB_NO_ERROR)
{
printf("\r\nRegister values: ");
for(i=0;i<number_of_regs;i++)
{
printf(" %04X",reg_value[i]);
}
}
#endif
return retval;
}
/******************************************************************************
Handle a "write multiple registers" request (function code 0x10)
Input parameters:
start_address : address of first register
number_of_regs : Quantity of input registers to read
reg_values : Array which holds continuous the values to write
Return 0: sucessful
else errorcode (see modbus.h)
******************************************************************************/
int mb_write_multiple_registers(unsigned int start_address,
unsigned int number_of_regs,
unsigned int * reg_values
)
{
int i;
int retval;
#ifdef MB_DEV_DEBUG
printf("\r\nWrite multiple registers: start %d quantity %d",start_address, number_of_regs);
printf("\r\nOutputs: ");
for(i=0;i<number_of_regs;i++)
{
printf(" %04X", swap_int(reg_values[i]));
}
#endif
/*
Write register values from provided storage reg_values to the device
If the application requires no interruption during the following write coil loop,
insert here semaphore protection or disable interrupts
*/
for(i=0;i<number_of_regs;i++)
{
retval = mb_write_holding_register_func(start_address + i,swap_int(reg_values[i]));
if(retval != MB_NO_ERROR)
{
break;
}
}
//Enable interupts or release semaphores here, if they were used above the write loop
return retval;
}
/******************************************************************************
Handle a "write single register" request (function code 0x06)
Input parameters:
start_address : address of first register
number_of_regs : Quantity of input registers to read
reg_values : Array which holds continuous the values to write
Return 0: sucessful
else errorcode (see modbus.h)
******************************************************************************/
int mb_write_single_register(unsigned int address, unsigned int value)
{
#ifdef MB_DEV_DEBUG
printf("\r\nWrite single register: address %d value %04X",address, swap_int(value));
#endif
return mb_write_holding_register_func(address,swap_int(value));
}
/******************************************************************************
Handle a "read device identification" request (function code 0x2B)
Currently supported Read Dev Id code: 01 (basic identification)
Input parameters:
mei_type : MEI type always 0x0E(?)
id code s : Read device code id
object_id : ID of the first request object
Output parameters:
object_next: Contains after execution the id of thge nex object, if *more_follws==0xFF
more_follwos:If value after excution==0xFF, there are more object available
object_list: Storage contains after execution the listed objects, as specified at
Modbus Application Spec 1.1
object_list_length: Length of object_list
Return 0: sucessful
else errorcode (see modbus.h)
******************************************************************************/
int mb_read_device_ident(unsigned char mei_type,
unsigned char id_code,
unsigned char object_id,
unsigned char * object_next,
unsigned char * number_of_objects,
unsigned char * more_follows,
unsigned char * object_list,
unsigned char * object_list_length
)
{
int i, j;
unsigned char obj_length;
#ifdef MB_DEV_DEBUG
printf("\r\nRead device ident id_code: %d object_id %d",id_code, object_id);
#endif
//Check parameters
if(mei_type!=0x0E)
{
return MB_SERVER_FAILURE;
}
if(id_code<1||id_code>0x02)
{
return MB_ILL_DATA_VAL;
}
if( object_id > MB_DEV_OBJ_MAX_ID - 1 ||
( id_code == 0x01 && object_id != 0x00 ) ||
( id_code == 0x02 && object_id != 0x03 ) )
{
return MB_ILL_DATA_ADDR;
}
*more_follows =0;
*object_list_length =0; //size of MBAB + first data of response
*object_next =0;
*number_of_objects =0;
//run through object array and fill provided list buffer
if( id_code == 1 ) j = 0x03;
else j = MB_DEV_OBJ_MAX_ID;
for(i = object_id; i < j; i++)
{
obj_length = strlen(mb_object_id_table[i]);
if(*object_list_length < MB_TCP_MAX_BUF - (obj_length+14))
{
object_list[(*object_list_length)++]= i; //object id
object_list[(*object_list_length)++]= obj_length; //object lenght
strcpy((char *)&object_list[*object_list_length],mb_object_id_table[i]); //object value
*object_list_length += obj_length;
}
else //no more space avail at frame
{
*more_follows=0xFF;
*object_next = i+1;
break;
}
}
*number_of_objects = i-object_id;
#ifdef MB_DEV_DEBUG
printf("\r\nRead device ident objects: %d length: %d",i, *object_list_length);
#endif
return MB_NO_ERROR;
}
//******************************************************************************
//end of file
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -