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

CAN Example Change Frequency
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
anton



Joined: 10 Mar 2005
Posts: 4

View user's profile Send private message

RE CAN frequency
PostPosted: Mon Mar 14, 2005 5:40 am     Reply with quote

I am using the following:
PIC 18F458 and MCP2551 as a tranceiver.
Using a 12 MHz crystal.
I need to run on both 250kbps and 500kbps

Any help would be great.
Thanks
_________________
Anton
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Mar 15, 2005 1:47 pm     Reply with quote

I looked at the problem and I believe I have a solution for you.

I used the CAN bus bit timing calculator call MBTime, from
http://intrepidcs.com/modules/CmodsDownload/upload/Software/MBTime.zip

That one is the most useful because it provides an interactive bit timing
diagram. You can change the values while watching the box at the
bottom of the window, in which they tell you if you're violating
any specs.

Say you want to get values for a 12 MHz crystal at 250 kbs.

1. Start up the MBTime program and enter those values in the two little
boxes at the upper right.

2. In the top center of the window, where it says "Controls", click
the "right arrow" button. A new window appears.

3. On right hand side, it lists three possible solutions, with 8, 12, or 24
quanta. All you really care is that there is at least one solution.
So click the "right arrow" button again to advance to the next screen.

4. Now you're at the interactive bit timing window. In the drop-down
box, you can select 8, 12, or 24 quanta. The higher you go in
quanta, the more flexibility you have in selecting the length of
the various delays. You have finer granularity. One downside
of picking a larger number of quanta is that the bitfields in the
CAN baudrate registers (in the 18F458) have a limited size.
So, if you choose 24 quanta, you can't increase some of the delays
beyond a certain point. You don't really have the flexibility that
you thought you had.

So for that reason, let's choose 12 quanta from the drop-down box.

We're ready to look at the timing. The "Sync" quanta is always 1.

So next, we look at the Propagation delay time. If you study AN754
http://ww1.microchip.com/downloads/en/AppNotes/00754.pdf
from Microchip, it gives some formulas for calculating the best prop
delay time, based on the length of your cable and the prop delays
through your CAN bus driver and receiver chips. But for a short
cable and normal drivers, I think 500 ns should work fine. But,
the granularity of our quanta is 333 ns. So to get 500 ns, we have
to pick 2 quanta to get at least that much, so this gives us 666 ns
for the Prop time. Do this by incrementing the Prop value in
the spinner box so it's set at 2.

The next issue is the Sample Point. On the Kvaser site, on their
bit timing calculator page, they give a few tips on picking the proper
values. They suggest a Sample Point of about 75%. (Note: I
didn't use the Kvaser calculator because I don't think the values
that it produces can be directly dropped into C source code for
programming the 18F458 BRGCONx registers. The values would
require some adjustment, so it's not as convenient to use.)

So, back to the MBTime program. You can use the "spin" boxes
for Phase Segment 1 and Phase Segment 2, to adjust the length
of those periods, to give a 75% sample point. Make sure that
the total number of quanta remains at 12. Watch the little box
at the bottom of the window. If it says "These settings meet
all requirements", then you're doing it correctly.

Leave SJW set = 1. The reason is, according to Microchip's
AN754, SJW only becomes important if the oscillators on the
different CAN boards have a fairly large difference in frequency.
(Such as 1%). If you're using crystals, that's not going to be a
problem.

So to summarize the settings, we have:
Quote:

Sync = 1 quanta
Prop = 2 quanta
Phase 1 = 6 quanta
Phase 2 = 3 quanta
TOTAL = 12 quanta
Sample point = 75%

Now that you've got a satisfactory timing, click the "Generate Report"
button. This will generate a HTML report with a timing diagram, that's
nicely formatted and you can print it out.

Down at the bottom of the report, it lists the settings for the three
CAN baud rate registers in the 18F458.
For our example of 12 MHz, and 250 kbs, we get this:
Quote:

CNF1/BRGCON1 b'00000001' 0x01
CNF2/BRGCON2 b'10101001' 0xA9
CNF3/BRGCON3 b'00000010' 0x02

The easiest way to use these values with the CCS CAN driver files, is
to edit the can_set_baud() function in the can-18xxx8.c file.
CCS uses bitfields in their driver. But the bit timing generator doesn't
directly generate these bitfield values. The report does tell you the
lengths of Prop, Phase Segment 1 and 2, and SJW, but you have to
subtract 1 from these values before you assign them to the BRGCONx
bitfields, because that's how the bitfields are defined in the 18F458 data
sheet. So I thought an easier way would be to comment out all the
CCS bitfield code, and just assign the 8-bit values directly to the
BRGCONx registers. See below.
Code:
void can_set_baud(void)
{       
BRGCON1 = 0x01;
BRGCON2 = 0xA9;
BRGCON3 = 0x02;

/*
   BRGCON1.brp=CAN_BRG_PRESCALAR;
   BRGCON1.sjw=CAN_BRG_SYNCH_JUMP_WIDTH;

   BRGCON2.prseg=CAN_BRG_PROPAGATION_TIME;
   BRGCON2.seg1ph=CAN_BRG_PHASE_SEGMENT_1;
   BRGCON2.sam=CAN_BRG_SAM;
   BRGCON2.seg2phts=CAN_BRG_SEG_2_PHASE_TS;

   BRGCON3.seg2ph=CAN_BRG_PHASE_SEGMENT_2;
   BRGCON3.wakfil=CAN_BRG_WAKE_FILTER;
*/
}

One risk is that CCS might be using the BRGCONx register constants
somewhere else in the program. To assure yourself that this doesn't
happen, edit the can-18xxx8.h file, and comment out all the constants
associated with the BRGCONx registers (and only those). Example:
Code:

/*

#IFNDEF CAN_BRG_SYNCH_JUMP_WIDTH
  #define CAN_BRG_SYNCH_JUMP_WIDTH  0  //synchronized jump width (def: 1 x Tq)
#ENDIF

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

#ifndef CAN_BRG_SEG_2_PHASE_TS
 #define CAN_BRG_SEG_2_PHASE_TS   TRUE //phase segment 2 time select bit (def: freely programmable)
#endif

#ifndef CAN_BRG_SAM
 #define CAN_BRG_SAM 0 //sample of the can bus line (def: bus line is sampled 1 times prior to sample point)
#endif

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

#ifndef CAN_BRG_PROPAGATION_TIME
 #define CAN_BRG_PROPAGATION_TIME 2 //propagation time select (def: 3 x Tq)
#endif

#ifndef CAN_BRG_WAKE_FILTER
 #define CAN_BRG_WAKE_FILTER FALSE   //selects can bus line filter for wake up bit
#endif

#ifndef CAN_BRG_PHASE_SEGMENT_2
 #define CAN_BRG_PHASE_SEGMENT_2 5 //phase segment 2 time select (def: 6 x Tq)
#endif
*/

There's still the possibility that CCS might be writing to individual bitfields
in their driver. So using a text search tool like Examine32, I did a search
for BRGCON in all the CAN source files. The only place they ever talk
to those registers is in the can_set_baud() function, and we've got that
covered. So there should be no problem with writing directly to the
registers, instead of using the CCS bitfields. And, it will save us some
time when making changes and be less error prone. There's also
the issue of things like the Wake Filter, SAM, and SEGPHTS fields,
but the MBTime program sets them to the same value as CCS does.
------------
Now let's look at your 2nd requested baud rate of 500 kbs with a 12 MHz
crystal.

I think you have to re-start the MBTime program when you change
the main parameters. I don't see anyway to reset it. So just close
it down and re-start it. Type in 12 MHz and 500 in the upper right boxes.

Click the "Control" right-arrow button once, and you see there's only one
solution offered, with 12 quanta. Click it again to get to the timing screen.

Now, we want to increase the Prop setting to at least 500ns, so increase
it to 3 quanta.

Next, we want the Sample Point to be 75%, so set Phase Segment 1 = 5,
and set Phase Segment 2 = 3. Remember to watch the comments box
at the bottom of the window. It will tell you if you've screwed up.
You can also watch the blue lines and the arrows on the bit timing
diagram. You can see when you've pushed it off the screen to the right,
or if you've reduced it too much and have got a margin on the right.
The sum of all the delays has to be kept at 12 quanta, because that was
the solution that the program calculated. So make sure the little box
says "These settings meet all timing requirements".

Then click on Generate Report. It will display a warning for the
MCP2510. That's irrelevant for the 18F458, or at least I hope it is.
Neither the B4 nor the C0 errata mention that bug. So it's probably
only in the MCP2510. If not, you'll have to increase your crystal
frequency to 16 MHz, according to a chart in the MCP2510 errata.

Anyway, for 12 MHz crystal and 500 kbs, you get these settings
for the baud rate registers:
Quote:

CNF1/BRGCON1 b'00000000' 0x00
CNF2/BRGCON2 b'10100010' 0xA2
CNF3/BRGCON3 b'00000010' 0x02


Just plug those directly into the BRGCONx registers as shown above.
Of course, you can also make them into constants. Then it would
be more properly done:

For 500 KBS:
Code:
#define BRGCON1_12MHZ_500KBS  0x00
#define BRGCON2_12MHZ_500KBS  0xA2
#define BRGCON3_12MHZ_500KBS  0x02


for 250 KBS:
Code:
#define BRGCON1_12MHZ_250KBS  0x01
#define BRGCON2_12MHZ_250KBS  0xA9
#define BRGCON3_12MHZ_250KBS  0x02




1st Edit -- Fixed a few typos.
More Edits -- Fixed the name of the AN754 appnote and added a link to it.
Edit -- Updated the link for the Bit Timing calculator program.
Edit -- Had to update the link again. They keep changing it.


Last edited by PCM programmer on Wed Sep 24, 2008 11:33 am; edited 4 times in total
anton



Joined: 10 Mar 2005
Posts: 4

View user's profile Send private message

PIC 18F458 CAN baudrate settings
PostPosted: Wed Mar 16, 2005 3:43 am     Reply with quote

Hi I tried the calculator, and did everything step by step as you described, everything worked and I got th same calculations as you did, but as soon as I change the crystal to 12Mhz and enter the new values the CAN doesn't work. If Iook at the CAN bus on a scope it creates a loop wave that continues until I reset the board.

I used CCS CAN development board. On a 20Mhz crystal I used these settings(the default ones used for the example)

Code:
#define CAN_USE_EXTENDED_ID         TRUE//TRUE
#define CAN_BRG_SYNCH_JUMP_WIDTH    0  //synchronized jump width (def: 1 x Tq)
#define CAN_BRG_PRESCALAR           4 //baud rate generator prescalar (def: 4) ( Tq = (2 x (PRE + 1))/Fosc )
#define CAN_BRG_SEG_2_PHASE_TS      TRUE//TRUE //phase segment 2 time select bit (def: freely programmable)
#define CAN_BRG_SAM                 0 //sample of the can bus line (def: bus line is sampled 1 times prior to sample point)
#define CAN_BRG_PHASE_SEGMENT_1     5 //phase segment 1 (def: 6 x Tq)
#define CAN_BRG_PROPAGATION_TIME    2 //propagation time select (def: 3 x Tq)
#define CAN_BRG_WAKE_FILTER         FALSE//FALSE   //selects can bus line filter for wake up bit
#define CAN_BRG_PHASE_SEGMENT_2     5 //phase segment 2 time select (def: 6 x Tq)
#define CAN_USE_RX_DOUBLE_BUFFER    TRUE//TRUE   //if buffer 0 overflows, do NOT use buffer 1 to put buffer 0 data
#define CAN_ENABLE_DRIVE_HIGH       0
#define CAN_ENABLE_CAN_CAPTURE      0
#byte BRGCON1_12MHz_250KBs =0xF70
#byte BRGCON2_12MHz_250KBs =0xF71
#byte BRGCON3_12MHz_250KBs =0xF72


Then I changed the register values, as you can see there is a "F" in the value. When I remove that(so that it looks more like a normal byte an that it fits the calculator standard) CAN stops working. As soon as I send a message over the bus it creates the loop wave.

Now: I tried the same using a 12Mhz crystal on the CCS CAN development board, and the settings you described above. I left the "F" out, and I put it back, but CAN still doesn't work. I dont know if I am just doing something wron or what. By the method you gave me above I got these values. (this as for a 250Kbps baudrate)

Code:
#define CAN_USE_EXTENDED_ID         TRUE//TRUE
#define CAN_BRG_SYNCH_JUMP_WIDTH   1  //synchronized jump width (def: 1 x Tq)
#define CAN_BRG_PRESCALAR           1 //baud rate generator prescalar (def: 4) ( Tq = (2 x (PRE + 1))/Fosc )
#define CAN_BRG_SEG_2_PHASE_TS      TRUE//TRUE //phase segment 2 time select bit (def: freely programmable)
#define CAN_BRG_SAM                 0 //sample of the can bus line (def: bus line is sampled 1 times prior to sample point)
#define CAN_BRG_PHASE_SEGMENT_1     6 //phase segment 1 (def: 6 x Tq)
#define CAN_BRG_PROPAGATION_TIME    2 //propagation time select (def: 3 x Tq)
#define CAN_BRG_WAKE_FILTER         FALSE//FALSE   //selects can bus line filter for wake up bit
#define CAN_BRG_PHASE_SEGMENT_2     3//phase segment 2 time select (def: 6 x Tq)
#define CAN_USE_RX_DOUBLE_BUFFER    TRUE//TRUE   //if buffer 0 overflows, do NOT use buffer 1 to put buffer 0 data
#define CAN_ENABLE_DRIVE_HIGH       0
#define CAN_ENABLE_CAN_CAPTURE      0
#byte BRGCON1_12MHz_250KBs =0x01
#byte BRGCON2_12MHz_250KBs =0xA9
#byte BRGCON3_12MHz_250KBs =0x02


Is this values correct? I cant see where I am going wrong. What values did you get?

Thanks for all your help
_________________
Anton
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Mar 16, 2005 11:55 am     Reply with quote

Quote:
#byte BRGCON1_12MHz_250KBs =0x01
#byte BRGCON2_12MHz_250KBs =0xA9
#byte BRGCON3_12MHz_250KBs =0x02

That's a mistake. The #byte statement is used to define the address
of a hardware PIC register or sometimes a RAM memory address.
Remove those lines from your program.

You should use the following code:
Code:

void can_set_baud(void)
{       
BRGCON1 = 0x01;
BRGCON2 = 0xA9;
BRGCON3 = 0x02;

/*
   BRGCON1.brp=CAN_BRG_PRESCALAR;
   BRGCON1.sjw=CAN_BRG_SYNCH_JUMP_WIDTH;

   BRGCON2.prseg=CAN_BRG_PROPAGATION_TIME;
   BRGCON2.seg1ph=CAN_BRG_PHASE_SEGMENT_1;
   BRGCON2.sam=CAN_BRG_SAM;
   BRGCON2.seg2phts=CAN_BRG_SEG_2_PHASE_TS;

   BRGCON3.seg2ph=CAN_BRG_PHASE_SEGMENT_2;
   BRGCON3.wakfil=CAN_BRG_WAKE_FILTER;
*/
}
anton



Joined: 10 Mar 2005
Posts: 4

View user's profile Send private message

RE CAN speed
PostPosted: Tue Mar 22, 2005 12:49 am     Reply with quote

Hi
Is there any way that you can post me a example of the can-18xxx8.c and can-18xxx8.h files where you succesfully modified the files to work on a 12 mhz crystal. I cannot, even with the help you gave me above get it to run. I did exactly what you told me and still I cannot get it to work. I think I am missing something.
In the code you posted above, you comment out the whole section on SJW propagation delay etc. As far as I can see you only change the registers. I tried both ways anyway, but without success.

Thankyou
_________________
Anton
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Mar 22, 2005 1:22 am     Reply with quote

I think it should work, but I haven't tested it in hardware.

On Tuesday, I will look for some 12 MHz crystals and see if
we have any in the building somewhere. If so, then I'll test
it with my CAN boards and let you know the results.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Mar 23, 2005 5:56 pm     Reply with quote

I tested it today with a 12 MHz oscillator at 250 kbs and it worked.

The only changes I had to make were in the can_set_baud() function,
in the can-18xxx8.c file. I added the three BRGCONx lines, and
commented out everything else.

I programmed the modified code into my 18F458 demo board.
That's a board that we built here at the company. I used the
Microchip MCP2510 Dev. Kit board to talk our board. It uses
the CANKing software. I was able to send a command and
toggle Port D, bit 0, on and off. (We have our own test program,
which receives a CAN command and writes the data to Port D).

The MCP2510 Dev. Kit board runs at 16 MHz. I configured the
CANKing program for 250 kbs and a 75% sample point. I didn't
get any bus errors, such as "error passive" or anything like that.
So it's working fine.

I don't know why it doesn't work for you. You were doing this
#byte stuff before, and I pointed out that it was incorrect.
Did you fix it so it looks exactly like the code below ?

Code:

void can_set_baud(void) {

// 12 MHz oscillator, 250 kbs
BRGCON1 = 0x01;
BRGCON2 = 0xA9;
BRGCON3 = 0x02;

/*
   BRGCON1.brp=CAN_BRG_PRESCALAR;
   BRGCON1.sjw=CAN_BRG_SYNCH_JUMP_WIDTH;

   BRGCON2.prseg=CAN_BRG_PROPAGATION_TIME;
   BRGCON2.seg1ph=CAN_BRG_PHASE_SEGMENT_1;
   BRGCON2.sam=CAN_BRG_SAM;
   BRGCON2.seg2phts=CAN_BRG_SEG_2_PHASE_TS;

   BRGCON3.seg2ph=CAN_BRG_PHASE_SEGMENT_2;
   BRGCON3.wakfil=CAN_BRG_WAKE_FILTER;
*/
}
anton



Joined: 10 Mar 2005
Posts: 4

View user's profile Send private message

RE CAN
PostPosted: Thu Mar 24, 2005 12:16 am     Reply with quote

Hi, I tried everything you said, I commented out the can_set_baud and added the BRGCON registers. I also commented out the header setings (SJW etc part) (is this correct), anyway I tried it without commenting it out as well.
I will play with it for a while, look over your code and maybe I can find out where I am going wrong.
I will let you know if I get it working or not.

Thanks for all your help.
Chat to you soon.
_________________
Anton
newby



Joined: 26 Sep 2004
Posts: 32

View user's profile Send private message

Optimal CAN settings for long distance communications ?
PostPosted: Thu Sep 28, 2006 11:21 pm     Reply with quote

I would like to use CAN for communications between uCs over distances > 100m.
The baud rate is not the problem, 50 - 100 kbits are enough.

I am also able to use the CAN bit timing calculators, but i need an advice how to set the different phases in an optimal way for this purpose.

The AN574 which should deal with this topic, is no longer available at the microchip homepage.

How should i set the different quantas and so on ?

Thanks for any helpful advice !
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Sep 29, 2006 12:46 am     Reply with quote

It's actually AN754. That was a typo. Thanks for pointing that out.
I will edit the post and fix it. Here's the link to AN754:
http://ww1.microchip.com/downloads/en/AppNotes/00754.pdf
newby



Joined: 26 Sep 2004
Posts: 32

View user's profile Send private message

PostPosted: Sat Sep 30, 2006 2:57 am     Reply with quote

AN754 is very interesting, also according to osc accuracy.

I am facing the following problems now:
- I use the CCS CAN-test board
- With the standard CAN settings used in the examples, 125 kbit
- My external CAN-board uses an 8 MHz ceramic resonator, CAN also configured for 125 kBits, 18F2680
- The test board uses the PCA82C251, my board the MCP2551


Problem:
If I connect my board (CAN-L/H, VSS, VDD) to the CCS test board using CAN-H and CAN-L (of the MCP2551), I am not able to establish a functioning connection.
If I don't use the MCP2551 and wire directly from the TX and RX pins of the uC to the TX and RX pins of the CCS-CAN test board, then everything works fine....

As far as I know the PCA82C251 and MCP2551 should work together - but they don't ?
I checked the connections and soldering of the MCP2551, seems to be fine. I also get an output out of the MCP2551.

Is there anything else I have to keep in mind ?!?
newguy



Joined: 24 Jun 2004
Posts: 1907

View user's profile Send private message

PostPosted: Sat Sep 30, 2006 9:08 am     Reply with quote

The PCA82C251 may not have built-in pullups. Here is a thread that may deal with a similar situation: http://www.ccsinfo.com/forum/viewtopic.php?t=23825&postdays=0&postorder=asc&start=0

The important post is the last one on the first page, by PCM.
newby



Joined: 26 Sep 2004
Posts: 32

View user's profile Send private message

PostPosted: Sun Oct 01, 2006 9:05 am     Reply with quote

Well, if i connect the CAN-boards using the CAN-L/H lines (MCP2551) then there are 15 small spikes on the TX of the 18F2680.
If i connect per RX and TX directly without MCP2551, i see a different pattern (far more complex) and the connection is working.

Is the MCP2551 not "strong enough" to take over the CAN-Bus ? Iīm not an expert but is this pattern (15 peaks) a sign that the 18F2860 is waiting and not able to get a "call connected signal" ?

I tried a 1kOhm PU on the TX line from the 18F2680, change nothing in both cases (using TX & RX and CAN-L/H). I donīt think that i need a PU, i can see the signal on the RX & TX without PU.
Ttelmah
Guest







PostPosted: Sun Oct 01, 2006 9:31 am     Reply with quote

Small spikes like this are common, where required resistors are not present. As the driver gates switch, there is enough internal capacitance to induce a tiny 'edge'on the signal lines. Have you got the terminating resistor present between Can-H, and Can-L at the end of the bus?. Normally 120R at each end of the bus. These are _required_, both providing signal termination, and a DC path for the drive outputs (which for Can-L, is a 'pull-down' only device, and for Can-H, a 'pull-up' only device). Without these, the bus will almost certainly be reporting a permanent 'dominant' state, which will prevent the PIC from being able to drive the bus.

Best Wishes
newby



Joined: 26 Sep 2004
Posts: 32

View user's profile Send private message

PostPosted: Sun Oct 08, 2006 1:15 am     Reply with quote

Well i found the mistake, a quite stupid one.

It was not the 120 Ohm resistor, I don't use one because for the distances and bit rates I use at the moment, I don't need one.

According to the datasheet of the MCP2551, the slew rate (V/us) of the signals can be influenced using an additional resistor called Rset. This Rset can be selected according to a figure and this figure shows that the slew rate doesn't change anymore with increasing resistance above about 100 kOhm - it levels out asymptotically.
Because I didn't know which slew rate I need and just thought "if all values above 100 kOhm" gives the same result, I don't use a resistor which means Rset = xyz MOhm and that?s OK..... But it wasn't ! I have put in a 10 kOhm resistor and from that on it works !

Thanks to all of you guys !
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 1, 2  Next
Page 1 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