打印
[技术文档]

基于航顺芯片HK32F103的CAN的驱动应用

[复制链接]
2942|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
SDLin|  楼主 | 2021-10-19 17:15 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
航顺芯片HK32F103系列是一款功能强大的32bit MCU,内部集成多个通信模块,其中CAN模块支持CAN协议2.0A2.0B。目前广泛应用的是CAN 2.0B协议,其收发数据速度高达1Mbps,有两种不同长度的ID标识符,一种是11位的,一种是29位的。该CAN协议的主要特点为:
(1) 多主控制
在总线空闲时,所有的单元都可开始发送消息。
(2) 消息的发送
        CAN 协议中,所有的消息都以固定的格式发送。总线空闲时,所有与总线相连的单元都可以开始发送新消息。两个以上的单元同时开始发送消息时,根据标识符( Identifier 以下称为 ID)决定优先级。 ID 并不是表示发送的目的地址,而是表示访问总线的消息的优先级。两个以上的单元同时开始发送消息时,对各消息ID的每个位进行逐个仲裁比较。仲裁获胜(被判定为优先级最高)的单元可继续发送消息,仲裁失利的单元则立刻停止发送而进行接收工作。即多个单元同时开始发送时,发送高优先级 ID 消息的单元可获得发送权。
(3) 系统的柔软性
        与总线相连的CAN节点没有类似于“地址”的信息。因此在总线上增加CAN节点时,连接在总线上的其它CAN节点的软硬件及应用层都不需要改变。
(4) 通信速度
        根据整个网络的规模,可设定适合的通信速度。在同一网络中,所有CAN节点必须设定成统一的通信速度。即使有一个CAN节点的通信速度与其它的不一样,此CAN节点也会输出错误信号,妨碍整个网络的通信。不同网络间则可以有不同的通信速度。
(5) 远程数据请求
        可通过发送“遥控帧” 请求其他CAN节点发送数据。
(6) 错误检测功能·错误通知功能·错误恢复功能
        所有的CAN节点都可以检测错误(错误检测功能)。
检测出错误的CAN节点会立即同时通知其他所有CAN节点(错误通知功能)。
正在发送消息的CAN节点一旦检测出错误,会强制结束当前的发送。强制结束发送的CAN
节点会不断反复重新发送此消息直到成功发送为止(错误恢复功能)。
(7) 故障封闭
        CAN 可以判断出错误的类型是总线上暂时的数据错误(如外部噪声等)还是持续的数据错误(如单元内部故障、驱动器故障、断线等)。由此功能,当总线上发生持续数据错误时,可将引起此故障的CAN节点从总线上隔离出去。
(8) 位填充: CAN通信的同步信息包含于传输数据中,电平的跳转提供了同步信息,如果连续多个相同的总线值出现,这将影响到同步信息的提取。为此CAN采用位填充规则,即在一帧中的帧起始,仲裁场,控制场,数据场和CRC场部分( CRC界定符,应答帧和结束除外),当发送器检测到5个具有相同数值的连续位时,将自动插入一个补码位。接收节点收到5个连续位后下一位自动删除。
(9) 连接
        CAN 总线是可同时连接多个CAN节点的总线。可连接的节点总数理论上是没有限制的。但实际上可连接的节点数受总线上的时间延迟及电气负载的限制。降低通信速度,可连接的CAN节点数增加;提高通信速度,则可连接的CAN节点数减少。如下是CAN通信速度和距离对应图:
(9) CAN总线物理框架可以抽象为
MCU(微处理器) <--> CAN控制器 <--> CAN收发器 <--> CAN数据传输总线(CAN-H,CAN-L)。如下图示:
CAN总线的数据传输线——>两条双向数据线,分为高位﹝CAN-H﹞和低位﹝CAN-L﹞数据线, 为了防止外界电磁波干扰和向外辐射,两条数据线缠绕在一起,要求至少每 2.5cm 就要扭绞一次,两条线上的电位是相反的,电压的和总等于常值。
CAN总线的终端电阻——>防止数据在到达线路终端后象回声一样返回,并因此而干扰原始数据,从而保证了数据的正确传送,终端电阻装在控制单元内。
CAN总线帧类型:
        数据帧-Data frame
        携带数据从发送节点到接收节点。
        分为标准帧(11位标识符)和扩展帧(29位标识符)。
        远程帧-Remote frame
向其他节点请求发送具有同一标识符的数据帧, 远程帧也有标准帧和扩展帧两种格式。
例如CAN节点A需要知道CAN节点B的油温温度,CAN节点A发送一个远程帧给节点B,节点B收到该远程帧后发送一个带油温数据的数据帧给节点A

错误帧-Error frame
        节点检测到错误之后发送错误帧。
                错误标志: 主动错误标志(000000)和被动错误标志(111111)。
                错误界定符:11111111
        过载帧-Overload frame
        接收节点通知其尚未做好接收准备, 过载标志(过载标志重叠部分)+过载标志界定符
       
以下是关于CAN/报文中各个部分的说明:
帧起始SOF
0,占用1位。当总线空闲时发送,用于CAN总线上的每个节点的信息同步。
仲裁段ID+RTR
                ID:
                        表示数据帧的优先级,先发送高位再发送低位。 11位或29位长度。
                RTR(Remote Transmit Request):
                        0: 表示该CAN帧是数据帧。
                        1: 表示该CAN帧是远程帧。
控制段IDE+r0+DLC
        IDE(IDentifier Extension):
                0: 标准格式
                1: 扩展格式
        保留位r0:
                0
                保留位r1:
                        0
                DLC(Data Length Code):
                        表示数据域中的字节数,范围0~8.
数据段Data
CRCCRC Sequence+CRC界定符
        CRC polynomial:
x15+x14+x10+x8+x7+x4+x3+1
        CRC界定符:
                1.
ACKACK Slot+ACK界定符
接收到匹配CRC序列的节点会在应答位期间,写0在发送器的隐性位作为回应。
        ACK界定符:
                1.
帧结束EOF
        1111111,表示数据帧或远程帧的结束。
SRR(Substitute Remote Request):
        1, 扩展帧中代替RTR.
CAN总线通信机制报文发送
        -载波侦听和带冲突检测协议的多路访问( CSMA/CD)
-发送节点:回读;
接收节点:监听
-线与机制:
所有节点发送1,总线上才是1;有一个节点发送0,总线上就是0,即高电平是隐性位,低电平是显性位。
-总线仲裁:如果有两个或两个以上的节点同时向总线上发送数据,标识符小的获得仲裁,标识符大的退出仲裁(回读和线与)。
例如:
ID1:00000000010
ID2:00000000001
CAN总线通信机制报文接收
        如果总线上有数据正在发送,所有节点都会接收总线数据,只有通过接收节点的报文过滤规则才能被节点接收进控制器。
       
CAN错误状态:
主动错误状态:主动错误状态是可以正常参加总线通信的状态。处于主动错误状态的单元检测出错误时,输出主动错误标志。
    被动错误状态: 被动错误状态是易引起错误的状态。 处于被动错误状态的单元检测出错误时,输出被动错误标志。处于被动错误状态的单元即使检测出错误,而其它处于主动错误状态的单元如果没发现错误,整个总线也被认为是没有错误的。
  总线关闭状态:总线关闭态是不能参加总线上通信的状态。信息的接收和发送均被禁止。
错误类型:
现在,我们以航顺芯片的HK32F103VET6(LQFP-100)为例来说明CAN通信的驱动实现。HK32F103VET6是航顺芯片的一款功能强大的32MCU,内部集成CAN控制器,因此进行CAN通信时,只需要外接一个CAN收发器。
HK32F103芯片的datasheet,如下截图我们得知,CAN的发送引脚为PA12,接收引脚为PA11
HK32F103芯片的用户手册,如下截图,得知需要把CAN的发送引脚PA12设置为推挽复用输出,CAN的接收引脚PA11设置为浮空输入或上拉输入。
详细的GPIO配置,依据该芯片的用户手册的表8-1
因此,软件中对引脚的设置如下:
这里,我们使用TJA1050作为CAN收发器,原理示意图如下:
CAN_D连接HK32F103VET6芯片的引脚PA12CAN_R连接HK32F103VET6芯片的引脚PA11CANLCANH接外部CAN总线(即前文提到的CAN-LCAN-H)。
软件驱动方面,首先应该使能CAN模块的时钟,如下:
HK32F103VET6芯片CAN模块(后续我们简称其为bxCAN)有3个主要的工作模式:初始化、正常和睡眠模式。在硬件复位后,bxCAN 工作在睡眠模式以节省电能,同时 CANTX 引脚的内部上拉电阻被激活。软件通过对 CAN_MCR 寄存器的INRQ或SLEEP 位置’1’,可以请求 bxCAN 进入初始化或睡眠模式。一旦进入了初始化或睡眠模式,bxCAN 就对 CAN_MSR 寄存器的 INAK SLAK 位置’1’来进行确认,同时内部上拉电阻被禁用。当INAK SLAK 位都为’0’时,bxCAN 就处于正常模式。在进入正常模式前,bxCAN 必须跟 CAN 总线取得同步;为取得同步,bxCAN 要等待 CAN 总线达到空闲状态,即在 CANRX 引脚上监测到 11 个连续的隐性位。
因此我们需要把CAN模块设置为初始化模式,如下:
在初始化模式设置成功之后,根据具体应用的要求,设置自动离线(Bus-Off)管理、自动唤醒模式、是否禁止报文自动重传、接收FIFO锁定模式、发送 FIFO 优先级等,如下示例:
CAN通信过程中,很重要的一点是设置通信速率,bxCAN的通信速率设置依据HK32F103VET6用户手册中的:
我们现在要设置500Kbps的通信速度,那么需要设置APB时钟频率为36MHz,还需要设置位BRP=3TS1=8TS2=7,如下:
至此,CAN初始化中几个重要特性已经设置好,可以把CAN模块设置位正常模式,以便正常地发送报文。从初始化模式切换为正常模式的设置,如下:
报文的发送,其核心在于正确操作CAN_TIxRCAN_TDTxRCAN_TDLxRCAN_TDHxR寄存器,如下为例,发送标准格式的ID=0x128字节长度的CAN数据帧报文。
并通过对应的状态寄存器检查发送成功与否:
某个CAN节点要接收哪些CAN报文,由其CAN接收规则(或者称为接收过滤器)设定。在接收到有效的报文之前,应该先设置好其接收规则。为此,HK32F103VET6的bxCAN 控制器为应用程序提供了 14 个位宽可变的、可配置的过滤器组(13~0),以便只接收那些软件需要的报文。硬件过滤的做法节省了 CPU 开销,否则就必须由软件过滤从而占用很大 CPU开销。每个过滤器组x由2个32位寄存器,CAN_FiR1CAN_FiR2(CAN_FiRx) (i0..13x=1..2)】,组成。
每个过滤器组的位宽都可以独立配置,以满足应用程序的不同需求。根据位宽的不同,每个过滤器组可提供:
• 1 32 位过滤器,包括:STDID[10:0]、EXTID[17:0]、IDE RTR
• 2 16 位过滤器,包括:STDID[10:0]、IDE、RTR EXTID[17:15]
此外过滤器可配置为,屏蔽位模式和标识符列表模式。
在屏蔽位模式下,标识符寄存器和屏蔽寄存器一起,指定报文标识符的任何一位,应该按照“必须匹配”或“不用关心”处理。
在标识符列表模式下,屏蔽寄存器也被当作标识符寄存器用。因此,不是采用一个标识符加一个屏蔽位的方式,而是使用 2 个标识符寄存器。接收报文标识符的每一位都必须跟过滤器标识符相同。
过滤器组可以通过相应的 CAN_FM1R 寄存器配置。在配置一个过滤器组前,必须通过清除 CAN_FAR寄存器的 FACT 位,把它设置为禁用状态。通过设置 CAN_FS1R 的相应 FSCx 位,可以配置一个过滤器组的位宽,请参见下图。通过 CAN_FM1R FBMx 位,可以配置对应的屏蔽/标识符寄存器的标识符列表模式或屏蔽位模式。
我们以常用的一个32位过滤器+标识符屏蔽的方式为例进行说明。
如上图,“映像”行中,RTR对应CAN_FiRxbit1IDE对应CAN_FiRxbit2EXID对应CAN_FiRxbit3-bit20STID对应CAN_FiRxbit21-bit31。结合前文仲裁段和控制段所述,RTR0表示该CAN帧是数据帧,为1时表示该CAN帧是远程帧;IDE0时表示该CAN帧是标准格式,1时表示该CAN帧是扩展格式。标准格式下只用到STID位,扩展格式下还会用到EXID位。在32位过滤器+标识符屏蔽的方式应用中,“ID”行中,即CAN_FiR1寄存器用于设置CAN报文的ID、IDE、RTR。“屏蔽”行中,即CAN_FiR2寄存器用于设置接收报文过程中,是否比较ID、IDE、RTR这些对应的各个位,为0时表示“不用关心”,为1时表示“必须匹配”。以RTR为例,当设置CAN_FiR2的RTR为1“必须匹配”,且CAN_FiR1时RTR为0时,表示只接收数据帧,不接收远程帧;而当设置CAN_FiR2的RTR为0时“不用关心”,表示无论是数据帧还是远程帧,都会进行接收。
下面,我们开始说明过滤器的具体设置。
首先应该设置过滤器组工作在初始化模式并暂时禁用过滤器,如下:
接着设置过滤器的位宽是单个32位,及工作在标识符屏蔽位模式下,如下:
假设我们现在只需要接收两条CAN标准数据帧,且其ID分别为0000000000000000000001,那么应该设置IDE0RTR0CAN_FiR10CAN_FiR20xFFC00006,如下:
接着设置接收到的报文存放于哪个FIFO,这里我们存放到FIFO 0,如下:
最后重新激活过滤器和设置过滤器工作在正常模式:
现在,该CAN节点就可以接收CAN ID分别为0000000000000000000001的标准数据帧,收到后CAN报文是存储于FIFO 0中,CPUFIFO 0 中读取数据,供上层应用使用。

使用特权

评论回复

相关帖子

沙发
HSXP063| | 2021-10-21 17:15 | 只看该作者
好文, 很详细 ,

使用特权

评论回复
板凳
两只袜子| | 2021-10-22 09:04 | 只看该作者
好文, 很详细

使用特权

评论回复
地板
SDLin|  楼主 | 2021-10-25 18:11 | 只看该作者
希望这可以帮助需要的人更好地理解HK32F103的CAN模块的底层驱动

使用特权

评论回复
5
嵌入小菜菜| | 2021-10-27 16:11 | 只看该作者
这个芯片确实不错的,而且是CAN的应用也没有任何的问题的。

使用特权

评论回复
6
岚夜| | 2021-11-3 21:11 | 只看该作者
我就想知道 用于计算STM32 的CAN波特率的参数 的那个工具,能不能用在HK32 上

使用特权

评论回复
7
SDLin|  楼主 | 2021-11-4 08:38 | 只看该作者
岚夜 发表于 2021-11-3 21:11
我就想知道 用于计算STM32 的CAN波特率的参数 的那个工具,能不能用在HK32 上

具体是哪个?可以做个实验,测下就知道了。

使用特权

评论回复
8
redone| | 2021-11-8 15:39 | 只看该作者
这个够我学几天的了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

5

主题

123

帖子

1

粉丝