|
|
View previous topic :: View next topic |
Author |
Message |
khalis
Joined: 12 Feb 2009 Posts: 54
|
Modbus (Procedures to decide the addresses of input etc) |
Posted: Wed Feb 18, 2009 8:38 pm |
|
|
Hi,
I have been studied the given example in pic c compiler - master.c, slave.c and modbus.c ... can someone explain a little bit about on how to manipulate crc table and how we define the input registers, coils register..etc...
Thanks |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Thu Feb 19, 2009 4:05 am |
|
|
Why do you want to manipulate the CRC table? The polynomial is fixed by the MODBUS standard.
The address usage in the master example is obvious, I think, cause it's a parameter in the respective functions.
The slave example has a very simple address scheme, possibly not sufficient for a real application. But I think, you are able to see, that for each function code supported by the example, a comparison of the incoming packet's address field is performed, requiring a zero address high byte. You may want to use a conversion to a 16 Bit address and length in your code before, e. g.
Code: | addr = make16(modbus_rx.data[0],modbus_rx.data[1]);
cnt = make16(modbus_rx.data[2],modbus_rx.data[3]); |
|
|
|
khalis
Joined: 12 Feb 2009 Posts: 54
|
|
Posted: Thu Feb 19, 2009 7:02 pm |
|
|
Sorry about the CRC. It was my first thought when I saw that crc table. I thought it was some kind of memory map that we would used to store our data but I was wrong about that.
In modbus slave.c example there were codes that made took times to figure it out.
first
Code: |
if(modbus_rx.data[0] || modbus_rx.data[2] ||
modbus_rx.data[1] >= 8 || modbus_rx.data[3] +
modbus_rx.data[1] > 8)
modbus_exception_rsp(MODBUS_ADDRESS, modbus_rx.func,
ILLEGAL_DATA_ADDRESS); |
second
Code: | modbus_read_holding_registers_rsp(MODBUS_ADDRESS,(modbus_rx.data[3]*2),hold_regs+modbus_rx.data[1]); |
Besides that, I like to create like (40001 - 40008) for input status and (40009 - 40017) for output status. It is possible?
I need your explanation. Thanks |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Fri Feb 20, 2009 1:26 am |
|
|
The problem is, that the author of ex_modbus_slave didn't spend the time to write a general handling of 16-Bit register addresses. So the examples uses the low byte of the address field as address. I give you an example, how a 16-Bit address handling can look like (with the previous shown calculation of addr and cnt) :
Code: | case FUNC_READ_HOLDING_REGISTERS:
if(addr >= ADDR_H || addr+cnt > ADDR_H || !cnt || cnt > 125)
modbus_exception_rsp(MODBUS_ADDRESS,modbus_rx.func,ILLEGAL_DATA_ADDRESS);
else
{
modbus_serial_send_start(MODBUS_ADDRESS, modbus_rx.func);
modbus_serial_putc(2*cnt);
for (i=0;i<cnt;i++,addr++)
{
data = get_db_val(addr);
modbus_serial_putc(make8(data, 1));
modbus_serial_putc(make8(data, 0));
}
modbus_serial_send_stop();
event_count++;
}
break; |
In this application, the complete register address range of 0 to ADDR_H is accepted by the slave, however it's mapped to internal data storage by get_db_val(), and it's returning meaningful data only for known addresses and zero for others. You may want to assert an exception for each undefined address, but I think, it's not necessary on read. |
|
|
|
|
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
|