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 support@ccsinfo.com

pic18F458 CAN bus - build error PLS HELP

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



Joined: 26 Sep 2012
Posts: 10

View user's profile Send private message

pic18F458 CAN bus - build error PLS HELP
PostPosted: Sun Oct 07, 2012 11:37 pm     Reply with quote

When I build this program, I got tons of errors.......kindly advice what is the possible problem...........

- Program origin from PCM
http://www.ccsinfo.com/forum/viewtopic.php?t=29627&start=7
- PIC18F458 used
- version 4.128

Program:

#include <18F458.h>

#fuses HS, NOPROTECT, NOWDT, NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

#include <can-18F4580.c>

#define BOARD1_ID 24
#define BOARD2_ID 25

// Uncomment this line to compile code for Board #1.
// Comment it out to compile for Board #2.
#define BOARD1 1

//======================================
void main()
{
struct rx_stat rxstat;
int32 rx_id;
int32 tx_id;
int8 rx_len;
int8 buffer[8];

can_init();


#ifdef BOARD1 // For Board #1
while(1)
{
buffer[0] = getc(); // Wait for a character

// Transmit it to board #2.
can_putd(BOARD2_ID, buffer, 1, 1, 1, 0);

buffer[0] = 0; // Clear the buffer byte

// Wait for the char to be echoed back.
while(!can_kbhit());

if(can_getd(rx_id, buffer, rx_len, rxstat))
{
if(rx_id == BOARD1_ID) // Is it for this board ?
{
putc(buffer[0]); // If so, display the char
}
}
}
#else // For Board #2
while(1)
{
if(can_kbhit()) // Message available ?
{
// If so, get the message.
if(can_getd(rx_id, buffer, rx_len, rxstat))
{
if(rx_id == BOARD2_ID) // Is it for this board ?
{
// If so, echo back the character.
can_putd(BOARD1_ID, buffer, 1, 1, 1, 0);
}
}
}
}
#endif

}


Errors received:

Executing: "C:\Program files\Picc\CCSC.exe" +FH "CANbustest.c" #__DEBUG=1 +ICD +DF +LN +T +A +M +Z +Y=9 +EA #__18F458=TRUE
*** Error 56 "C:\Program Files\PICC\drivers\can-18F4580.c" Line 172(11,17): Element is not a member
*** Error 56 "C:\Program Files\PICC\drivers\can-18F4580.c" Line 173(11,16): Element is not a member
*** Error 56 "C:\Program Files\PICC\drivers\can-18F4580.c" Line 687(36,42): Element is not a member
*** Error 51 "C:\Program Files\PICC\drivers\can-18F4580.c" Line 692(4,8): A numeric expression must appear here
*** Error 51 "C:\Program Files\PICC\drivers\can-18F4580.c" Line 697(4,8): A numeric expression must appear here
*** Error 51 "C:\Program Files\PICC\drivers\can-18F4580.c" Line 702(4,8): A numeric expression must appear here
*** Error 51 "C:\Program Files\PICC\drivers\can-18F4580.c" Line 707(4,8): A numeric expression must appear here
*** Error 51 "C:\Program Files\PICC\drivers\can-18F4580.c" Line 712(4,8): A numeric expression must appear here
*** Error 51 "C:\Program Files\PICC\drivers\can-18F4580.c" Line 717(4,8): A numeric expression must appear here
*** Error 56 "C:\Program Files\PICC\drivers\can-18F4580.c" Line 839(36,42): Element is not a member
*** Error 51 "C:\Program Files\PICC\drivers\can-18F4580.c" Line 852(4,8): A numeric expression must appear here
*** Error 51 "C:\Program Files\PICC\drivers\can-18F4580.c" Line 865(4,8): A numeric expression must appear here
*** Error 51 "C:\Program Files\PICC\drivers\can-18F4580.c" Line 878(4,8): A numeric expression must appear here
*** Error 51 "C:\Program Files\PICC\drivers\can-18F4580.c" Line 891(4,8): A numeric expression must appear here
*** Error 51 "C:\Program Files\PICC\drivers\can-18F4580.c" Line 904(4,8): A numeric expression must appear here
*** Error 51 "C:\Program Files\PICC\drivers\can-18F4580.c" Line 917(4,8): A numeric expression must appear here
*** Error 56 "C:\Program Files\PICC\drivers\can-18F4580.c" Line 1613(31,37): Element is not a member
*** Error 56 "C:\Program Files\PICC\drivers\can-18F4580.c" Line 1652(31,37): Element is not a member
*** Error 56 "C:\Program Files\PICC\drivers\can-18F4580.c" Line 1690(31,37): Element is not a member
*** Error 56 "C:\Program Files\PICC\drivers\can-18F4580.c" Line 1728(31,37): Element is not a member
*** Error 56 "C:\Program Files\PICC\drivers\can-18F4580.c" Line 1767(31,37): Element is not a member
*** Error 56 "C:\Program Files\PICC\drivers\can-18F4580.c" Line 1805(31,37): Element is not a member
*** Error 56 "CANbustest.c" Line 39(22,23): Element is not a member
23 Errors, 0 Warnings.
Halting build on first failure as requested.
BUILD FAILED: Mon Oct 08 13:09:02 2012

Please help..............
Ttelmah



Joined: 11 Mar 2010
Posts: 19401

View user's profile Send private message

PostPosted: Mon Oct 08, 2012 3:24 am     Reply with quote

I'd guess that one of your include directories is set up to look in a directory used by an older compiler.

If you look at the first error on line 172, it is:
Code:

CIOCON.tx2src=CAN_CANTX2_SOURCE;


So go and look for where this value is defined.

It is all in the .h file, and correctly sets the define value to zero if you are using your chip. The register definition also includes the right bit defines for tx2src.

However it is not present in the include file for an old V3 compiler (this was added in the early V4 releases). It looks as if somehow your compiler is finding an old can-18f4580.h, and trying to use this with the modern can-18f4580.c, which wants the extra definitions. So you need to check your search path/project settings etc., and make sure the compiler looks in the right place....

Best Wishes
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Oct 08, 2012 11:28 am     Reply with quote

Quote:
#include <18F458.h>

#include <can-18F4580.c>

You're using an 18F458 PIC, but you are #including the CAN driver
for a newer PIC which has ECAN registers. 18F458 doesn't support ECAN.
My original test program uses the CAN driver for the 18F458.
Edit your program to use this driver instead:
Code:

#include <can-18xxx8.c>


The "xxx" in the middle of the filename does not mean that you should
put in another PIC part number. That file actually exists, and is supplied
by CCS. It's for the 18F458. Use it.
prostep



Joined: 26 Sep 2012
Posts: 10

View user's profile Send private message

PostPosted: Sun Oct 14, 2012 11:47 pm     Reply with quote

PCM, will this program work with 10MHz clock?
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Mon Oct 15, 2012 3:49 am     Reply with quote

prostep wrote:
PCM, will this program work with 10MHz clock?


The CAN drivers set up the CAN hardware for 125kbps with a processor clock of 20MHz. If your processor clock is different, such as 10MHz, or you want to run at a different CAN bus speed, then you will have to alter the setup of the CAN driver.

You set up the CAN differently by defining the relevant parameters in your code BEFORE the #include <can-18xxx8.c> . These are:

Code:

// These values are the default values from can-18xxx.h are are for
// 125kbps @ 20MHz.

#define CAN_BRG_PRESCALAR  4  //baud rate generator prescalar (def: 4) ( Tq = (2 x (PRE + 1))/Fosc )

#define CAN_BRG_PHASE_SEGMENT_1  5 //phase segment 1 (def: 6 x Tq)

#define CAN_BRG_PROPAGATION_TIME 2 //propagation time

#define CAN_BRG_PHASE_SEGMENT_2 5 //phase segment 2 time


To find valid values, use a program such as mbtime from http://intrepidcs.com/support/mbtime.htm as getting the right values is tricky and not at all straightforward - it much more complicated than UART timing.

Note: CAN isn't an addressed protocol. CAN messages are messages, and are broadcast to all CAN devices (generally called CAN nodes). Any node that want to listen to a message can do so, it doesn't have to be just one destination node. This is powerful, but you need to get your head around it as it is not as simple as sending from "here" to "there": IDs are NOT addresses, they are message types.

RF Developer
prostep



Joined: 26 Sep 2012
Posts: 10

View user's profile Send private message

PostPosted: Sun Oct 28, 2012 2:57 am     Reply with quote

I tried the above program on Teraterm, however I would like to know what is the actual response or output I am expected to see from the terminal emulator?

Currently I had local echo turn off, when I tried typing, words are not appearing on the Teraterm screen.....I suspect something does goes wrong....

Could anyone advise the settings on Teraterm or Hyperterminal as I am really new in using terminal emulator and most importantly what is the output I am expecting to see?

I am using a 20Mhz crystal and a usb to rs232 cable.
prostep



Joined: 26 Sep 2012
Posts: 10

View user's profile Send private message

PostPosted: Sun Oct 28, 2012 7:55 am     Reply with quote

I had just tried the loopback for individual CAN node with success. Program used is from this post:
http://www.ccsinfo.com/forum/viewtopic.php?t=20106

However, I am still unable to succeed with two nodes using the program from the first post.

Kindly please advice....anyone....thanks
prostep



Joined: 26 Sep 2012
Posts: 10

View user's profile Send private message

PostPosted: Sun Oct 28, 2012 11:03 am     Reply with quote

I had solved the problem! Very Happy
It was the placement of my 120ohm resistor, initially I placed them slightly far from my MCP2551. I corrected it by placing it as near as possible to my MCP2551, and it works! Whatever I typed on the keyboard is reflected on Teraterm screen (Local echo OFF).

PCM: What do I need to add to the program to test for 3 nodes? Kindly advice.....

PC->board1->board2->board3->board2->board1->PC

or anyone??
ezflyr



Joined: 25 Oct 2010
Posts: 1019
Location: Tewksbury, MA

View user's profile Send private message

PostPosted: Sun Oct 28, 2012 3:27 pm     Reply with quote

Hi,

The very basic nature of your questions suggests that you've bitten off more
than you can chew with this project..... Is a CAN bus project your first effort
with CCS 'C'?

To add additional nodes, you would need to define additional node
addresses. You will also need to change the code so that its not just either
'Board1' or 'Board2', but allows other boards. The current code uses a
straight-forward if-then-else construct to do this, so you'll need to use
something that allows a greater number of selections, such as an 'else if'
construct or a switch statement.


Good Luck!

John
prostep



Joined: 26 Sep 2012
Posts: 10

View user's profile Send private message

PostPosted: Wed Nov 07, 2012 1:50 am     Reply with quote

My attempt on 3 nodes......kindly give advice....I admit I am very poor in C, but I am making an effort to learn......

Btw can anyone explain what does the '1' mean here?
-> #define BOARD1 1

and how actually the ID came about? I just try my luck for board3 ID.....Please advise. Thanks.
Code:

#include <18F458.h>
#fuses HS, NOPROTECT, PUT, BROWNOUT, NOWDT, NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

#include <can-18xxx8.c>

#define BOARD1_ID  24
#define BOARD2_ID  25
#define BOARD3_ID  26


// Comment '#define BOARD2 1' out to compile for Board #1.
// Comment '#define BOARD1 1' out to compile for Board #2.
// Comment both out to compile for Board #3.
 
#define BOARD1   1   
#define BOARD2   1
//======================================
void main()
{
struct rx_stat rxstat;
int32 rx_id;
int32 tx_id;
int8 rx_len;               
int8 buffer[8];

can_init();


#ifdef BOARD1   // For Board #1
while(1)
  {
   buffer[0] = getc();   // Wait for a character

   // Transmit it to board #2.
   can_putd(BOARD2_ID, buffer, 1, 1, 1, 0);

   buffer[0] = 0;   // Clear the buffer byte

   // Wait for the char to be echoed back.
   while(!can_kbhit());

   if(can_getd(rx_id, buffer, rx_len, rxstat))
     {
      if(rx_id == BOARD1_ID)  // Is it for this board ?
        {
         putc(buffer[0]);  // If so, display the char
        }
      }
  }
#elif BOARD2   // For Board #2
while(1)
  {
   if(can_kbhit())  // Message available ?
     {
      // If so, get the message.
      if(can_getd(rx_id, buffer, rx_len, rxstat))
        {
         if(rx_id == BOARD2_ID)  // Is it for this board ?
           {
           
      
  can_putd(BOARD3_ID, buffer, 1, 1, 1, 0);

   buffer[0] = 0;   // Clear the buffer byte
           }
         }
      }
  }
#else   // For Board #3
while(1)
  {
   if(can_kbhit())  // Message available ?
     {
      // If so, get the message.
      if(can_getd(rx_id, buffer, rx_len, rxstat))
        {
         if(rx_id == BOARD3_ID)  // Is it for this board ?
           {
            // If so, echo back the character.
            can_putd(BOARD1_ID, buffer, 1, 1, 1, 0);
           }
         }
      }
  }

#endif
 
}
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Wed Nov 07, 2012 4:11 am     Reply with quote

prostep wrote:

Btw can anyone explain what does the '1' mean here?
-> #define BOARD1 1


It means you are getting yourself confused!

What it actually means is that you are defining a pre-processor constant "BOARD1" and giving it the string value "1". All preprocessor constants are strings. When used in code the string value is substituted in place of the constant name. So that whenever the compiler sees "BOARD1" it puts "1" in its place.

You are making this code more compicated than it should be. All you need to do is:


Code:

#include <18F458.h>
#fuses HS, NOPROTECT, PUT, BROWNOUT, NOWDT, NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

#include <can-18xxx8.c>

#define BOARD1_ID  24
#define BOARD2_ID  25
#define BOARD3_ID  26


// Change this to the board ID you want.
 
#define MY_ID BOARD3_ID   

//======================================
void main()
{
struct rx_stat rxstat;
int32 rx_id;
int32 tx_id;
int8 rx_len;               
int8 buffer[8];

can_init();

while(1)
  {
   buffer[0] = getc();   // Wait for a character

   // Transmit it to board #2.
   can_putd(BOARD2_ID, buffer, 1, 1, 1, 0);

   buffer[0] = 0;   // Clear the buffer byte

   // Wait for the char to be echoed back.
   while(!can_kbhit());

   if(can_getd(rx_id, buffer, rx_len, rxstat))
     {
      if(rx_id == MY_ID)  // Is it for this board ?
        {
         putc(buffer[0]);  // If so, display the char
        }
      }
  }
}


Note board IDs is not the right way to do CAN messaging. CAN uses the message ID to resolve bus conflicts and detect collisions. All messages should have unique IDs. If you use them as addresses, as you are here, then its possible for more than one message to have the same ID, as all messages sent to one "board" will have the same ID.

You can also, as I do in my projects, set up the CAN filters to only accept messages that you want to receive. In this case, only messages for your "board". That is more complicated to set up.

Also CAN messages can have up to 8 bytes of data. There is a lot of overhead - extra bytes for framing, ID, error checking and stuff - so sending one byte of data per CAN message is very inefficient.

RF Developer
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