CAN transmission

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

CAN transmission

跳至解决方案
2,201 次查看
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,092 次查看
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,093 次查看
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,092 次查看
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 项奖励
回复