|
|
View previous topic :: View next topic |
Author |
Message |
MoSh
Joined: 05 Feb 2013 Posts: 1
|
Nodes can't communicate with the termination resistors Conne |
Posted: Sat Feb 09, 2013 11:24 pm |
|
|
Hi,
I am trying to get two nodes to communicate with each other. I am using PIC 18F458 with transceiver MCP2551 with a 250 kbps rate.
The problem that encounters me is that the two nodes communicate well without termination resistors, But when a termination resistors of 120 ohm each are connected on both ends the communication fails.
I am not using cables as a bus. My bus is the breadboard positive (as CanH) and negative (as CanL), So the bus length is just a couple centimeters long.
I have to get it to work with the termination resistors as one of the nodes that I plan to connect is a device the has internally a 120 ohm termination resistor.
So how to get it to work with termination resistors?
A schematic
It's a little bit different than what I have implemented, As I have added a led to indicate that the pic has started, However the CAN part is the same.
Setup
Code
Node 1
Code: |
unsigned char Data[8];
unsigned short init_flag, send_flag, dt, len, read_flag;
char SJW, BRP, Phase_Seg1, Phase_Seg2, Prop_Seg;
long id, mask;
void main()
{
TRISB = 0x08; // RB2 is output, RB3 is input
TRISC = 0;
TRISD.f0=0;
PORTD.f0=1;
Delay_ms(1000);
PORTD.f0=0;
SJW = 1;
BRP = 0;
Phase_Seg1 = 8;
Phase_Seg2 = 6;
Prop_Seg = 1;
init_flag = _CAN_CONFIG_SAMPLE_THRICE &_CAN_CONFIG_PHSEG2_PRG_ON &_CAN_CONFIG_DBL_BUFFER_ON &_CAN_CONFIG_ALL_MSG &_CAN_CONFIG_LINE_FILTER_OFF;
send_flag = _CAN_TX_PRIORITY_0 &_CAN_TX_XTD_FRAME &_CAN_TX_NO_RTR_FRAME;
read_flag = 0;
// Initialize CAN module
//
CANInitialize(SJW, BRP, Phase_Seg1, Phase_Seg2, Prop_Seg, init_flag);
CANSetOperationMode(_CAN_MODE_CONFIG, 0xFF);
mask = -1;
CANSetMask(_CAN_MASK_B1, mask, _CAN_CONFIG_XTD_MSG);
CANSetMask(_CAN_MASK_B2, mask, _CAN_CONFIG_XTD_MSG);
CANSetOperationMode(_CAN_MODE_NORMAL, 0xFF);
Data[0]=0xAB;
Data[1]=0xCD;
Data[2]=0xEF;
Data[3]=0xAB;
for(;;) // Endless loop
{
CANWrite(0x0CFFF048, Data, 8, send_flag); // send 'T'
Data[0]++;
Data[1]++;
Data[2]++;
Data[3]++;
}
} |
Node 2
Code: |
sbit LCD_RS at RC4_bit;
sbit LCD_EN at RC5_bit;
sbit LCD_D4 at RC0_bit;
sbit LCD_D5 at RC1_bit;
sbit LCD_D6 at RC2_bit;
sbit LCD_D7 at RC3_bit;
sbit LCD_RS_Direction at TRISC4_bit;
sbit LCD_EN_Direction at TRISC5_bit;
sbit LCD_D4_Direction at TRISC0_bit;
sbit LCD_D5_Direction at TRISC1_bit;
sbit LCD_D6_Direction at TRISC2_bit;
sbit LCD_D7_Direction at TRISC3_bit;
unsigned char Data[8];
//Can Initializing Vars
unsigned short init_flag, send_flag, dt, len, read_flag;
char SJW, BRP, Phase_Seg1, Phase_Seg2, Prop_Seg;
long id, mask;
//ECU Data Vars
unsigned int Rpm,Pressure_Type,Temp_Type,Version_Major,Version_Minor,Version_Build;
signed int TPS;
//LCD list Vars
char *Parameter_1,*Parameter_2;
int *Value_1,*Value_2;
int List_Counter=1/*,Group*/,Old_List_Counter;
char Temp[16];
void main()
{
TRISB = 0x08; // RB2 is output, RB3 is input
TRISC = 0;
TRISA.f3=0;
PORTA.f3=1;
Delay_ms(1000);
PORTA.f3=0;
// CAN BUS Timing Parameters
//
SJW = 1;
BRP = 0;
Phase_Seg1 = 8;
Phase_Seg2 = 6;
Prop_Seg = 1;
init_flag = _CAN_CONFIG_SAMPLE_THRICE &_CAN_CONFIG_PHSEG2_PRG_ON &_CAN_CONFIG_DBL_BUFFER_ON &_CAN_CONFIG_ALL_MSG &_CAN_CONFIG_LINE_FILTER_OFF;
send_flag = _CAN_TX_PRIORITY_0 &_CAN_TX_XTD_FRAME &_CAN_TX_NO_RTR_FRAME;
read_flag = 0;
// Initialise CAN module
//
CANInitialize(SJW, BRP, Phase_Seg1, Phase_Seg2, Prop_Seg, init_flag);
CANSetOperationMode(_CAN_MODE_CONFIG, 0xFF);
mask = -1;
CANSetMask(_CAN_MASK_B1, mask, _CAN_CONFIG_XTD_MSG);
CANSetMask(_CAN_MASK_B2, mask, _CAN_CONFIG_XTD_MSG);
CANSetOperationMode(_CAN_MODE_NORMAL, 0xFF);
Lcd_Init(); // Initialize LCD
Lcd_Cmd(_LCD_CLEAR); // Clear LCD
Lcd_Out(1,1,"CAN BUS"); // Display heading on LCD
Delay_ms(2000); // Wait for 2 seconds
/////
Parameter_1="RPM = ";
Parameter_2="TPS = ";
Value_1=&Rpm;
Value_2=&TPS;
Lcd_Init();
Lcd_Cmd(_LCD_CLEAR); // Clear LCD
Lcd_Out(1,1,"RPM = "); // Display Parameter_1 on LCD
Lcd_Out(2,1,"TPS = "); // Display Parameter_2 on LCD
/////
PORTA.f3=1;
Delay_ms(1000);
PORTA.f3=0;
while(1) // Endless loop
{
dt = 0;
while(dt==0)
{
dt = CANRead(&id, Data, &len, &read_flag);
}
switch (id)
{
case 0x0CFFF048:
Rpm=Data[0]+(Data[1]*0xFF);
TPS=Data[2]+(Data[3]*0xFF);
break;
}
IntToStr(*Value_1,Temp) ;
Lcd_Out(1,strlen(Parameter_1),Temp);
IntToStr(*Value_2,Temp);
Lcd_Out(2,strlen(Parameter_2),Temp);
}
} |
Thanks. |
|
|
andrewg
Joined: 17 Aug 2005 Posts: 316 Location: Perth, Western Australia
|
|
Posted: Sun Feb 10, 2013 1:42 am |
|
|
As it happens, I'm currently working on a four node CAN system, three of which have fixed termination resistors! And it's working fine.
I can see that you've grounded the slew rate control pin (#8 on the MCP2551). I'd have at minimum a 10K resistor on that. I'm using 47K resistors, but a relatively slow bus (25000 baud).
The MCP2551 data sheet has a graph with a Rs range from 10K to 120K, so I'd start at 10K (suitable for faster speeds) and work up. _________________ Andrew |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Sun Feb 10, 2013 3:01 am |
|
|
As a comment, the terminators want to be close to the ends of the wires. Your left hand terminator, has about 3" of wire 'beyond' it to the left. This is short enough that it shouldn't be a problem, but it's worth avoiding this. This is called a 'stub'.
Big question though is what the impedance of the 'transmission line' you have is. The point about the CAN bus is it is designed to use twisted pair wires with an impedance close to 120R. The termination resistors then serve to reduce to almost nothing, signal reflections at the ends of this bus. However your lines will have impedance's several order's of magnitude away from this, so the resistors won't do the job they are actually designed to do. Reflections _will_ be made worse by running without slew rate limiting (higher frequency components on the bus), so Andrew's comments apply here. If you have a signal generator, and scope, you might want to try putting a signal into the power lines, through a known resistor, and seeing what the impedance actually 'is' (basically a voltage divider, then ramp the signal, and you can estimate the line impedance by measuring the drop across the resistor). Your terminators then want to match this value.
Best Wishes |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Sun Feb 10, 2013 3:17 am |
|
|
The breadboard circuit shows about no effective power supply bypassing. It won't be surprizing if the supply
current pulses generated with connected termination disturb the system's operation. |
|
|
|
|
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
|