CAN transmission

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 
2,215件の閲覧回数
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!

ラベル(1)
0 件の賞賛
返信
1 解決策
1,106件の閲覧回数
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 件の賞賛
返信
2 返答(返信)
1,107件の閲覧回数
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 件の賞賛
返信
1,106件の閲覧回数
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 件の賞賛
返信