03STM32之CAN发送管理分析.docx

上传人:b****8 文档编号:10478348 上传时间:2023-02-13 格式:DOCX 页数:13 大小:336.10KB
下载 相关 举报
03STM32之CAN发送管理分析.docx_第1页
第1页 / 共13页
03STM32之CAN发送管理分析.docx_第2页
第2页 / 共13页
03STM32之CAN发送管理分析.docx_第3页
第3页 / 共13页
03STM32之CAN发送管理分析.docx_第4页
第4页 / 共13页
03STM32之CAN发送管理分析.docx_第5页
第5页 / 共13页
点击查看更多>>
下载资源
资源描述

03STM32之CAN发送管理分析.docx

《03STM32之CAN发送管理分析.docx》由会员分享,可在线阅读,更多相关《03STM32之CAN发送管理分析.docx(13页珍藏版)》请在冰豆网上搜索。

03STM32之CAN发送管理分析.docx

03STM32之CAN发送管理分析

STM32之CAN---发送管理分析

1CAN发送邮箱

STM32共有三个CAN发送邮箱,在检测到总线空闲时交发送,但需要注意的是,有可能会发送失败,有可能因为仲裁失败从而导致失败,也有可能是其它错误,原则上bxCAN将自动重发,但bxCAN也可以配置不自动重发。

正因为如此,发送邮箱中有可能同时存在多个需要发送的报文,一旦出现这种情况,那么发送邮箱中的多个报文又将是谁先发送谁后发送呢?

有两种模式:

ID模式和FIFO模式。

ID模式由报文的ID值决定,即ID值越小,优先级越高,另一种FIFO模式,顾名思义,即为消息队列方式,谁先到谁先发送,此种模式下三个邮箱与接收FIFO类似。

下图是发送邮箱的状态图:

                                                             图1

由上图可知,发送邮箱共有四种状态,空状态,挂号状态,预定发送状态(scheduled),发送状态。

发送报文的流程为:

应用程序选择1个空发送邮箱;设置标识符,数据长度和待发送数据;然后对CAN_TIxR寄存器的TXRQ位置’1’,来请求发送。

TXRQ位置’1’后,邮箱就不再是空邮箱;而一旦邮箱不再为空,软件对邮箱寄存器就不再有写的权限。

TXRQ位置1后,邮箱马上进入挂号状态,并等待成为最高优先级的邮箱,参见发送优先级。

一旦邮箱成为最高优先级的邮箱,其状态就变为预定发送状态。

一旦CAN总线进入空闲状态,预定发送邮箱中的报文就马上被发送(进入发送状态)。

一旦邮箱中的报文被成功发送后,它马上变为空邮箱;硬件相应地对CAN_TSR寄存器的RQCP和TXOK位置1,来表明一次成功发送。

如果发送失败,由于仲裁引起的就对CAN_TSR寄存器的ALST位置’1’,由于发送错误引起的就对TERR位置’1’。

2发送优先级

         如之前所述,如果三个邮箱中同时存在多个待发送的报文时,此时存在一个问题,即先送哪个邮箱中的报文好呢?

此时,存在一个发送优先级的问题。

此时,非空发送邮箱进入发送仲裁,发送仲裁有两种策略:

ID模式和FIFO模式。

∙ID模式:

当有超过1个发送邮箱在挂号时,发送顺序由邮箱中报文的标识符决定。

根据CAN协议,标识符数值最低的报文具有最高的优先级。

如果标识符的值相等,那么邮箱号小的报文先被发送。

此模式通过对CAN主控寄存器CAN_MCR的TXFP位清0来设置。

∙FIFO模式:

通过对CAN_MCR寄存器(CAN主控寄存器)的TXFP位置’1’,可以把发送邮箱配置为发送FIFO。

在该模式下,发送的优先级由发送请求次序决定。

该模式对分段发送很有用。

3取消发送

发送邮箱中待发送的报文在正常发送成功之前也可以中途取消,通过对CAN_TSR寄存器的ABRQ位置’1’,可以中止发送请求。

∙当发送邮箱处于挂号或预定状态时:

发送请求马上就被中止了。

∙当发送邮箱处于发送状态时:

        那么中止请求可能导致2种结果:

                   1:

如果邮箱中的报文被成功发送,那么邮箱变为空邮箱,并且CAN_TSR寄存器(CAN发送状态寄存器)的TXOK位被硬件置’1’;

                   2:

如果邮箱中的报文发送失败了,那么邮箱变为预定状态,然后发送请求被中止,邮箱变为空邮箱且TXOK位被硬件清’0’。

      因此,不管如何,一旦取消发送,那么在发送操作结束后,邮箱都会变为空邮箱。

      固件库中取消发送的接口为:

[cpp] viewplain copy

1./** 

2.  * @brief  Cancels a transmit request. 

3.  * @param  CANx:

 where x can be 1 or 2 to select the CAN peripheral. 

4.  * @param  Mailbox:

 Mailbox number. 

5.  * @retval None 

6.  */  

7.void CAN_CancelTransmit(CAN_TypeDef* CANx, uint8_t Mailbox);  

4自动重传模式

该模式主要用于满足CAN标准中,时间触发通信选项的需求。

通过对CAN_MCR寄存器的NART位置’1’,来让硬件工作在该模式(禁止自动重传)。

在该模式下,发送操作只会执行一次。

如果发送操作失败了,不管是由于仲裁丢失或出错,硬件都不会再自动发送该报文。

在一次发送操作结束后,硬件认为发送请求已经完成,从而对CAN_TSR寄存器的RQCP位置’1’,同时发送的结果反映在TXOK、ALST和TERR位上。

5发送邮箱的组成

说了那么多,那个三个发送邮箱的结构到底是怎么样的呢?

与接收FIFO的邮箱类似,发送邮箱也是由四个寄存器组成:

发送邮箱标识符寄存器(CAN_TIxRx=0..2),发送邮箱长度和时间戳寄存器(CAN_TDTxRx=0..2),发送邮箱低字节数据寄存器(CAN_TDLxRx=0..2),发送邮箱高字节寄存器(CAN_TDHxRx=0..2)。

5.1发送邮箱标识符寄存器(CAN_TIxR)(x=0..2)

地址偏移量:

0x180,0x190,0x1A0

复位值:

0xXXXXXXXX,X=未定义位(除了第0位,复位时TXRQ=0)

注:

1当其所属的邮箱处于等待发送的状态时,该寄存器是写保护的。

        2该寄存器实现了发送请求控制功能(第0位)-复位值为0

                                                                                    图2

与接收FIFO的邮箱的发送邮箱标识符寄存器类似,各位定义如下:

位31:

21

STID[10:

0]:

标准标识符

扩展身份标识的高字节。

位20:

3

EXID[17:

0]:

扩展标识符

扩展身份标识的低字节。

位2

IDE:

标识符选择

该位决定发送邮箱中报文使用的标识符类型

0:

使用标准标识符;

1:

使用扩展标识符。

位1

RTR:

远程发送请求

0:

数据帧;

1:

远程帧。

位0

TXRQ:

发送数据请求

由软件对其置1,来请求发送其邮箱的数据。

当数据发送完成,邮箱为空时,硬件对其清0。

5.2发送邮箱数据长度和时间戳寄存器(CAN_TDTxR)(x=0..2)

地址偏移量:

0x184,0x194,0x1A4

复位值:

未定义

                                                                                   图3

位31:

16

TIME[15:

0]:

报文时间戳

该域包含了,在发送该报文SOF的时刻,16位定时器的值。

位15:

9

保留位

位8

TGT:

发送时间戳

只有在CAN处于时间触发通信模式,即CAN_MCR寄存器的TTCM位为1时,该位才有效。

0:

不发送时间戳;

1:

发送时间戳TIME[15:

0]。

在长度为8的报文中,时间戳TIME[15:

0]是最后2个发送的字节:

TIME[7:

0]作为第7个字节,TIME[15:

8]为第8个字节,它们替换了写入CAN_TDHxR[31:

16]的数据(DATA6[7:

0]和DATA7[7:

0])。

为了把时间戳的2个字节发送出去,DLC必须编程为8。

位7:

4

保留位。

位3:

0

DLC[15:

0]:

发送数据长度

该域指定了数据报文的数据长度或者远程帧请求的数据长度。

1个报文包含0到8个字节数据,而这由DLC决定。

5.3发送邮箱低字节数据寄存器(CAN_TDLxR)(x=0..2)

地址偏移量:

0x188,0x198,0x1A8

复位值:

未定义位

当邮箱为空时,寄存器中的所有位为只读。

                                                                                        图4

位31:

24

DATA3[7:

0]:

字节3

报文的数据字节3。

位23:

16

DATA2[7:

0]:

字节2

报文的数据字节2。

位15:

8

DATA1[7:

0]:

字节1

报文的数据字节1。

位7:

0

DATA0[7:

0]:

字节0

报文的数据字节0。

报文包含0到8个字节数据,且从字节0开始。

5.4发送邮箱高字节数据寄存器(CAN_TDHxR)(x=0..2)

地址偏移量:

0x18C,0x19C,0x1AC

复位值:

未定义位

当邮箱为空时,寄存器中的所有位为只读。

                                                                   图5

位31:

24

DATA7[7:

0]:

字节7

报文的数据字节7

注:

如果CAN_MCR寄存器的TTCM位为1,且该邮箱的TGT位也为1,那么DATA7和DATA6将被TIME时间戳代替。

位23:

16

DATA6[7:

0]:

字节6

报文的数据字节6。

位15:

8

DATA5[7:

0]:

字节5

报文的数据字节5。

位7:

0

DATA4[7:

0]:

字节4

报文的数据字节4。

6CAN发送状态寄存器(CAN_TSR)

地址偏移量:

0x08

复位值:

0x1C000000

单有发送邮箱还不行,不得有一个寄存器从整体上显示发送各邮箱的状态及控制,而CAN发送状态寄存器(CAN_TSR)即负责此工作的。

                                                                             图6

各定义如下:

位31

LOW2:

邮箱2最低优先级标志

当由多个邮箱在等待发送报文,且邮箱2的优先级最低时,硬件对该位置1。

位30

LOW1:

邮箱1最低优先级标志

当由多个邮箱在等待发送报文,且邮箱1的优先级最低时,硬件对该位置1。

位29

LOW0:

邮箱0最低优先级标志

当由多个邮箱在等待发送报文,且邮箱0的优先级最低时,硬件对该位置1。

位28

TME2:

发送邮箱2空

当邮箱2中没有等待发送的报文时,硬件对该位置1。

位27

TME1:

发送邮箱1空

当邮箱1中没有等待发送的报文时,硬件对该位置1。

位26

TME0:

发送邮箱0空

当邮箱0中没有等待发送的报文时,硬件对该位置1。

位25:

24

CODE[1:

0]:

邮箱号

当有至少1个发送邮箱为空时,邮箱号为下一个空的发送邮箱号。

当所有的发送邮箱都为空时,邮箱号为优先级最低的那个发送邮箱号。

位23

ABRQ2:

邮箱2中止发送

软件对该位置1可以中止邮箱2的发送请求,当邮箱2的发送报文被清除时硬件对该位清0。

如果邮箱2中没有等待发送的报文,则对该位置1没有任何效果。

位22:

20

保留位,硬件强制其值为0

位19

TERR2:

邮箱2发送失败

当邮箱2因为出错而导致发送失败时,对该位置1。

位18

ALST2:

邮箱2仲裁丢失

当邮箱2因为仲裁丢失而导致发送失败时,对该位置1。

位17

TXOK2:

邮箱2发送成功

每次在邮箱2进行发送尝试后,硬件对该位进行更新:

0:

上次发送尝试失败;

1:

上次发送尝试成功。

当邮箱2的发送请求被成功完成后,硬件对该位置1。

位16

RQCP2:

邮箱2请求完成

当上次对邮箱2的请求(发送或中止)完成后,硬件对该位置1。

软件对该位写’1’可以对其清0;当硬件接收到发送请求时也对该位清0(CAN_TI2R寄存器的TXRQ位被置1)。

该位被清0时,邮箱2的其它发送状态位(TXOK2,ALST2和TERR2)也被清0。

位15

ABRQ1:

邮箱1中止(发送)

软件对该位置1可以中止邮箱1的发送请求,当邮箱1的发送报文被清除时硬件对该位清0。

如果邮箱1中没有等待发送的报文,则对该位置1没有任何效果。

位14:

12

保留位,硬件强制其值为0

位11

TERR1:

邮箱1发送失败

当邮箱1因为出错而导致发送失败时,对该位置1。

位10

ALST1:

邮箱1仲裁丢失

当邮箱1因为仲裁丢失而导致发送失败时,对该位置1。

位9

TXOK1:

邮箱1发送成功

每次在邮箱1进行发送尝试后,硬件对该位进行更新:

0:

上次发送尝试失败;

1:

上次发送尝试成功。

当邮箱1的发送请求被成功完成后,硬件对该位置1。

位8

RQCP1:

邮箱1请求完成

当上次对邮箱1的请求(发送或中止)完成后,硬件对该位置1。

软件对该位写’1’可以对其清0;当硬件接收到发送请求时也对该位清0(CAN_TI1R寄存器的TXRQ位被置1)。

该位被清0时,邮箱1的其它发送状态位(TXOK1,ALST1和TERR1)也被清0。

位7

ABRQ0:

邮箱0中止(发送)

软件对该位置1可以中止邮箱0的发送请求,当邮箱0的发送报文被清除时硬件对该位清0。

如果邮箱0中没有等待发送的报文,则对该位置1没有任何效果。

位6:

4

保留位,硬件强制其值为0

位3

TERR0:

邮箱0发送失败

当邮箱0因为出错而导致发送失败时,对该位置1。

位2

ALST0:

邮箱0仲裁丢失

当邮箱0因为仲裁丢失而导致发送失败时,对该位置1。

位1

TXOK0:

邮箱0发送成功

每次在邮箱0进行发送尝试后,硬件对该位进行更新:

0:

上次发送尝试失败;

1:

上次发送尝试成功。

当邮箱0的发送请求被成功完成后,硬件对该位置1。

位0

RQCP1:

邮箱0请求完成

当上次对邮箱0的请求(发送或中止)完成后,硬件对该位置1。

软件对该位写’1’可以对其清0;当硬件接收到发送请求时也对该位清0(CAN_TI0R寄存器的TXRQ位被置1)。

该位被清0时,邮箱0的其它发送状态位(TXOK0,ALST0和TERR0)也被清0。

这里值得注意的是位25~24,即下一个空的发送邮箱号。

当所有的发送邮箱都为空时,邮箱号为优先级最低的那个发送邮箱号。

通过此两位,STM32就知道下一条发送报文该存储到哪个邮箱了。

7与CAN发送有关的固件发送接口

发送接口如下:

[cpp] viewplain copy

1./** 

2.  * @brief  Initiates and transmits a CAN frame message. 

3.  * @param  CANx:

 where x can be 1 or 2 to to select the CAN peripheral. 

4.  * @param  TxMessage:

 pointer to a structure which contains CAN Id, CAN DLC and CAN data. 

5.  * @retval The number of the mailbox that is used for transmission or 

6.  *         CAN_TxStatus_NoMailBox if there is no empty mailbox. 

7.  */  

8.uint8_t CAN_Transmit(CAN_TypeDef* CANx, CanTxMsg* TxMessage);  

获取发送状态接口如下:

[cpp] viewplain copy

1./** 

2.  * @brief  Checks the transmission status of a CAN Frame. 

3.  * @param  CANx:

 where x can be 1 or 2 to select the CAN peripheral. 

4.  * @param  TransmitMailbox:

 the number of the mailbox that is used for transmission. 

5.  * @retval CAN_TxStatus_Ok if the CAN driver transmits the message,  

6.  *         CAN_TxStatus_Failed in an other case. 

7.  */  

8.uint8_t CAN_TransmitStatus(CAN_TypeDef* CANx, uint8_t TransmitMailbox);  

8一个示例

[cpp] viewplain copy

1.CanTxMsg TxMessage;  

2.int i;  

3.  

4.if(id_fmt == STD_ID)//如果是标准CAN ID  

5.{   

6.    TxMessage.StdId = send_frame->id;  //设置标准CAN ID  

7.    TxMessage.IDE = CAN_ID_STD;   //设置IDE为标准CAN ID  

8.}  

9.else  

10.{      

11.    TxMessage.StdId = (send_frame->  

12.    id >>18) & 0x7FF; //设置扩展CAN ID的标准基本ID部分      

13.    TxMessage.ExtId = send_frame->id & 0x3FFFF;     //设置扩展CAN ID的扩展ID部分  

14.    TxMessage.IDE = CAN_ID_EXT;   //设置IDE为扩展CAN ID  

15.}  

16.  

17.TxMessage.RTR = CAN_RTR_DATA; //数据帧  

18.TxMessage.DLC = 8;  //数据长度  

19.for(i=0;i<8;i++)
  

20.{  

21.    TxMessage.Data[i] = send_frame->data_buff[i];  

22.}  

23.  

24.CAN_Transmit(CAN1,&TxMessage);  

 

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > IT计算机 > 互联网

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1