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

Basic MODBUS example
Goto page Previous  1, 2
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
chrisatwan



Joined: 07 Apr 2005
Posts: 3
Location: newark, nj

View user's profile Send private message Send e-mail AIM Address Yahoo Messenger MSN Messenger

Basic Modbus RTU
PostPosted: Tue Apr 12, 2005 1:48 pm     Reply with quote

I am sorry. I am just not sure if this should be called when an interrupt occurs or on a timer. Do you call it from another piece of code.

Chris Atwan
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

Re: Basic Modbus RTU
PostPosted: Tue Apr 12, 2005 2:05 pm     Reply with quote

chrisatwan wrote:
I am sorry. I am just not sure if this should be called when an interrupt occurs or on a timer. Do you call it from another piece of code.

Chris Atwan


You definitely wouldn't call it from an interrupt since the code will enable_interrupts(global). Notice the routine doesn't really do much if Comm1.Packet is not set. This is set from timer1 which is used as a timeout after receiving a byte of data. Since this function is #inline and it checks the Packet flag before doing anything, you want to call this frequently. How frequent? I would do it as often as possible since calling it will do nothing but a couple of bit_tests. You could set a flag when a packet is complete and check that flag but wait, that is actually what the code is doing since it is inline. You could make it just a bit more efficient by handling the Initalized portion yourself and removing it from the service routine.
chrisatwan



Joined: 07 Apr 2005
Posts: 3
Location: newark, nj

View user's profile Send private message Send e-mail AIM Address Yahoo Messenger MSN Messenger

Basic Modbus RTU
PostPosted: Wed Apr 13, 2005 7:22 am     Reply with quote

I guess I am having so much trouble becuase I am trying to port this code to an Atmel chip. I have no PIC chip or programmer to try this with. It is harder than I thought to do this.

Chris
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

Re: Thanks
PostPosted: Wed Apr 13, 2005 3:12 pm     Reply with quote

Barney wrote:

Figure out a way to shoe horn the CRC look up table into the code.

You could use the bit shift method in the first post in this thread. It's much smaller.
Barney



Joined: 18 Oct 2004
Posts: 41
Location: Newark, CA

View user's profile Send private message

PostPosted: Thu Apr 14, 2005 12:58 pm     Reply with quote

Yep, that is what I am doing. But I am an efficiency freak and I don't like having my MPU wasting clock cycles if I don't have to. So for now I am using the bit shift algorithm and looking for a way to move to the table look up.
Pbernardi



Joined: 14 Sep 2005
Posts: 12

View user's profile Send private message

PostPosted: Mon Jun 26, 2006 2:24 pm     Reply with quote

Hi,

Reviving the topic.

I�ve tried to use the Neutone�s Code in a PIC18F452 with PCH 2.234, and I use the ModBusView (www.oceancontrols.com.au) to try to communicate to my PC.

I used the following code:



Code:


void main()
{
   config();
   COMM1.Network_Address = 1;
   Registry_Map[1] = 23;         //a debug value
   while(1)
   {
      COMM1_Service();
   }
}


But it doens�t seem alive; The ModBusView accuses TimeOut.

The #Fuses and PIC configurations are OK, there is some code running, and I created this code just for testing.

The PIC appears receive data; The variable COMM1_Buffer usually is somethink like {0xCE,0x80,0x01}, but I�ve not seen it receiving more than 3 words.

Any idea?

Paulo Bernardi.
_________________
Paulo Bernardi
Pbernardi



Joined: 14 Sep 2005
Posts: 12

View user's profile Send private message

PostPosted: Tue Jun 27, 2006 8:11 am     Reply with quote

Hi,

I changed this page code by by code library�s code (http://www.ccsinfo.com/forum/viewtopic.php?t=19306&highlight=modbus) that looks more complete.

Debugging my code, I see that the master�s chars are coming, but the CRC isn�t working weel.

the master sends : [01][03][00][00][00][0A][C5][CD], I receive this, but the CRC ([C5][CD]) isn�t the same of the program (that changes everytime)

So, the program discards the data and receive a new one, and discars and receive other... with no response.

Does anybore can help me?
_________________
Paulo Bernardi
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

PostPosted: Wed Jun 28, 2006 9:22 am     Reply with quote

It's been a long time since that code was posted. If you find a bug in the code library please post how you fixed it. The code I posted was written to demonstrate a method. The flow of the code is right. It's not the code I actually used real products because I don't own that code.
Pbernardi



Joined: 14 Sep 2005
Posts: 12

View user's profile Send private message

PostPosted: Wed Jun 28, 2006 10:35 am     Reply with quote

Neutone,

Thanks for reply.

I�ve found a little mistake on your code, after change it worked.

Code:
/****************************************************/
      /*     Mean time to decode CRC ~ xxuS per byte      */
      /****************************************************/
      COMM1.CRClo_Index=Comm1.CRChi_Index-1;                // Solve this index once instead of once per byte
      Comm1.Index = 0;                                      // Start at begining of packet
      COMM1.CRC_Lo = COMM1.CRC_Hi = 0xFF;                   // Prepare to CRC (missing on original code)
      while(Comm1.Index < COMM1.CRClo_Index)                // Use all bytes prior to CRClo_Index
      {  Comm1.Table_Index = COMM1_Buffer[Comm1.Index];     // Generate CRC
         Comm1.Table_Index ^= Comm1.CRC_Lo;                 // Generate CRC
         Comm1.CRC_Lo = Table_CRC_Hi[Comm1.Table_Index];    // Generate CRC
         Comm1.CRC_Lo ^= Comm1.CRC_Hi;                      // Generate CRC
         Comm1.CRC_Hi = Table_CRC_Lo[Comm1.Table_Index];    // Generate CRC
         Comm1.Index++;
      }


But wasn�t it the real problem. It was a strange behavior (bug?) using this code on PIC18F452. When I declared:

Code:
char Table_CRC_Lo[256]


It didn�t work well. But using:

Code:
const char Table_CRC_Lo[256]


Shocked It worked fine. Why? I don�t kwon.. Confused
_________________
Paulo Bernardi
Guest








PostPosted: Mon Jul 10, 2006 5:14 pm     Reply with quote

But wasn�t it the real problem. It was a strange behavior (bug?) using this code on PIC18F452. When I declared:

Code:
char Table_CRC_Lo[256]


It didn�t work well. But using:

Code:
const char Table_CRC_Lo[256]


Shocked It worked fine. Why? I don�t kwon.. Confused[/quote]

It�s easy... when you put char Table_CRC_Lo[256] the array is allocated in RAM, but when you use const char Table_CRC_Lo[256] it�s created in ROM (program FLASH, in reality). So if you are using a lot of the 18F452 RAM, it can easylly overflow and not compile.
buneri



Joined: 23 Aug 2007
Posts: 14

View user's profile Send private message

How to access 43001 Adress
PostPosted: Fri Nov 02, 2007 12:25 am     Reply with quote

Int16 Registry_Map[128];
#locate Registry_Map = 0x200
Int8 REG_Map[256];
#locate REG_Map = Registry_Map

Int16 Recieved_Packets; // Accessed in holding register 400001 via MODBUS
#locate Recieved_Packets = Registry_Map

Int16 Reply_Packets_This_Second; // Accessed in holding register 400002 via MODBUS
#locate Reply_Packets_This_Second = Registry_Map + 2


In the above coding you have accessed the input registers at 40001 and 40002.
I want to read or write the input registers at 43001 onward in slave.
What will be the code for that?
Plz tell me in hurry
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

Re: How to access 43001 Adress
PostPosted: Fri Nov 02, 2007 4:05 pm     Reply with quote

buneri wrote:
Int16 Registry_Map[128];
#locate Registry_Map = 0x200
Int8 REG_Map[256];
#locate REG_Map = Registry_Map

Int16 Recieved_Packets; // Accessed in holding register 400001 via MODBUS
#locate Recieved_Packets = Registry_Map

Int16 Reply_Packets_This_Second; // Accessed in holding register 400002 via MODBUS
#locate Reply_Packets_This_Second = Registry_Map + 2


In the above coding you have accessed the input registers at 40001 and 40002.
I want to read or write the input registers at 43001 onward in slave.
What will be the code for that?
Plz tell me in hurry


When you decode the packet subtract 3000 from the register address. That will return the value at Registry_Map[0] as 43001. You will be limited to 128 sequential register addresses.
buneri



Joined: 23 Aug 2007
Posts: 14

View user's profile Send private message

How to access adress 43001
PostPosted: Sat Nov 03, 2007 1:03 am     Reply with quote

Thank You very much for fast response,
I dont understand, how it would be possible to locate 3001 adress location in PIC16f877A since it has very limitted memory.

If it is possible what technique i should use to solve my problem. Please reply with detail and clear.I dont understand ur previous point.

I m waiting 4 ur response.

Thanks
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2
Page 2 of 2

 
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