STM32的CAN总线调试心得by-caesar_第1页
STM32的CAN总线调试心得by-caesar_第2页
STM32的CAN总线调试心得by-caesar_第3页
STM32的CAN总线调试心得by-caesar_第4页
STM32的CAN总线调试心得by-caesar_第5页
已阅读5页,还剩6页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、STM32的CAN总线调试心得(一) 工业现场总线 CAN 的基本介绍以及 STM32 的 CAN 模块简介CAN总线特点:(1) 数据通信没有主从之分,任意一个节点可以向任何其他(一个或多个)节点发起数据通信,靠各个节点信息优先级先后顺序来决定通信次序,高优先级节点信息在134s通信;(2) 多个节点同时发起通信时,优先级低的避让优先级高的,不会对通信线路造成拥塞; (3) 通信距离最远可达10KM(速率低于5Kbps)速率可达到1Mbps(通信距离小40M);(4) CAN总线传输介质可以是双绞线,同轴电缆。CAN总线适用于大数据量短距离通信或者长距离小数据量,实时性要求比较高,多主多从或

2、者各个节点平等的现场中使用。发送 3 个发送邮箱 发送报文的优先级特性可软件配置 记录发送 SOF 时刻的时间戳接收 3 级深度的2个接收 FIFO 14 个位宽可变的过滤器组 由整个 CAN 共享 标识符列表 FIFO 溢出处理方式可配置 记录接收 SOF 时刻的时间戳可支持时间触发通信模式 禁止自动重传模式 16 位自由运行定时器 定时器分辨率可配置 可在最后 2 个数据字节发送时间戳管理 中断可屏蔽 邮箱占用单独 1 块地址空间,便于提高软件效率(二) STM32 CAN 模块工作模式STM32 的 can 的工作模式分为: /* CAN operating mode */ #defin

3、e CAN_Mode_Normal (u8)0x00) /* normal mode,用于多节点通信 */ #define CAN_Mode_LoopBack (u8)0x01) /* loopback mode,回环模式用于自测试 */ #define CAN_Mode_Silent (u8)0x02) /* silent mode */ #define CAN_Mode_Silent_LoopBack (u8)0x03) / loopback combined with silent mode 在例程中我们将使用到 CAN_Mode_LoopBack 和 CAN_Mode_Normal 两

4、种模式。 我们第一步做的就是使用运行在 CAN_Mode_LoopBack 下进行自测试。 在参考手册中 CAN_Mode_LoopBack (环回模式) 的定义如下:环回模式可用于自测试。为了避免外部的影响,在环回模式下 CAN 内核忽略确认错误 (在数据 / 远程帧的确认位时刻,不检测是否有显性位) 。在环回模式下,bxCAN 在内部把 Tx 输出回馈到 Rx 输入上,而完全忽略 CANRX 引脚的实际状态。发送的报文可以在 CANTX 引脚上检测到。 因此这种模式也特别适合大家做好硬件后自测程序。如要改回正常模式,需在配置文件里如下修改:(注意接收节点和发送节点)/ CAN_InitSt

5、ructure.CAN_Mode=CAN_Mode_LoopBack; / 回环模式CAN_InitStructure.CAN_Mode=CAN_Mode_Normal; / 正常通信模式(三) CAN 接口端口映射STM32 中的 CAN 物理引脚脚位可以设置成三种:默认模式,重定义地址1模式,重定义地址2模式重定义地址1模式/* Configure CAN pin: RX */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure

6、.GPIO_Mode = GPIO_Mode_IPU;GPIO_Init(GPIOB, &GPIO_InitStructure);/Configure CAN pin: TX GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_Init(GPIOB, &GPIO_InitStructure);/ Configure CAN Remap 重影射 GPIO_PinRem

7、apConfig(GPIO_Remap1_CAN, ENABLE);-(四) CAN 波特率设置(重点)在多节点CAN通信中要设置统一正确。我们需要搞明白CAN波特率的设置,这个章节也是使用CAN的最重要的部分之一,因为这实际应用中我们需要根据我们实际的场合来选择 CAN 的波特率。对于波特率的设置需要详细学习参考手册对应部分的解释。我们在调试软件的时候可以使用示波器来测试 CANTX 引脚上的波形的波特率,这样可以得到事 半功倍的效果,大大的缩短调试学习的时间。 CAN_InitStructure.CAN_SJW = CAN_SJW_1tq; /* 重新同步跳宽*/ CAN_InitStru

8、cture.CAN_BS1 = CAN_BS1_4tq; /* 时间段1 */ CAN_InitStructure.CAN_BS2 = CAN_BS2_3tq; /* 时间段2 */ CAN_InitStructure.CAN_Prescaler = 45; /* 波特率预分频数 */ /* 波特率计算方法 */也就是BaudRate = APB1 / (BS1 + BS2 + 1) * Prescaler)CANbps=36000000/(45*(4+3+1)=100Kbps这里注意的是采用点的位置,也就时BS1,BS2的设置问题,这里我也找了一些资料,抄录下来给大家,是 CANopen 协

9、议中推荐的设置。1Mbps 速率下,采用点的位置在6tq位置处,BS1=5, BS2=2500kbps 速率下,采用点的位置在8tq位置处,BS1=7, BS2=3250kbps 速率下,采用点的位置在14tq位置处,BS1=13, BS2=2125k, 100k, 50k, 20k, 10k 的采用点位置与 250K 相同。(五) 正常发送接收模式(1)硬件连接完成了 loopback 模式的测试之后接下来要学习的就是多机通讯了, 如果您拥有两块带 CAN 硬件的 STM32 的板子,您需要自己构建硬件的物理层的连接, 使用三根线将 CANH,CANL,GND 三根线直连,当然你要接好终端电

10、阻才能保证通讯的正常通讯,当两块板子都跳好后我们使用万用表测量下CANH和CANL之间的电阻是否为 60 欧姆。多块板子多机通讯的是否你只需要在总线的主机端和最后一端接上终端电阻就可以了.如下图所示:(电压转换芯片-(高速收发器)选择TI的SN65HVD1050D或者TJA1050管脚兼容)(2)CAN发送报文报文ID 为 0x1234, 数据为2个字节的一个数据包. TxMessage.StdId=0x00; / 标准标识符为0 TxMessage.ExtId=0x1234; / 设置扩展标示符(29位) TxMessage.IDE=CAN_ID_EXT; / 使用扩展标识符 TxMessa

11、ge.RTR=CAN_RTR_DATA; / 消息类型为数据帧 TxMessage.DLC=2;/ 发送两个字节,每帧最大8个字节 TxMessage.Data0=0xDE; / 第一帧信息 TxMessage.Data1=0xCA; / 第二帧信息 CAN_Transmit(CAN1, &TxMessage); 发送报文有2种 :1中为11位 的标准帧,另一种为29位的扩展帧。发送报文的流程为:发送报文 CAN报文由2种 1中为11位 的标准帧,另一种为29位的扩展帧,+最大8字节数据+CRC校验应用程序选择1个空发送邮箱;设置标识符、数据长度和待发送数据;然后CAN_TIxR寄存器的TXR

12、Q位置1,来请求发送。TXRQ位置1后,邮箱就不再是空邮箱;而一旦邮箱不再为空,软件对邮箱寄存器就不再有写的权限。TXRQ位置1后,邮箱马上进入挂号状态,并等待成为最高优先级的邮箱,参见发送优先级。一旦邮箱成为最高优先级的邮箱,其状态就变为预定发送状态。当CAN总线进入空闲状态,预定发送邮箱中的报文就马上被发送(进入发送状态)。邮箱中的报文被成功发送后,它马上变为空邮箱,硬件相应地对CAN_TSR寄存器的RQCP和TXOK位置1,来表明一次成功发送。发送的优先级可以由标识符或发送请求次序决定:由标识符决定。当有超过1个发送邮箱在挂号时,发送顺序由邮箱中报文的标识符决定。根据CAN协议,标识符数

13、值最低的报文具有最高的优先级。如果标识符的值相等,那么邮箱号小的报文先被发送。由发送请求次序决定。通过对CAN_MCR寄存器的TXFP位置1,可以把发送邮箱配置为发送FIFO。在该模式下,发送的优先级由发送请求次序决定。该模式对分段发送很有用。(3)CAN接收报文接收到的报文,被存储在3级邮箱深度的FIFO中。FIFO完全由硬件来管理,从而节省了CPU的处理负荷,简化了软件并保证了数据的一致性。应用程序只能通过读取FIFO输出邮箱,来读取FIFO中最先收到的报文。根据CAN协议,当报文被正确接收(直到EOF域的最后1位都没有错误),且通过了标识符过滤,那么该报文被认为是有效报文。标识符过滤(重

14、点难点)STM32普通型芯片的CAN有14组过滤器组,互联型有28组过滤器组.一般我们用的都是普通型的,所以在本文中可以说STM32有14组过滤器组. 根据配置,每1组过滤器组可以有1个,2个或4个过滤器.这些过滤器相当于关卡,每当收到一条报文时,CAN要先将收到的报文,从这些过滤器上过一下,能通过的报文是有效报文,收进FIFO中,不能通过的是无效报文(不是发给我的报文),直接丢弃.所有的过滤器是并联的,即,一个报文只要通过了一个过滤器,就是算是有效的.每组过滤器组有两种工作模式: 标识符列表模式,标识符屏蔽位模式.在标识符列表模式下,收到报文的标识符必须与过滤器的值完全相等,才能通过.在标识

15、符屏蔽位模式下,可以指定标识符的哪些位为何值时,就算通过.这其实就是限定了处于某一范围的标识符能够通过.在一组过滤器中,整组的过滤器都使用同一种工作模式.另外,每组过滤器中的过滤器宽度是可变的,可以是32位或16位.由工作模式和宽度,一个过滤器组可以变成以下几中形式之一:(1) 1个32位的屏蔽位模式的过滤器.(2) 2个32位的列表模式的过滤器.(3) 2个16位的屏蔽位模式的过滤器.(4) 4个16位的列表模式的过滤器.所有的过滤器是并联的,即,一个报文只要通过了一个过滤器,就是算是有效的.举例说明:当给定一个CAN ID,如0x1800f001,当然这个是扩展ID,这里有问的是,这个CA

16、N ID的值本身包含两部分,即基本ID与扩展ID,即么你知道这个扩展ID0x1800f001的哪些位是基本ID,哪些位又是扩展ID?(在基本CANID格式下不存在这个问题) 在回答这个问题之前我们来看看ISO11898的定义,如下图:如上图,基本格式不存在扩展ID,而扩展格式中ID0ID17为Extension ID,而ID18ID28为Base ID.因此CAN ID值0x1800f001扩展二进制为:0b 0001 1000 0000 0000 1111 0000 0000 0001,有括号分别区别为:0b 0001 1000 0000 0000 1111 0000 0000 0001,红

17、色部分为扩展ID,蓝色部分为基本ID。那么知道这些有什么用呢?接下来的代码示例中你就会有什么用了。位宽为32位的屏蔽模式在此种模式下中过滤多个CAN ID,此时,过滤器包含两个寄存器,屏蔽码寄存器和标识符寄存器。此模式下最多只存在一个屏蔽过滤器。如下图所示:如上图,上面的ID为标识符寄存器,中间部分的MASK为屏蔽码寄存器。每个寄存器都是32位的。最下边显示的是与CAN ID各位定位的映射关系。上图最下边的映射关系恰好等于扩展CAN值左移3位再补上IDE(扩展帧标识),RTR(远程帧标志)。下面给出一个代码例子,假设我们要接收多个ID:0x7e9,0x1800f001,前面为标准ID,后面为扩

18、展ID,要同时能接收这两个ID,那么该如何设置这个过滤器呢?1. CAN_FilterInitTypeDefCAN_FilterInitStructure;2. U16std_id=0x7e9;3. U32ext_id=0x1800f001;4. U32mask=0;5. 6. CAN_FilterInit(&CAN_FilterInitStructure);/初始化CAN_FilterInitStructrue结构体变量 7. CAN_FilterInitStructure.CAN_FilterNumber=0;/设置过滤器组0,范围为013 8. CAN_FilterInitStructu

19、re.CAN_FilterMode=CAN_FilterMode_IdMask;/设置过滤器组0为屏蔽模式 9. CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;/设置过滤器组0位宽为32位 10. 11. /标识位寄存器的设置 12. /ext_id16取高16位 13. CAN_FilterInitStructure.CAN_FilterIdHigh=((ext_id16)|0xffff;/设置标识符寄存器高字节。 14. CAN_FilterInitStructure.CAN_FilterIdLow=(U16)(

20、ext_id3)|CAN_ID_EXT;/设置标识符寄存器低字节 15. /这里也可以这样设置 16. /CAN_FilterInitStructure.CAN_FilterIdHigh=std_id5;/设置标识符寄存器高字节 17. /CAN_FilterInitStructure.CAN_FilterIdLow=0|CAN_ID_EXT;/设置标识符寄存器低字节,这里也可以设置为CAN_ID_STD 18. 19. /屏蔽寄存器的设置 20. mask=std_id;21. mask=ext_id;22. mask=mask;23. mask16)&0xffff;/设置屏蔽寄存器高字节

21、26. CAN_FilterInitStructure.CAN_FilterMaskIdLow=mask&0xffff;/设置屏蔽寄存器低字节 27. 28. CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FIFO0;/此过滤器组关联到接收FIFO0 29. CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;/激活此过滤器组 30. CAN_FilterInit(&CAN_FilterInitStructure);/设置过滤器CAN_FilterInitTypeDef CAN_Fi

22、lterInitStructure;U16 std_id =0x7e9;U32 ext_id =0x1800f001;U32 mask =0;CAN_FilterInit(&CAN_FilterInitStructure); /初始化CAN_FilterInitStructrue结构体变量CAN_FilterInitStructure.CAN_FilterNumber=0; /设置过滤器组0,范围为013CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; /设置过滤器组0为屏蔽模式CAN_FilterInitStructu

23、re.CAN_FilterScale=CAN_FilterScale_32bit; /设置过滤器组0位宽为32位/标识位寄存器的设置/ext_id16取高16位CAN_FilterInitStructure.CAN_FilterIdHigh=((ext_id16)| 0xffff; /设置标识符寄存器高字节。CAN_FilterInitStructure.CAN_FilterIdLow=(U16)(ext_id3) | CAN_ID_EXT; /设置标识符寄存器低字节/这里也可以这样设置/CAN_FilterInitStructure.CAN_FilterIdHigh=std_id5; /设置

24、标识符寄存器高字节/CAN_FilterInitStructure.CAN_FilterIdLow=0|CAN_ID_EXT; /设置标识符寄存器低字节,这里也可以设置为CAN_ID_STD/屏蔽寄存器的设置mask =std_id;mask =ext_id;mask =mask;mask 16)&0xffff; /设置屏蔽寄存器高字节CAN_FilterInitStructure.CAN_FilterMaskIdLow=mask&0xffff; /设置屏蔽寄存器低字节CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FIFO0; /此过

25、滤器组关联到接收FIFO0CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; /激活此过滤器组CAN_FilterInit(&CAN_FilterInitStructure); /设置过滤器总结可知,当过滤器为屏蔽模式时,标识符寄存器对应的ID内容可为任意一需求接收的ID值,当同时要接收标准帧和扩展帧时,标识符寄存器对应IDE位也随意设置,屏蔽寄存器的IDE位设置为0,表示不关心标准帧还是扩展帧。而屏蔽寄存器对应的ID内容为各需求接收的ID值依次异或的结果再取反。 如果不想用复杂的过滤功能,FIFO可以只激活一组过滤器组,且将它设置成32位

26、的屏蔽位模式,两个标准值寄存器(FxR1,FxR2)都设置成0。这样所有报文均能通过。(STM32提供的例程里就是这么做的!)如下:CAN_FilterInitStructure.CAN_FilterNumber=0;/选择过滤器0CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;/指定过滤器被设置为标识符屏蔽模式CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;/给出过滤器位宽为32位CAN_FilterInitStructure.CAN_Filt

27、erIdHigh=0x0000; CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;CAN_FilterInitStructure.CAN_FilterFIFOAssignment=0;/为过滤器分配缓存 此处到/fifo 因为 CAN_FilterInitStructure.CAN_FilterNumber=0;CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;CAN_FilterInit(&CAN_FilterInitStructure);CAN_ITConfig(CAN1,CAN_IT_FMP0, ENABLE);更具体的可以参考一下这个帖子:接收的CAN1配置成如下:CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;CAN_FilterInitStruct

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论