1.CAN通讯的理解
想学习CAN通讯,那么要对通讯协议有一定的认知。通讯协议是指通信双方对数据传送控制的一种约定。约定中包括对数据格式,同步方式,传输速度,传送步骤,检纠错方式以及控制字符定义等问题做出统一规定,通信双方必须共同遵守。
CAN通讯全称控制器局域网通讯,是用来在局域网中高效传输,处理信息的一种通讯方式。它采用数据块编码的方式,数据块根据帧类型的不同有四种格式,可使不同的节点接收到相同的数据,然后再根据各节点内CAN配置选择处理还是丢弃该信息(这与TCP/IP协议栈的链路层的MAC地址过滤很相似,是可以互通理解的),CAN的位流是按照非归零(NRZ)码方式编码,一个完整的位电平有显性和隐性两种方式。显性和隐性是根据CAN总线上的差分电压VCAN1H-VCAN1L, 若小于阈值则为隐性位,代表逻辑1,大于阈值则为显性位,代表逻辑0,这种将单电平转换成两根差分线的方式提高了电路的可靠性,不过也决定局域网里同时只能有一路数据传输,因此CAN通讯是半双工的。
2.CAN通讯帧格式
CAN报文有四种不同的帧类型:
(1).数据帧:数据帧将数据从发送器传输到接收器。
数据帧和可以使用标准帧和扩展帧两种格式。它们用一个帧间空间与前面的帧分隔。
1).帧起始(SOF) 标志帧的开始,由一个“显性(0)”位构成。只有在总线空闲时才允许节点发送(信号),其它所有节点必须同步于首先开始发送报文的节点的帧起始前沿。
2).仲裁场 由标识符和传送帧类型(RTR)组成的仲裁场
标准帧格式:
扩展帧格式:
对于数据帧 RTR恒为0,SRR恒为1,因此可以根据仲裁场起始第12个字符数判断是标准帧还是扩展帧。
3).控制场 保留位R1,R0(恒为0),以及帧长度选择位DLC(4位)构成的。
4).数据场 由数据帧里的发送数据组成,长度由DLC控制,但小于等于8字节。
5).CRC场 由CRC序列(CRC Sequence),以及CRC界定符(CRC Delimiter)构成。CRC序列之后是CRC界定符,它包含一个单独的“隐性(1)”位。
6).应答场(ACK Field) 2位,包含应答间隙(ACK Slot)和应答界定符(ACK Delimiter),当接收器正确地接收到有效的报文,接收器就会在应答间隙(ACK Slot)中写入显性位(0),在返回给发送器,完成一次通讯(半双工).
① 应答间隙
所有接收到匹配CRC序列的节点会在应答间隙期间用“显性(0)”的位写入发送器的“隐性(1)”位来组成应答数据。
② 应答界定符
应答界定符是应答场的第二位,并且必须为“隐性(1)”的位。因此,应答间隙(ACK Slot)被两个“隐性”的位所包围,也就是CRC界定符和应答界定符。
7).帧结束 由7个隐性位构成,代表帧的结束。
(2).远程帧:总线节点发出远程帧,请求发送具有同一识别符的数据帧。
远程帧除了RTR位默认为1,没有数据场外,其它与数据帧相同,不在赘述。
(3).错误帧:报文发送过程中,检测到任一节点出错,即于下一位发送出错帧,通知发送端停止发送。
错误标志:有两种形式的错误标志:激活错误标志和认可错误标志。
1).激活错误”标志由6个连续的“显性”位组成
2).“认可错误”标志由6个连续的“隐性”的位组成,除非被其他节点的“显性”位重写。
错误界定符:错误界定符包括8个“隐性”的位。
错误标志传送了以后,每一个节点就发送一个“隐性”的位,并一直监视总线直到检测出一个“隐性”的位为止,然后就开始发送其余7个“隐性”位。
(4).过载帧:接收端用于要求发送端延缓发送下一个数据帧或者远程帧。
1).超载标志: 过载标志由6个“显性”的位组成。过载标志的所有形式和“激活错误”标志的一样
2).过载界定符包括8个“隐性”的位,具体动作与错误界定符一致
CAN通讯是数据块编码的半双工通讯方式,没有主从设备区别,因此发出报文的节点为该报文的发送器,该节点在总线空闲或丢失仲裁前恒为发送器;如果一个节点不是报文发送器,并且总线不处于空闲状态,则该节点为接收器。
3.CAN通讯的STM32实现
CAN协议是比较复杂的一种通讯协议,因此需要在学习如何使用stm32实现前了解协议本身的很多内容,下面就可以开始stm32中CAN协议环回测试,用来简单的理解CAN协议的测试。既然是要STM32实现,那么步骤的设计如下:
(1).工作原理图
了解了CAN通讯,下面进入正题,CAN通讯连接首先看原理图如下:
从上面可以看出CAN1_TX: PD1 CAN1_RX PD0
(2).CAN硬件驱动配置
CAN通讯端口配置还是比较简单的:
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_AFIO, ENABLE);
GPIO_InitStructure.GPIO_Pin = CAN1_TX_Pin;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //将CAN1输出端PD1配置为推挽输出模式
GPIO_Init(CAN1_TX_Port,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = CAN1_RX_Pin;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //将CAN1输入端PD0配置为浮空输入
GPIO_Init(CAN1_RX_Port, &GPIO_InitStructure);
CAN通讯模式配置(因为是简单的测试,因此配置为环回模式,过滤器配置为屏蔽位模式)
void CAN1_MODE_Config(void) { CAN_InitTypeDef CAN_InitStructure; CAN_FilterInitTypeDef CAN_FilterInitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); CAN_DeInit(CAN1); CAN_InitStructure.CAN_ABOM = DISABLE; //离线模式由软件实现 CAN_InitStructure.CAN_AWUM = DISABLE; //软件唤醒 CAN_InitStructure.CAN_TTCM = DISABLE; //禁止时间触发通信模式 CAN_InitStructure.CAN_NART = ENABLE; //禁止自动重传 CAN_InitStructure.CAN_TXFP = DISABLE; //优先级由报文的标识符来决定 CAN_InitStructure.CAN_RFLM = DISABLE; //接受溢出时FIFO不锁定,下一个收到的报文覆盖原有报文 CAN_InitStructure.CAN_Mode = CAN_Mode_LoopBack; //CAN硬件工作环回模式 CAN_InitStructure.CAN_SJW = CAN_SJW_1tq; //重新同步跳跃宽度为2个时间单位 CAN_InitStructure.CAN_BS1 = CAN_BS1_8tq; //时间段为8个时间单位 CAN_InitStructure.CAN_BS2 = CAN_BS2_7tq; //时间段为7个时间单位 CAN_InitStructure.CAN_Prescaler = 5; //设定一个时间单位的长度为5,范围(1~1024) CAN_Init(CAN1, &CAN_InitStructure); CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask; //设定过滤器组为屏蔽位模式 CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit; //过滤器位宽为32位过滤器一个 CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000; //设定过滤器标识符高位(32为高位段,16位为第一个) CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000; //设定过滤器标识符低位(32为低位段,16位为第二个) CAN_FilterInitStructure.CAN_FilterMaskIdHigh= 0x0000; //设定过滤器标识符高位(32为高位段,16位为第一个) CAN_FilterInitStructure.CAN_FilterMaskIdLow= 0x0000; //设定过滤器标识符低位(32为低位段,16位为第二个) CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0; //过滤器FIFO0指向过滤器0 CAN_FilterInitStructure.CAN_FilterNumber = 1; //指定待初始化的过滤器,范围1~13 CAN_FilterInitStructure.CAN_FilterActivation = ENABLE; //使能过滤器 CAN_FilterInit(&CAN_FilterInitStructure); CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE); //FIF0消息挂号中断允许 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn; //CAN1_RX0中断向量表中开启 NVIC_Init(&NVIC_InitStructure); }
完成了驱动方面的配置,下面要进行的就是发送CAN数据和接收CAN数据的生成和实现了:
//CAN发送帧构成
void CAN_TxMessageInit(uint32_t std_id, uint32_t ext_id, uint8_t ide, uint8_t rtr, uint8_t dlc, uint8_t *pdata)
{
uint8_t i;
assert_param(dlc>8);
CanTxMessage.StdId = std_id&0x7ff; //设定标准标识符0~0x7ff 11位
CanTxMessage.ExtId = ext_id&0x3ffff; //设定额外标识符0~0x3ffff 18位
CanTxMessage.IDE = ide; //输出标识符类型,STD(标准标识符)或EXT(额外标识符)
CanTxMessage.RTR = rtr; //输出帧类型,DATA(数据帧)或者REMOTE(远程帧)
CanTxMessage.DLC = dlc; //帧长度,0~8
for(i=0; i CanTxMessage.Data[i] = *(pdata+i); } } //CAN中断接收函数 void CAN1_RX0_IRQHandler(void) { ITStatus Status;
上一篇:STM32F105 CAN总线数据收发调试
下一篇:stm32f103 学习笔记 —— 07 CAN通讯协议
推荐阅读
史海拾趣
面对电子行业日益激烈的市场竞争,GD Rectifiers Ltd通过并购整合的方式加速了自身的发展步伐。公司精心挑选了几家在细分领域具有领先地位的竞争对手,通过友好协商和合理估值,成功完成了对这些企业的并购。并购后,GD Rectifiers Ltd充分利用被并购企业的技术优势和市场份额,实现了产品线的进一步丰富和销售渠道的拓展。同时,公司还加强了对内部资源的整合和优化,提高了整体运营效率和市场竞争力。
面对数字化时代的到来,GD Rectifiers Ltd主动拥抱变革,积极推进数字化转型。公司投入巨资建设了先进的数字化生产管理系统和客户关系管理系统,实现了生产过程的智能化和透明化。通过数据分析和挖掘技术,公司能够更准确地把握市场需求和客户需求的变化趋势,为产品研发和市场营销提供有力支持。同时,公司还加强了与供应商和客户的数字化连接和协作,提高了供应链的协同效率和响应速度。数字化转型的成功实施为GD Rectifiers Ltd注入了新的活力,进一步提升了公司的市场竞争力和行业地位。
随着全球对环境保护问题的日益关注,GD Rectifiers Ltd积极响应并践行绿色环保理念。公司投入大量资源进行绿色产品的研发和生产,推出了一系列符合环保标准的整流器产品。这些产品不仅具有高效、节能的特点,还大幅降低了生产和使用过程中的环境污染。同时,公司还加强了对废弃物的处理和回收利用工作,努力实现生产全过程的绿色化。GD Rectifiers Ltd的环保行动赢得了社会各界的广泛赞誉和支持,为公司的可持续发展奠定了坚实基础。
在电源适配器和服务器电源市场,EUtech公司凭借技术创新迅速崛起。他们不断优化产品设计,提高产品性能,同时注重节能环保。随着下游AI行业的快速发展,公司及时抓住机遇,推出了一系列高性能、高可靠性的电源产品,赢得了市场的广泛认可。
自1958年成立以来,Chemtronics公司在电子维护和维修领域不断进取。最初,公司专注于生产一系列清洁剂产品,以其高效清洁能力获得了市场的认可。随着时间的推移,Chemtronics逐渐将产品线扩展至超纯溶剂、净化室级别擦拭棒和擦拭布等领域,进而又扩展到电子电气和电信工业的精密返工和维修工具。这一转变不仅体现了公司对市场需求的敏锐洞察,也彰显了其不断创新的精神。
http://circuit.eeworld.com.cn/view/6656/ 这是小弟问的电路图的网址,想问下各位高手这个图各部分的工作原理和各部分的作用.谢谢了… 查看全部问答∨ |
|
本人在TPMS以及防盗器行业已经混了5年了,总的来说,已经从对TPMS和防盗器的懵懂状态走了出来,现将自己的体会,谈下,请对此行业有兴趣的朋友可以交流! 一、 TPMS,这是个让人喜欢让人忧的产品,让人喜欢的是他真正 ...… 查看全部问答∨ |
各位英雄,俺觉得初级工程师很没意思,也不考试什么的,还得交180块大洋,那帮人对你又一点了解也没有,只要把钱交到 就基本ok。 俺又没钱,现在毕业一年了 公司有申报初级工程师的。各位大侠指导下,你说俺能不能,等4or5年后,直接考中级,行不行 ...… 查看全部问答∨ |
大家好,小弟是一个新手,最近准备在Linux环境下根据spi协议为一款单片机写一个光学传感器的驱动程序,因为以前从来没有过这方面的经验,所以觉得无从下手,所以希望各位有这方面经验的高手们帮忙指点一下,我现在应该做些什么,具体应该分成哪些步骤,需要 ...… 查看全部问答∨ |
|
我想买个WINCE系统的手机练练wince系统下的编程. 我已经找好了几款手机 酷派的 6168H(cup:Samsung) 8310(cup:TI) 2938(cup:ARM9) 但发现他们用的CPU是不同厂商的. 请问:不同cup要用不同的SDK吗? 到手机的官网没有找到相关的SDK, 我 ...… 查看全部问答∨ |
是这样子D~ 做了几块板子 就有一块跑起来了 JTAG能检测到CPU 能检测到NORFLASH NANDFLASH的ID 能下BOOTLOADER到NORFLASH NANDFLASH 并从FLASH拷到SDRAM运行 能跑起WINCE 那么我们先认为硬件设计是没有问题D~~ 但是有板子情况如下: 1、晶 ...… 查看全部问答∨ |
ADI实验电路CN0197基于AD7280A的电池管理系统进度汇报 具体方案提交已经有一段时间了 很高兴能够入围。这段时间在等待芯片的同时也做了一系列工作,现汇报一下工作进展1.在熟悉ad7280a芯片用途之后,根据数据手册选定单片机,由于最初的想法是方便使用,节约成本,所以就手头而言,只有pic的仿真器icd2 ...… 查看全部问答∨ |