CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

modbus protocol

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
aroonkriss



Joined: 03 Dec 2012
Posts: 19
Location: kerala

View user's profile Send private message

modbus protocol
PostPosted: Mon Dec 03, 2012 11:05 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Dec 03, 2012 11:55 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Dec 04, 2012 2:00 am     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Dec 04, 2012 2:13 am     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Dec 04, 2012 3:22 am     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Dec 04, 2012 9:47 pm     Reply with quote

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

View user's profile Send private message

modbus protocol- register mapping
PostPosted: Wed Dec 05, 2012 11:41 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Dec 06, 2012 2:32 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Dec 06, 2012 4:45 am     Reply with quote

Thank you very much (RF Developer) sir, that was helpful. I got the idea. Thanks a lot.
_________________
I dream world peace
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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