☆ can协议基础知识 i2c.spi总线多用于短距离传输,协议简单,数据量少,主要用于ic之间的通讯,而 can 总线则不同,can(controller area network) 总线定义了更为优秀的物理层、数据链路层,并且拥有种类丰富、简繁不一的上层协议。与i2c、spi有时钟信号的同步通讯方式不同,can通讯并不是以时钟信号来进行同步的,它是一种异步通讯,只具有can_high和can_low两条信号线,共同构成一组差分信号线,以差分信号的形式进行通讯。
can物理层的形式主要分为闭环总线及开环总线网络两种,一个适合于高速通讯,一个适合于远距离通讯。can闭环通讯网络是一种遵循iso11898标准的高速、短距离网络,它的总线最大长度为40m,通信速度最高为1mbps,总线的两端各要求有一个 “120欧”的电阻来做阻抗匹配,以减少回波反射。
☆ 闭环总线网络 can开环总线网络是遵循iso11519-2标准的低速、远距离网络,它的最大传输距离为1km,最高通讯速率为125kbps,两根总线是独立的、不形成闭环,要求每根总线上各串联有一个“2.2千欧”的电阻。
☆ 开环总线网络
can总线上可以挂载多个通讯节点,节点之间的信号经过总线传输,实现节点间通讯。由于can通讯协议不对节点进行地址编码,而是对数据内容进行编码,所以网络中的节点个数理论上不受限制,只要总线的负载足够即可,可以通过中继器增强负载。
can通讯节点由一个can控制器及can收发器组成,控制器与收发器之间通过can_tx及can_rx信号线相连,收发器与can总线之间使用can_high及can_low信号线相连。其中can_tx及can_rx使用普通的类似ttl逻辑信号,而can_high及can_low是一对差分信号线,使用比较特别的差分信号。当can节点需要发送数据时,控制器把要发送的二进制编码通过can_tx线发送到收发器,然后由收发器把这个普通的逻辑电平信号转化成差分信号,通过差分线can_high和can_low线输出到can总线网络。而通过收发器接收总线上的数据到控制器时,则是相反的过程,收发器把总线上收到的can_high及can_low信号转化成普通的逻辑电平信号,通过can_rx输出到控制器中。
☆ 差分信号 差分信号又称差模信号,与传统使用单根信号线电压表示逻辑的方式有区别,使用差分信号传输时,需要两根信号线,这两个信号线的振幅相等,相位相反,通过两根信号线的电压差值来表示逻辑0和逻辑1。
相对于单信号线传输的方式,使用差分信号传输具有如下优点:
抗干扰能力强,当外界存在噪声干扰时,几乎会同时耦合到两条信号线上,而接收端只关心两个信号的差值,所以外界的共模噪声可以被完全抵消。
能有效抑制它对外部的电磁干扰,同样的道理,由于两根信号的极性相反,他们对外辐射的电磁场可以相互抵消,耦合的越紧密,泄放到外界的电磁能量越少。
时序定位精确,由于差分信号的开关变化是位于两个信号的交点,而不像普通单端信号依靠高低两个阈值电压判断,因而受工艺,温度的影响小,能降低时序上的误差,同时也更适合于低幅度信号的电路。
由于差分信号线具有这些优点,所以在usb协议、485协议、以太网协议及can协议的物理层中,都使用了差分信号传输。 ☆ can协议中的差分信号 can协议中对它使用的can_high及can_low表示的差分信号做了规定。以高速can协议为例,当表示逻辑1时(隐性电平),can_high和can_low线上的电压均为2.5v,即它们的电压差v h -v l =0v;而表示逻辑0时(显性电平),can_high的电平为3.5v,can_low线的电平为1.5v,即它们的电压差为v h -v l =2v。
☆ can 总线的特点 can 总线网络是一种真正的多主机网络,在总线处于空闲状态时,任何一个节点单元都可以申请成为主机,向总线发送消息。其原则是:最先访问总线的节点单元可以获得总线的控制权;多个节点单元同时尝试获取总线的控制权时,将发生仲裁事件,具有高优先级的节点单元将获得总线控制权。
can 协议中,所有的消息都以固定的数据格式打包发送。两个以上的节点单元同时发送信息时,根据节点标识符(常称为 id,亦打包在固定的数据格式中)决定各自优先级关系,所以 id 并非表示数据发送的目的地址,而是代表着各个节点访问总线的优先级。如此看来,can 总线并无类似其他总线“地址”的概念,在总线上增加节点单元时,连接在总线的其他节点单元的软硬件都不需要改变。
can 总线的通信速率和总线长度有关,在总线长度小于 40m 的场合中,数据传输速率可以达到 1mbps,而即便总线长度上升至 1000m,数据的传输速率仍可达到 50kbps,无论在速率还是传输距离都明显优于常见的 rs232、rs485 和 i2c 总线。
对于总线错误,can 总线有错误检测功能、错误通知功能、错误恢复功能三种应对措施,分别应对于下面三点表述:所有的单元节点都可以自动检测总线上的错误;检测出错误的节点单元会立刻将错误通知给其他节点单元;若正在发送消息的单元检测到当前总线发生错误,则立刻强制取消当前发送,并不断反复发送此消息至成功为止。
can 总线上的每个节点都可以通过判断得出,当前总线上的错误是暂时的错误(如瞬间的强干扰)还是持续的错误(如总线断裂)。当总线上发生持续错误时,引起故障的节点单元会自动脱离总线。
can 总线上的节点数量在理论上没有上限,但在实际上受到总线上的时间延时及电气负载的限制。降低最大通信速率,可以增加节点单元的连接数;反之,减少节点单元的连接数,则最大通信速率可以提高。
can总线的数据通信是以数据帧的格式进行的,而数据帧又是由位场组成的,其中每一个位又被划分为四段.即ss(sync seg),pts(prop seg--传播时间段),pbs1(phase seg1--相位缓冲段1),pbs2(phase seg1--相位缓冲段2).
数据帧的结构图:
图中d表示显性电平,r表示隐形电平.id:高位在前,低位在后。基本id,禁止高7位都为隐性,即不能:id=1111111xxxx。rtr,远程请求位。0,数据帧;1, 远程帧;srr,替代远程请求位。设置为1(隐性电平);ide,标识符选择位。0,标准标识符;1,扩展标识符;r0,r1:保留位。必须以显现电平发送,但是接收可以是隐性电平。dlc:数据长度码。0~8,表示发送/接收的数据长度(字节)。ide,标识符选择位。0,标准标识符;1,扩展标识符; ☆ 位时序分解 为了实现位同步,can协议把每一个数据位的时序分解成ss段、pts段、pbs1段、pbs2段,这四段的长度加起来即为一个can数据位的长度。分解后最小的时间单位是tq,而一个完整的位由8~25个tq组成。
☆ stm32中的can接口 stm32的芯片中具有bxcan控制器 (basic extended can),它支持can协议2.0a和2.0b标准。该can控制器支持最高的通讯速率为1mb/s;可以自动地接收和发送can报文,支持使用标准id和扩展id的报文;外设中具有3个发送邮箱,发送报文的优先级可以使用软件控制,还可以记录发送的时间;具有2个3级深度的接收fifo,可使用过滤功能只接收或不接收某些id号的报文;可配置成自动重发;不支持使用dma进行数据收发。
1. can控制内核2. can发送邮箱3. can接收fifo 4. 验收筛选器
stm32有两组can控制器,其中can1是主设备,框图中的“存储访问控制器”是由can1控制的,can2无法直接访问存储区域,所以使用can2的时候必须使能can1外设的时钟。
stm32至少配备一个bxcan(basic extend can )控制器,支持2.0a和2.0b协议,最高数据传输速率可达1m bps,支持11位标准帧格式和29位扩展帧格式的接收和发送,具备三个发送邮箱和两个接收fifo,此wa此外还有三级可编程滤波器,stm32的bxcan非常适应can总线网络y网络应用发展需求,其主要主要特征如下 :
支持can协议2.0a和2.0b主动模式
波特率最高可达1mbps
支持时间触发通讯功能 数据发送特性:具备三个发送邮箱;发送报文的优先级可以通过软件配置,可记录发送时间的时间戳。
数据接收特性:具备三级深度和两个接收fifo;具备可变的过滤器组,具备可编程标识符列表,可配置fifo溢出处理方式,记录接收时间的时间戳报文管理:中断可屏蔽;邮箱单独占有一块地址空间,便于提高软件效率。本文的实验设计将利用stm32 的bxcan控制器的环回工作模式,实现bxcan控制器的自收发过程,并使用串口设备跟踪监视数据收发情况。程序流程如下图
本程序设计主要围绕bxcan控制器的初始化初始化配置展开,其要点罗列如下:
1. 初始化rcc寄存器,配置pll输出72mhz时钟,apb1总线频率为36mhz,分别打开can,gpio和usart1的设备时钟。
2. 设置can的tx引脚(即pa12)为复用推挽模式,并设置rx引脚(即pa1)为上拉输入模式,其中三个重要的参数如下配置:
can_initstructure.can_sjw配置为can_sjw_1tq;can_initstructure.can_bs1配置为can_bs1_8tq;can_initstructure.can_bs2配置为can_bs2_7tq; 3. 最后分频数配置为5,配置接受接受缓冲区标识符为0x00aa0000,配置过滤器为32位屏蔽位模式,过滤器屏蔽标识符为0x00ff0000.
4. 初始化usart设备
5. 使用扩展帧shu帧数据格式,id为0xaa,数据长度长度为8stm32的can控制器设计的重点集中在can寄存器组的初始化过程中,而can初始化的重点在于波特率的设置,过滤器的设置和位时序的设置,以下作详细叙述。 (1)can波特率的计算
计算波特率是任何一种总线的zhon重要内容之一,can总线也不例外.从stm32微控制器的官方参考手册里可以查找到关于can波特率的计算公式如下.
通过配置位时序寄存器can_btr的ts1[3:0]及ts2[2:0]寄存器位设定bs1及bs2段的长度后,就可以确定每个can数据位的时间:
bs1段时间:
t s1 =tq x (ts1[3:0] + 1), bs2段时间:
t s2 = tq x (ts2[2:0] + 1), 一个数据位的时间:
t 1bit =1tq+t s1 +t s2 =1+ (ts1[3:0] + 1)+ (ts2[2:0] + 1)= n tq
其中单个时间片的长度tq与can外设的所挂载的时钟总线及分频器配置有关,can1和can2外设都是挂载在apb1总线上的,而位时序寄存器can_btr中的brp[9:0]寄存器位可以设置can外设时钟的分频值 ,所以:
tq = (brp[9:0]+1) x t pclk其中的pclk指apb1时钟,默认值为36mhz。 最终可以计算出can通讯的波特率:
baudrate = 1/n tq程序设计要点中强调的三个重要参数,其实是can总线物理层中所要求的位时序。共三个阶段,分别为sjw,bs1和bs2阶段,这三个阶段的时间长度都是以长度为tq的时间单元为单位的。这样可以逐步计算出can总线的波特率。因此要点提示中所要求的参数,实际上将can的波特率设置为450kdps。过滤器的设置 can总线没有所谓地址的概念。总线上的每个报文都可以被各个节点接收。这是一种典型的广播式网络。在实际应用中。某个节点往往只希望接收到特定类型的数据, 这就要借助过滤器来实现。顾名思义,过滤器的作用就是把节点不希望接收到的数据过滤掉。只将希望接收到的数据给予通行。
stm32的can控制器,提供14个过滤器。可以设置为屏蔽模式和列表模式对can总线上的报文进行过滤。当节点希望接收到一种报文时。可以用屏蔽位模式对can总线上的报文进行过滤。反之,当节点希望接受到单一类型报文时。则应该配置为列表模式。本机程序中使用了32位的屏蔽位模式。
下面仅对这种模式进行解析。can控制器的每个过滤器都具备一个寄存器。称为屏蔽寄存器。其中标识符寄存器的每一位都有屏蔽寄存器的每一位所对应。事实上,这也对应着can数据。事实上,这也对应着看标准数据帧中的标识符段。
如下图所示。此处重点在于屏蔽寄存器的作用。通过查阅stm32微控制器参考文档可以知道。当过滤器工作在屏蔽模式下时。屏蔽寄存器被置为1的每一位都要求can接收到的数据帧标识符段必须和对应的接收缓冲区标识位相同。否则予以滤除。以本程序为例。要点中要求将节点接收缓冲标识符配置为0x00aa0000。过滤器屏蔽标识符为0x00ff0000。该节点接收到的数据帧的标识符段的位[23:16],必须和接收缓冲区标识符中的[23:16]匹配。否则予以滤除。但若满足了这一条件而即便如下的位不匹配。则该数据帧仍不会被滤除。正如本程序而言。即can接口仅仅接收标识符段的位[23:16]为0xaa的数据帧. 根据can总线物理层的要求。can总线的波特率和传输距离成反比关系。传输距离变化时,要根据位时序来调整can总线的波特率。
程序代码如下: void rcc_config(void){rcc_apb2periphclockcmd(rcc_apb2periph_gpioa|rcc_apb2periph_usart1,enable) rcc_apb1periphclockcmd(rcc_apb1periph_can1,enable) }void gpio_for_can_and_uart_config(void){/*定义一个gpio_inittypedef类型的结构体*/gpio_inittypedef gpio_initstructure; /*设置can的rx--pa.11引脚*/gpio_initstructure.gpio_pin = gpio_pin_11;gpio_initstructure.gpio_mode = gpio_mode_ipu;gpio_init(gpioa, &gpio_initstructure);/*设置can的tx--pa.12引脚*/gpio_initstructure.gpio_pin = gpio_pin_12;gpio_initstructure.gpio_mode = gpio_mode_af_pp;gpio_initstructure.gpio_speed= gpio_speed_50mhz;gpio_init(gpioa, &gpio_initstructure);/*设置usart1 的rx 脚 -pa.10为父浮空输入脚*/gpio_initstructure.gpio_pin = gpio_pin_10;gpio_initstructure.gpio_mode = gpio_mode_in_floating;gpio_init(gpioa, &gpio_initstructure); } void can_config(void){can_inittypedef can_initstructure;can_filterinittypedef can_filterinitstructure; can_deinit(can1); can_structinit(&can_initstructure);can_initstructure.can_ttcm=disable;can_initstructure.can_abom=disable;can_initstructure.can_awum=disable;can_initstructure.can_nart=disable;can_initstructure.can_rfim=disable;can_initstructure.can_txfp=disable; can_initstructure.can_mode=can_mode_loopback;can_initstructure.can_sjw=can_sjw_1tq;can_initstructure.can_bs1=can_bs1_8tq;can_initstructure.can_bs2=can_bs2_7tq; can_initstructure.can_prescaler=5;can_init(can1,&can_initstructure); can_filterinitstructure.can_filternumber=0;can_filterinitstructure.can_filtermode=can_filtermode_idmask;can_filterinitstructure.can_filterscale=can_filterscale_32bit;can_filterinitstructure.can_filteridhigh=0x00aa<<3;can_filterinitstructure.can_filteridlow=0x0000;can_filterinitstructure.can_filtermaskidhigh=0x00ff<<3;can_filterinitstructure.can_filtermaskidlow=0x0000;can_filterinitstructure.can_filterfifoassignment=0;can_filterinitstructure.can_filteractivation=enable;can_filterinit(&can_filterinitstructure); } void main(void){u8 transmitmailbox=0;cantxmsg txmessage;canrxmsg rxmessage;rcc_config();gpio_for_can_and_uart_config();usart_config();can_config(); txmessage.extid=0x00aa0000;txmessage.rtr=can_rtr_data;txmessage.ide=can_id_ext;txmessage.dlc=8;txmessage.data[0]=0x00;txmessage.data[1]=0x12;txmessage.data[2]=0x34;txmessage.data[3]=0x56;txmessage.data[4]=0x78;txmessage.data[5]=0xab;txmessage.data[6]=0xcd;txmessage.data[7]=0xef; transmitmailbox=can_transmit(can1,&txmessage);while((can_transmitstatus(can1,transmitmailbox))!=cantxok);printf(rnthe can has send data :0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,rn,txmessage.data[0],txmessage.data[1],txmessage.data[2],txmessage.data[3],txmessage.data[4],txmessage.data[5],txmessage.data[6],txmessage.data[7],); while((can_messagepending(can1,can_fifo0)==0));rxmessage.stdid=0x00;rxmessage.ide=can_id_ext;rxmessage.dlc=0;rxmessage.data[0]=0x00;rxmessage.data[1]=0x12;rxmessage.data[2]=0x34;rxmessage.data[3]=0x56;rxmessage.data[4]=0x78;rxmessage.data[5]=0xab;rxmessage.data[6]=0xcd;rxmessage.data[7]=0xef; can_receive(can1,can_fifo0,&rxmessage);printf(rnthe can has received data :0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,rn,rxmessage.data[0],rxmessage.data[1],rxmessage.data[2],rxmessage.data[3],rxmessage.data[4],rxmessage.data[5],rxmessage.data[6],rxmessage.data[7],);while(1); }
小米6发布前夕彩排现场遭曝光:骁龙835+曲面屏+双摄,小米的配置这次是没谁了
未来四年全球汽车ABS和EPB传感器电缆市场年复合增7%
安兔兔发布了2018年12月份的Android手机性能排行榜
线性稳压器的稳定性优化简易方法-阶跃响应波形和相关部件常数
联想A5体验 各方面都十分均衡的百元机
STM32中CAN总线接口发送和接收数据
6月动力电池市场:车企和电池企业如何和谐相处?
华为新闻 华为手机供应商大部分是外国厂商 三星全球手机份额第一
新纳米涂层技术让汽车告别洗车
汽车导航产品存两大使用隐患
浅谈高端惯性传感器技术的未来运用市场
802D数控铣床调试的步骤
EMI/EMC入门学习方法分享
5G手机都有哪些?OPPO Reno5G版年前将与“藕粉”见面
Imagination在中国首次发布GPU内核 开始全新征程
24588元 微软Surface Book增强版国行开售
5G的起航有那么顺利吗
电磁流量计的测量原理及优劣势
USB扩展卡无法使用故障处理
碳化硅MOSFET在6.6kW高频高功率密度功率变换器中的应用