View previous topic :: View next topic |
Author |
Message |
walterma Guest
|
CIOCON.ENDRHI doesn't work! |
Posted: Fri Mar 14, 2008 10:44 am |
|
|
Hi, I'm using a PIC18LF2580 (Vcc=3,3V) with a SN65HVD230 as CAN-tranceiver. Between the PIC and the SN65HVD230 there are 2 optocouplers HCPL-0720 . I have read some topics about the CIOCON register. If CIOCON.ENDRHI is set, so the CANTX will be connect to Vcc when recessive, but this doesn't work!!! I tried to use a pullup resistor on the CANTX pin, but it doesn't work too!
If the PIC is in Listen-Only mode so I can receive the CAN-message. But if the PIC is in Normal mode (receive AND transmit mode) so the CANTX is always connected to GND (dominant state) and the master can't send the data.
Please help!!! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Mar 14, 2008 11:04 am |
|
|
Post a short program that shows the problem. Do not post 200
lines of code. The program should be compilable without errors.
Make sure that you show the #include, #fuses, #use statements. |
|
|
walterma Guest
|
CIOCON |
Posted: Sun Mar 16, 2008 5:47 am |
|
|
void main()
{
int8 i;
int8 can_debug_info=0;
int32 can_rx_id = 0;
int8 can_buffer[8];
int8 can_rx_len;
struct rx_stat can_rx_stat;
for(i=0;i<8;i++) {
can_buffer[i]=0;
}
setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_adc(ADC_OFF|ADC_TAD_MUL_0);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL);
setup_timer_1(T1_DISABLED);
//setup up timer2 to interrupt every 0.5ms if using 40Mhz clock
setup_timer_2(T2_DIV_BY_4,79,16);
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
setup_vref(FALSE);
set_tris_a(0b11000000);
set_tris_b(0b11111001);
// initialize the CAN interface
debug("Setup CAN interface...");
can_init();
//can_set_mode(CAN_OP_LISTEN);
debug("OK\r\n");
// activate interrupts
enable_interrupts(INT_TIMER2);
enable_interrupts(GLOBAL);
while(1)
{
if(can_kbhit())
{
debug("CAN message receive!!!\r\n");
RXB0CON.rxful = 0;
RXB1CON.rxful = 0;
B0CONR.rxful = 0;
B1CONR.rxful = 0;
B2CONR.rxful = 0;
B3CONR.rxful = 0;
B4CONR.rxful = 0;
B5CONR.rxful = 0;
if(can_getd(can_rx_id, &can_buffer[0], can_rx_len, can_rx_stat))
{
a3977_wakeup(A3977_SLEEP_PIN);
a3977_do_steps(A3977_STEP_PIN,5);
//a3977_sleep(A3977_SLEEP_PIN);
if ((can_rx_id==CAN_ID_MASTER_MOVE_MOTOR_CW) ||
(can_rx_id==CAN_ID_MASTER_MOVE_MOTOR_CCW))
{
a3977_wakeup(A3977_SLEEP_PIN);
if(can_rx_id==CAN_ID_MASTER_MOVE_MOTOR_CW)
a3977_set_direction(A3977_DIR_PIN, A3977_DIRECTION_CW);
else
a3977_set_direction(A3977_DIR_PIN, A3977_DIRECTION_CCW);
a3977_do_steps(A3977_STEP_PIN,10);
a3977_sleep(A3977_SLEEP_PIN);
}
}
}
//every two seconds, send new data if transmit buffer is empty
/* if(can_tbe() && (ms>4000))
{
ms=0;
can_putd(CAN_ID_SLAVE_DEBUG, &can_debug_info, 1, 1, 1, 0);
if(++can_debug_info>20)
can_debug_info=0;
}*/
}
} |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Sun Mar 16, 2008 7:02 am |
|
|
A lot of code is missing so we can't compile your program, let alone check it for errors. Read PCM-programmer's post again; the program should be short (max 1 page) and complete so we can copy/paste it into our compiler.
A few more tips:
- Becoming a member of this forum is free and gives you the possibility to edit your posts.
- Post code using the 'code' buttons. This will ensure the formatting of your code is preserved and makes for easier reading. |
|
|
walterma
Joined: 16 Mar 2008 Posts: 6
|
CIOCON |
Posted: Sun Mar 16, 2008 9:21 am |
|
|
Code: |
#include "main.h"
#include <stdlib.h>
#include <can-18F4580.h>
#include <can-18F4580.c>
void main()
{
setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_adc(ADC_OFF|ADC_TAD_MUL_0);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL);
setup_timer_1(T1_DISABLED);
//setup up timer2 to interrupt every 0.5ms if using 40Mhz clock
setup_timer_2(T2_DIV_BY_4,79,16);
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
setup_vref(FALSE);
set_tris_a(0b11000000);
set_tris_b(0b11111001);
// initialize the CAN interface
can_init();
//can_set_mode(CAN_OP_LISTEN);
while(1)
{
if(can_kbhit())
{
// do something
}
}
}
|
in the main.h I've defined following constants:
Code: |
#define CAN_BRG_PRESCALAR 3 // with Fosc=40MHz, #TQ per bit interval=20
// -> Nominal Bit Rate=500kHz
#define CAN_BRG_SYNCH_JUMP_WIDTH 1
#define CAN_BRG_PROPAGATION_TIME 2
#define CAN_BRG_PHASE_SEGMENT_1 4
#define CAN_BRG_PHASE_SEGMENT_2 3
//-----
// 10 = number of TQ per bit interval
#define CAN_BRG_SAM 0 // sample once
#define CAN_BRG_SEG_2_PHASE_TS TRUE // phase segment 2 time select bit
// (def: freely programmable)
#define CAN_BRG_WAKE_FILTER FALSE // selects can bus line filter for wake up
// bit
#define CAN_ENABLE_DRIVE_HIGH 1 // CANTX will drive Vdd when recessive
#define CAN_USE_EXTENDED_ID FALSE // use standard ID
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Mar 16, 2008 9:27 am |
|
|
Code: | The program should be compilable without errors |
Your posted code won't compile. That is because it doesn't have:
Quote: | Make sure that you show the #include, #fuses, #use statements. |
|
|
|
walterma
Joined: 16 Mar 2008 Posts: 6
|
CIOCON |
Posted: Sun Mar 16, 2008 9:30 am |
|
|
excuse me!!!! Here is the main.h
Code: |
#ifndef MAIN_H
#define MAIN_H
#include "18F2580.h"
#device adc=8
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES H4 //High speed osc with HW enabled 4X PLL
#FUSES NOPROTECT //Code not protected from reading
#FUSES BROWNOUT //Reset when brownout detected
#FUSES NOPUT //No Power Up Timer
#FUSES NOCPD //No EE protection
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NODEBUG //No Debug mode for ICD
#FUSES LVP //Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES IESO //Internal External Switch Over mode enabled
#FUSES FCMEN //Fail-safe clock monitor enabled
#FUSES NOPBADEN //PORTB pins are configured as digital I/O on RESET
#FUSES BBSIZ1K //1K words Boot Block size
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOEBTRB //Boot block not protected from table reads
#FUSES NOCPB //No Boot Block code protection
#FUSES LPT1OSC //Timer1 configured for low-power operation
#FUSES MCLR //Master Clear pin enabled
//#FUSES XINST //Extended set extension and Indexed Addressing mode enabled
#use delay(clock=40000000)
#use rs232(baud=115200,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
// -----------------------------------------------------------------------------
// CAN-Interface
// -----------------------------------------------------------------------------
#define CAN_ID_MASTER_MOVE_MOTOR_CW 0x144
#define CAN_ID_MASTER_MOVE_MOTOR_CCW 0x144
#define CAN_ID_SLAVE_DEBUG 0x301
#define CAN_BRG_PRESCALAR 3 // with Fosc=40MHz, #TQ per bit interval=20
// -> Nominal Bit Rate=500kHz
#define CAN_BRG_SYNCH_JUMP_WIDTH 1
#define CAN_BRG_PROPAGATION_TIME 2
#define CAN_BRG_PHASE_SEGMENT_1 4
#define CAN_BRG_PHASE_SEGMENT_2 3
//-----
// 10 = number of TQ per bit interval
#define CAN_BRG_SAM 0 // sample once
#define CAN_BRG_SEG_2_PHASE_TS TRUE // phase segment 2 time select bit
// (def: freely programmable)
#define CAN_BRG_WAKE_FILTER FALSE // selects can bus line filter for wake up
// bit
#define CAN_ENABLE_DRIVE_HIGH 1 // CANTX will drive Vdd when recessive
#define CAN_USE_EXTENDED_ID FALSE // use standard ID
#endif
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Mar 16, 2008 3:15 pm |
|
|
This fuse must be changed to NOLVP. Do that in all your programs.
Quote: | Between the PIC and the SN65HVD230 there are 2 optocouplers
HCPL-0720. |
While you're debugging this problem, I would get rid of those opto-
couplers, and connect the PIC directly to the SN65HVD230 chip.
Also, do you have the 120 ohm termination resistors installed ?
Get rid of the opto-couplers and make sure you have the CAN bus
termination resistors installed. This page shows how to do it:
http://www.interfacebus.com/Design_Connector_CAN.html
Quote: |
I'm using a PIC18LF2580 (Vcc=3,3V) with a SN65HVD230 as CAN-tranceiver |
What is connected to the Rs pin on the SN65HVD230 chip ?
Look at the table on page 3 of the data sheet:
http://www.ti.com/lit/gpn/sn65hvd230
It shows that you should connect the Rs pin to ground for normal
operation. If you left the Rs pin floating (unconnected), there are
going to be serious problems. If it floats above 0.75v, the SN65HVD230
will go into Standby mode and shut down the driver section. |
|
|
walterma
Joined: 16 Mar 2008 Posts: 6
|
ciocon |
Posted: Sun Mar 16, 2008 4:50 pm |
|
|
The 120 Ohm resistors are installed and Rs is connected with GND. I've the same problem if I connect the PIC with the tranceiver without the optocouplers. If the CAN-interface on the PIC is in listen-only mode, so I receive the correct data. I checked the assembler code and I found the place where the CIOCON.ENDRHI is set, but it doesn't work! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Mar 16, 2008 6:23 pm |
|
|
I have an 18F4580. If you have a program that can demonstrate the
problem, I can compile it and test it with my 18F4580. I can do this
on Monday.
Does the program that you posted earlier in this thread show the
problem ? If I run that program, will I see the CANTX pin on the PIC
held at a constant "logic zero" level ?
I have another question. Do you have the CANTX and CANRX pins on
the PIC connected together ? They are not supposed to be connected
together. The CANTX pin should go to the "D" pin on the SN65HVD230,
and the CANRX pin should go to the "R" pin on the SN65HVD230. |
|
|
walterma
Joined: 16 Mar 2008 Posts: 6
|
CIOCON |
Posted: Mon Mar 17, 2008 5:58 am |
|
|
Yes, the code will show the problem. The CANTX and CANRX aren't connected together. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Mar 17, 2008 12:20 pm |
|
|
It turns out that I don't have a 18F4580. I only have the 18F458.
It's similar but it's not the exact chip that you have. So I can't really
do the hardware test.
Instead, look at your .LST file. Load it in your editor and search for F73.
This is the CIOCON register address. You should see a line that looks
like this, in which a "BSF" instruction sets the ENDRHI bit = 1.
Code: | .... CIOCON.endrhi=CAN_ENABLE_DRIVE_HIGH;
0198: BSF F73.5 |
Do you have that line in your .LST file ? Make sure that it says "BSF"
and not "BCF". BCF would clear the bit. You want it set high.
Search for all instances of "F73". Make sure that it never clears the
ENDRHI bit. |
|
|
walterma
Joined: 16 Mar 2008 Posts: 6
|
ciocon |
Posted: Mon Mar 17, 2008 12:39 pm |
|
|
I've already checked the assembler code - see my message on Sun 4:50pm. The bit is set!
Code: |
.................... CIOCON.endrhi=CAN_ENABLE_DRIVE_HIGH;
07C6: BSF F73.5
.................... CIOCON.cancap=CAN_ENABLE_CAN_CAPTURE;
07C8: BCF F73.4
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Mar 17, 2008 1:03 pm |
|
|
Here are some possible reasons for your problem.
1. The PIC may be bad, so that the CANTX pin doesn't work correctly.
Changing to a new PIC might solve the problem.
2. Some external circuit could be holding the CANTX pin at a logic zero
level. This could be caused by a solder bridge, or incorrect circuit
board layout, or incorrect wire connections. You could test this by
disconnecting all external circuits from the CANTX and CANRX pins.
3. The ECAN module may be in a mode that disables the CANTX pin.
For example, the ECAN module has "Legacy" mode and some other
modes, as well as "Normal" mode, "Loopback" mode, etc.
In other words, it could be a configuration issue.
4. It may be operating properly (for the current configuration) and we
just haven't read the data enough to understand it. |
|
|
|