flukeco
Junior Member level 1
- Joined
- Apr 25, 2014
- Messages
- 16
- Helped
- 0
- Reputation
- 0
- Reaction score
- 0
- Trophy points
- 1
- Activity points
- 180
Hi,
I'm using PIC18F2580 and MCP2551 CAN transceiver. My goal is to implement basic CAN bus monitoring program to capture CAN's frame ID,
data length and data bytes.
I use logic analyzer and can see that CANRX pin on PIC is continuously receiving data. However, the RXFUL bit of RXBnCON register
has never been set in my program.
The following is my CAN initialize function and CAN receive function. I want to capture all valid standard and extended CAN frames.
If you find anything wrong in the code, please give me some suggestion. Your help will be highly appreciated.
Best Regards,
Pat
I'm using PIC18F2580 and MCP2551 CAN transceiver. My goal is to implement basic CAN bus monitoring program to capture CAN's frame ID,
data length and data bytes.
I use logic analyzer and can see that CANRX pin on PIC is continuously receiving data. However, the RXFUL bit of RXBnCON register
has never been set in my program.
The following is my CAN initialize function and CAN receive function. I want to capture all valid standard and extended CAN frames.
If you find anything wrong in the code, please give me some suggestion. Your help will be highly appreciated.
Best Regards,
Pat
Code:
void CAN_init(void) {
TRISB = 0b00001000; /* CANRX(RB3) is input, CANTX(RB2) is output*/
PORTB = 0b00000000;
CANCON = 0b10000000; /* Request configuration mode (CANCON<7:5> = 0b1xx) */
/* Wait until op mode is configuration mode (CANSTAT<7:5> = 0b100) */
while ((CANSTAT & 0b11100000) != 0b100) {
Nop();
}
/* Set up baud rate registers */
/* 500 Kbps @ 40MHz */
BRGCON1 = 0b01000001; /* SWJ = 2TQ BPS = 1 */
BRGCON2 = 0b10111010; /* SEG2PHTS = 1, sampled once, PS1 = 8TQ, PropagationT = 3TQ */
BRGCON3 = 0b00000111; /* Wake-up disabled, PS2 = 8Tq */
/* Receive all valid messages, double buffer enabled */
RXB0CON = 0b00000100;
RXB1CON = 0b00000000;
/* Set masks */
RXM0SIDH = 0;
RXM0SIDL = 0;
RXM0EIDH = 0;
RXM0EIDL = 0;
RXM1SIDH = 0;
RXM1SIDL = 0;
RXM1EIDH = 0;
RXM1EIDL = 0;
/* Set filters */
RXF0SIDH = 0;
RXF0SIDL = 0;
RXF0EIDH = 0;
RXF0EIDL = 0;
RXF1SIDH = 0;
RXF1SIDL = 0;
RXF1EIDH = 0;
RXF1EIDL = 0;
RXF2SIDH = 0;
RXF2SIDL = 0b00001000;
RXF2EIDH = 0;
RXF2EIDL = 0;
RXF3SIDH = 0;
RXF3SIDL = 0b00001000;
RXF3EIDH = 0;
RXF3EIDL = 0;
RXF4SIDH = 0;
RXF4SIDL = 0b00001000;
RXF4EIDH = 0;
RXF4EIDL = 0;
RXF5SIDH = 0;
RXF5SIDL = 0b00001000;
RXF5EIDH = 0;
RXF5EIDL = 0;
CANCON = 0x00; /* Request normal mode (CANCON<7:5> = 0b000) */
/* Wait until op mode is normal mode (CANSTAT<7:5> = 0b000) */
while ((CANSTAT & 0b11100000) != 0b000) {
Nop();
}
}
char CAN_read(struct _CANframe *frame) {
unsigned char RXflag, hi, lo;
RXflag = 0;
/* Check RXB0 */
if (RXB0CONbits.RXFUL) {
if (RXB0SIDLbits.EXID == 0) {
/* Standard ID */
/* SID low byte = RXBnSIDH<4:0> (high 5 bits), RXBnSIDL<7:5> (low 3 bits)
* SID high byte = 0b00000 (high 5 bits), RXBnSIDH<7:5> (low 3 bits)
*/
lo = ((RXB0SIDH & 0b00011111) << 3) | ((RXB0SIDL & 0b11100000) >> 5);
hi = (RXB0SIDH & 0b11100000) >> 5;
frame->ID = (unsigned long)MAKEWORD(lo, hi);
} else {
/* Extended ID
* EID low word = RXBnEIDH:RXBnEIDL
* EID high word:
* MSB => 0b000 (high 3 bits), RXBnSIDH<7:3> (low 5 bits)
* LSB => RXBnSIDH<2:0> (high 3 bits), RXBnSIDL<7:5> (middle 3 bits), RXBnSIDL<1:0> (low 2 bits)
*/
lo = ((RXB0SIDH & 0b00000111) << 5) | ((RXB0SIDL & 0b11100000) >> 3) | (RXB0SIDL & 0b00000011);
hi = (RXB0SIDH & 0b11111000) >> 3;
frame->ID = MAKELONG(MAKEWORD(RXB0EIDL, RXB0EIDH), MAKEWORD(lo, hi));
}
frame->length = RXB0DLC & 0b00000111;
frame->data[0] = RXB0D0;
frame->data[1] = RXB0D1;
frame->data[2] = RXB0D2;
frame->data[3] = RXB0D3;
frame->data[4] = RXB0D4;
frame->data[5] = RXB0D5;
frame->data[6] = RXB0D6;
frame->data[7] = RXB0D7;
RXB0CONbits.RXFUL = 0;
RXflag = 1;
}
/* Check RXB1 */
else if (RXB1CONbits.RXFUL) {
if (RXB1SIDLbits.EXID == 0) {
/* Standard ID */
/* SID low byte = RXBnSIDH<4:0> (high 5 bits), RXBnSIDL<7:5> (low 3 bits)
* SID high byte = 0b00000 (high 5 bits), RXBnSIDH<7:5> (low 3 bits)
*/
lo = ((RXB1SIDH & 0b00011111) << 3) | ((RXB1SIDL & 0b11100000) >> 5);
hi = (RXB1SIDH & 0b11100000) >> 5;
frame->ID = (unsigned long)MAKEWORD(lo, hi);
} else {
/* Extended ID
* EID low word = RXBnEIDH:RXBnEIDL
* EID high word:
* MSB => 0b000 (high 3 bits), RXBnSIDH<7:3> (low 5 bits)
* LSB => RXBnSIDH<2:0> (high 3 bits), RXBnSIDL<7:5> (middle 3 bits), RXBnSIDL<1:0> (low 2 bits)
*/
lo = ((RXB1SIDH & 0b00000111) << 5) | ((RXB1SIDL & 0b11100000) >> 3) | (RXB1SIDL & 0b00000011);
hi = (RXB1SIDH & 0b11111000) >> 3;
frame->ID = MAKELONG(MAKEWORD(RXB1EIDL, RXB1EIDH), MAKEWORD(lo, hi));
}
frame->length = RXB1DLC & 0b00000111;
frame->data[0] = RXB1D0;
frame->data[1] = RXB1D1;
frame->data[2] = RXB1D2;
frame->data[3] = RXB1D3;
frame->data[4] = RXB1D4;
frame->data[5] = RXB1D5;
frame->data[6] = RXB1D6;
frame->data[7] = RXB1D7;
RXB1CONbits.RXFUL = 0;
RXflag = 1;
}
if (RXflag == 1) {
RXflag = 0x00;
PIR3bits.RXB0IF = 0;
PIR3bits.RXB1IF = 0;
return 1;
} else {
return 0;
}
}