|
|
View previous topic :: View next topic |
Author |
Message |
paddy
Joined: 04 Nov 2012 Posts: 15
|
Writing multiple registers function in modbus |
Posted: Fri Jan 11, 2013 4:34 am |
|
|
Hello All,
I am using modbus_slave.c example file in which i am using FUNC_WRITE_MULTIPLE_REGISTERS.
It works fine when i am writing data from starting address 0001. But when i change it with some another address, it will not work. I am not able to write data on other address except 0001.
Please have a look and suggest what i need to do.
Thanks
Code: |
case FUNC_WRITE_MULTIPLE_REGISTERS:
if(modbus_rx.data[0] || modbus_rx.data[2] ||
modbus_rx.data[1] >= 122 || modbus_rx.data[3]+modbus_rx.data[1] > 122)
modbus_exception_rsp(MODBUS_ADDRESS,modbus_rx.func,ILLEGAL_DATA_ADDRESS);
else
{
int i,j;
int8 k;
k=modbus_rx.data[1];
//for(i=0,j=5; i < modbus_rx.data[4]/2; ++i,j+=2)
for(i=k,j=5; i < modbus_rx.data[4]/2; ++i,j+=2)
hold_regs[i] = make16(modbus_rx.data[j+1],modbus_rx.data[j]);
modbus_write_multiple_registers_rsp(MODBUS_ADDRESS,
make16(modbus_rx.data[0],modbus_rx.data[1]),
make16(modbus_rx.data[2],modbus_rx.data[3]));
event_count++;
}
break;
|
|
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Fri Jan 11, 2013 7:03 am |
|
|
There's a problem in your register writing loop:
Code: |
k=modbus_rx.data[1];
//for(i=0,j=5; i < modbus_rx.data[4]/2; ++i,j+=2)
for(i=k,j=5; i < modbus_rx.data[4]/2; ++i,j+=2)
hold_regs[i] = make16(modbus_rx.data[j+1],modbus_rx.data[j]);
|
As modbus_rx.data[4] is the count of data bytes in the message, i.e. twice the number of registers, you can't use it in that way as the end condition of the loop. Instead do:
Code: |
k=modbus_rx.data[1];
for(i=0,j=5; i < modbus_rx.data[4]/2; ++i,j+=2)
hold_regs[k + i] = make16(modbus_rx.data[j+1],modbus_rx.data[j]);
|
This is limited to 128 registers and they mus all fall inside the 0-255 register address range.
In my implementation of this function I don't have all registers as "real" registers in the hold_regs array. For read, I have sixteen scratch, i.e. temporary, registers and send them to an virtualisation/abstraction routine that collects the data to the correct parts of my code. For write I simply send each register value in turn to my virtualisation routine.
Code: |
// Data is big endian.
for(i=0,j=5; i < modbus_rx.data[4]/2; ++i,j+=2)
Write_Register(k + i, make16(modbus_rx.data[j],modbus_rx.data[j+1]));
|
This limits the number of registers that can be read in one message to the number of scratch registers.
RF Developer |
|
|
paddy
Joined: 04 Nov 2012 Posts: 15
|
|
Posted: Sat Jan 12, 2013 4:34 am |
|
|
Yes!!! It worked!!!!
Thanks for your kind support. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|