CAN transmission

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

CAN transmission

Jump to solution
2,198 Views
WP
Contributor II

Hello, I am using the CAN interface of the MCF51AC256 microcontroller. I have managed to make it transmit and receive messages, but when I try transmitting 3 messages one after another, it transmits more than I want.

 

More precisely, I want to transmit TX0, then TX1 and then TX2. But it transmits TX0, TX1, then TX0, TX1, TX2, and then TX0, TX1, TX2.

 

It seems that the TXE flag is not set after each transmission, as it should be... I have gone through the reference manual several times to see whether I have missed something in the register functioning system, but I can't find anything wrong. Can someone help?

 

Here is the code I'm using:

 

          /* transmit (buffer TX0) */
        while (!CANTFLG_TXE0)    // wait till buffer TX0 is empty
        {
          ;
        }
        CANTBSEL_TX0 = 1;        // select buffer TX0
        CANTDLR = 8;             // 8-byte message length
        CANTIDR0 = 0x0C;         // ID = 100
        CANTIDR1 = 0x80;         // bit 4 = 0 : data frame
                                 // bit 3 = 0 : standard identifier
        CANTDSR0 = pot[0];       // copier valeurs à transmettre
        CANTDSR1 = pot[1];       
        CANTDSR2 = pot[2];    
        CANTDSR3 = pot[3];       
        CANTDSR4 = pot[4];    
        CANTDSR5 = pot[5];       
        CANTDSR6 = pot[6];    
        CANTDSR7 = pot[7];       
        CANTBSEL_TX0 = 0;        // deselect buffer TX0
        CANTFLG_TXE0 = 1;        // buffer full, clear flag to transmit
                                 // (writing 1 clears flag)
          
          /* transmit (buffer TX1) */
        while (!CANTFLG_TXE1)    // wait till buffer TX1 is empty
        {
          ;
        }
        CANTBSEL_TX1 = 1;        // select buffer TX1
        CANTDLR = 8;             // 8-byte message length
        CANTIDR0 = 0x0C;         // ID = 101
        CANTIDR1 = 0xA0;         // bit 4 = 0 : data frame
                                 // bit 3 = 0 : standard identifier
        CANTDSR0 = pot[8];       // copier valeurs à transmettre
        CANTDSR1 = pot[9];       
        CANTDSR2 = pot[10];    
        CANTDSR3 = pot[11];       
        CANTDSR4 = pot[12];    
        CANTDSR5 = pot[13];       
        CANTDSR6 = pot[14];    
        CANTDSR7 = pot[15];       
        CANTBSEL_TX1 = 0;        // deselect buffer TX1
        CANTFLG_TXE1 = 1;        // buffer full, clear flag to transmit
                                 // (writing 1 clears flag)

          /* transmit (buffer TX2) */
        while (!CANTFLG_TXE2)    // wait till buffer TX2 is empty
        {
          ;
        }
        CANTBSEL_TX2 = 1;        // select buffer TX2
        CANTDLR = 8;             // 8-byte message length
        CANTIDR0 = 0x0C;         // ID = 102
        CANTIDR1 = 0xC0;         // bit 4 = 0 : data frame
                                 // bit 3 = 0 : standard identifier
        CANTDSR0 = pot[16];      // copier valeurs à transmettre
        CANTDSR1 = pot[17];       
        CANTDSR2 = pot[18];    
        CANTDSR3 = pot[19];       
        CANTDSR4 = pot[20];    
        CANTDSR5 = pot[21];       
        CANTDSR6 = pot[22];    
        CANTDSR7 = pot[23];       
        CANTBSEL_TX2 = 0;        // deselect buffer TX2
        CANTFLG_TXE2 = 1;        // buffer full, clear flag to transmit
                                 // (writing 1 clears flag)

 

I would really appreciate any help. Thank you!

Labels (1)
0 Kudos
Reply
1 Solution
1,089 Views
kef
Specialist I

   CANTFLG_TXE0 = 1;        // buffer full, clear flag to transmit

 

Since 1) flags are cleard writing '1' to them, and 2) CANTFLG register has more flags, red line above will clear all set CANTFLG flags! That's why you send more messages than you really want. Red line can schedule for transmission messages from all 3 Tx buffers. Proper code to send just Tx0 buffer is this:

 

   CANTFLG = CANTFLG_TXE0_MASK;

 

 

--------------------- 

      CANTBSEL_TX0 = 0;        // deselect buffer TX0

 

It is absolutely not necessary to clear CANTBSEL bits. If you you would remove ^^ such lines, then you may use another correct code to send single, CANTBSEL-selected  buffer:

 

    CANTFLG = CANTBSEL;

 

This is valid because hardware restricts setting more than just one CANTBSEL bits.

View solution in original post

0 Kudos
Reply
2 Replies
1,090 Views
kef
Specialist I

   CANTFLG_TXE0 = 1;        // buffer full, clear flag to transmit

 

Since 1) flags are cleard writing '1' to them, and 2) CANTFLG register has more flags, red line above will clear all set CANTFLG flags! That's why you send more messages than you really want. Red line can schedule for transmission messages from all 3 Tx buffers. Proper code to send just Tx0 buffer is this:

 

   CANTFLG = CANTFLG_TXE0_MASK;

 

 

--------------------- 

      CANTBSEL_TX0 = 0;        // deselect buffer TX0

 

It is absolutely not necessary to clear CANTBSEL bits. If you you would remove ^^ such lines, then you may use another correct code to send single, CANTBSEL-selected  buffer:

 

    CANTFLG = CANTBSEL;

 

This is valid because hardware restricts setting more than just one CANTBSEL bits.

0 Kudos
Reply
1,089 Views
WP
Contributor II

Thank you so much, it works fine now!!

(though it would have been a lot more logical if CANTFLG_TXE0 allowed us to clear only one buffer...)

0 Kudos
Reply