View previous topic :: View next topic |
Author |
Message |
aroonkriss
Joined: 03 Dec 2012 Posts: 19 Location: kerala
|
modbus protocol |
Posted: Mon Dec 03, 2012 11:05 pm |
|
|
Hi all,
I am new in the embedded system coding. I have to implement a modbus slave system as part of a project. I have hard-coded the modbus request from master. I took the query from modbus protocol document PI_MBUS_300 for reading the holding register. Query is 06,03,00,6b,00,03.
I know what each field represents. I have doubts regarding the if statement in the following piece of code, especially
Code: | modbus_rx.data[1] >= 8 || modbus_rx.data[3]+modbus_rx.data[1] > 8)
|
why the data has been checked greater than 8.
Code: |
case FUNC_READ_HOLDING_REGISTERS:
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);
|
In the declaration part
Code: | int hold_regs[6] = {0x8800,0x7700,0x6600,0x5500,0x4400,0x3300};
int input_regs[10] = {0x1100,0x2200,0x3300,0x4400,0x5500,0x6600,0x7700,0x8800};
|
whenever I debug with the above mentioned data, the control goes to 'ILLEGAL data'.
please help me ASAP. _________________ I dream world peace |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Mon Dec 03, 2012 11:55 pm |
|
|
In the ex_modbus_slave example, there's no holding register 0x6b. I see that you can copy and paste from the
Modbus_Application_Protocol document. Next step is to understand the address range supported by the CCS
example code. |
|
|
aroonkriss
Joined: 03 Dec 2012 Posts: 19 Location: kerala
|
|
Posted: Tue Dec 04, 2012 2:00 am |
|
|
FvM wrote: | In the ex_modbus_slave example, there's no holding register 0x6b. I see that you can copy and paste from the
Modbus_Application_Protocol document. Next step is to understand the address range supported by the CCS
example code. |
Thank you Sir, for replying.. how could i find out the address range for each register group. please guide me _________________ I dream world peace |
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Tue Dec 04, 2012 2:13 am |
|
|
Why do you think the example had arrays of eight elements Which the code you show has had modified), and checked the address was between 0 and 7? The example only implements eight of each main data type. It, like all CCS supplied "drivers" and examples, is an example for you to try and then change and extend to meet your requirements.
I did exactly that on my own Modbus project, and it works well.
RF Developer |
|
|
aroonkriss
Joined: 03 Dec 2012 Posts: 19 Location: kerala
|
|
Posted: Tue Dec 04, 2012 3:22 am |
|
|
RF_Developer wrote: | Why do you think the example had arrays of eight elements Which the code you show has had modified), and checked the address was between 0 and 7? The example only implements eight of each main data type. It, like all CCS supplied "drivers" and examples, is an example for you to try and then change and extend to meet your requirements.
I did exactly that on my own Modbus project, and it works well.
RF Developer |
thank you for replying...
i just copied the code from one site and studying the flow of the program. i need to customize it according to my project need.
my doubt is how can i set a particular range of address for each register group? . So that i can check for the illegal address by comparing the hi and low byte of the address. please guide me _________________ I dream world peace |
|
|
aroonkriss
Joined: 03 Dec 2012 Posts: 19 Location: kerala
|
|
Posted: Tue Dec 04, 2012 9:47 pm |
|
|
Hi, anyone please guide me. How can I pre-set address for each register ?
Any help would be appreciated.
thank you _________________ I dream world peace |
|
|
aroonkriss
Joined: 03 Dec 2012 Posts: 19 Location: kerala
|
modbus protocol- register mapping |
Posted: Wed Dec 05, 2012 11:41 pm |
|
|
Hi,
Shall I program eeprom for storing the registers data so that I can query with the particular address where I have stored the data ? Or any other method to map particular address to holding reg and other regs. Please help me. I am stuck with this. Any help would be appreciated. _________________ I dream world peace |
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Thu Dec 06, 2012 2:32 am |
|
|
How you map your data on to Modbus registers is something only you can do. We don't know what your application needs.
The example, to be simple, has actual arrays with one element for each Modbus register. A real Modbus application is likely to be more complex than that; mine are. What I have done is call a pair of write-register() and read_register() routines that, using switch, maps Modbus register addresses on to actual data sources. I've had to deal with gaps in the register address space and stuff like that. Real applications are not likely to use just a few registers. I map something like 180 in one app. So my Modbus registers are virtual rather than actual. I.e. my Modbus pulls data from virtual sources rather than my measuring stuff pushes it to a set of register copies as in the CCS example code.
Here is a sample of what it looks like:
Code: |
int16 Read_Register(int Address)
{
int16 Register_Data = 0;
switch (Address)
{
case 0:
// 488.2 Status register
Register_Data = Status_Byte_Register;
break;
case 1:
// 488.2 Event register
Register_Data = Get_Event_Status_Byte();
break;
case 2:
// 488.2 style Error register
Register_Data = Error_Register;
break;
case 3:
Register_Data = Service_Request_Enable_Register;
break;
case 4:
Register_Data = Event_Status_Enable_Register;
break;
case 5:
Register_Data = Error_Enable_Register;
break;
case 6:
// Mode register.
Register_Data = Module_Mode | ((int16)(Fault_Location & 0x0F) << 8) | ((int16)(Module_Fault & 0x0F) << 12);
break;
// 7 - 9 unused - will read as zero.
case 10:
// Modbus address. Simples.
Register_Data = Modbus_Address;
break;
case 11:
// Version.
Register_Data = (int16)Version.Major << 8 | Version.Minor;
break;
case 12:
// Build number.
Register_Data = Version.Build;
break;
case 13:
// Firmware timecode low
Register_Data = Timecode & 0x0000FFFF;
break;
case 14:
// Firmware timecode high
Register_Data = Timecode >> 16;
break;
...
more cases etc.
}
return Register_Data;
}
...
// Here is my modified read holding registers:
case FUNC_READ_HOLDING_REGISTERS:
if(modbus_rx.data[0] || modbus_rx.data[2] ||
modbus_rx.data[1] >= MAX_REGISTERS || modbus_rx.data[3]+modbus_rx.data[1] > MAX_REGISTERS)
modbus_exception_rsp(Modbus_address, modbus_rx.func, ILLEGAL_DATA_ADDRESS);
else
{
// Read the registers into our holding area. Note we can only cope with up to 16.
for (Register_Address = 0; Register_Address < modbus_rx.data[3]; Register_Address++)
{
Scratch_Registers[Register_Address] = Read_Register(modbus_rx.data[1] + Register_Address);
}
// Send back the scratch copy of the registers.
modbus_read_holding_registers_rsp(Modbus_address,(modbus_rx.data[3]*2), Scratch_Registers);
event_count++;
}
break;
|
I hope that gives you some ideas.
RF Developer |
|
|
aroonkriss
Joined: 03 Dec 2012 Posts: 19 Location: kerala
|
|
Posted: Thu Dec 06, 2012 4:45 am |
|
|
Thank you very much (RF Developer) sir, that was helpful. I got the idea. Thanks a lot. _________________ I dream world peace |
|
|
|