一.CAN简介 CAN是控制器局域网络(Controller Area Network, CAN)的简称,是由以研发和生产汽车电子产品著称的德国BOSCH公司开发的,是国际上应用最广泛的现场总线之一。 CAN控制器通过组成总线的2根线(CAN-H和CAN-L)的电位差来确定总线的电平,信号是以两线之间的“差分”电压形式出现,总线电平分为显性电平和隐性电平。 CAN总线采用两种互补的逻辑数值"显性"和"隐性"。"显性"数值表示逻辑"0",而"隐性"表示逻辑"1"。当总线上同时出现“显性”位和“隐性”位时,最终呈现在总线上的是“显性”位。 在“隐性”状态下,VCAN_H和VCAN_L被固定与平均电压电平,Vdiff近似为零,此时VCAN_H和VCAN_L的标称值为2.5V。 “显性”位以大于最小阀值的差分电压表示,此时VCAN_H的标称值为3.5V,VCAN_L的标称值为1.5V。 本实验采用SN65HVD230芯片作为CAN收发器,其逻辑电路图以及管脚图如下。D为CAN发送,R为CAN 接收。CAN-H,CAN-L为CAN总线。CAN收发器即将TTL电平转换为CAN总线电平。 在总线空闲时,所有的单元都可开始发送消息(多主控制)。所有的消息都以固定的格式发送。 二.CAN帧结构 报文传输由以下4个不同的帧类型所表示和控制: 1.数据帧 数据帧由7个不同的域组成。 (1)帧开始(Start of Frame) 这个域表示数据帧的开始。仅由一个“显性”位组成. (2)仲裁域(Arbitration Frame) 这个域表示一个帧的优先级,仲裁场由标识符和远程发送请求位(RTR位)组成。RTR位在数据帧中为显性,在远程帧中为隐性。 IDE的全称是“识别符扩展位(Identifier Extension Bit)”,对于扩展格式,IDE位属于仲裁场;对于标准格式,IDE位属于控制场。标准格式的IDE位为“显性”,而扩展格式的IDE位为“隐性”。 (3)控制域(Control Frame): 这个域表示保留位和数据帧长度代码(DLC),控制场由6个位组成,标准格式和扩展格式的控制场格式不同。标准格式里的帧包括数据长度代码、IDE位及保留位r0。扩展格式里的帧包括数据长度代码和两个保留位:r1和r0。 (4)数据域(Data Frame): 这是数据内容,0~8个字节的数据能被发送,首先发送最高有效位。 (5)CRC域(CRC Frame): 这个域用于检查帧的传输错误。 (6)ACK域(CRC Frame): 是对帧已经被正常接收的一个证实。应答场长度为2个位,包含应答间隙(ACK Slot)和应答界定符(ACK Delimiter) (7)帧结束(End of Frame): 指示数据帧结束,这个标志序列由7个“隐性”位组成 2.远程帧 作为接收器的节点,可以通过向相应的数据源节点发送远程帧激活该源节点,让该源节点把数据发送给接收器。而且都由6个不同的位场组成:帧起始、仲裁场、控制场、CRC场、应答场、帧结尾。与数据帧相反,远程帧的远程发送请求位(RTR)是“隐性”的。它没有数据场,数据长度代码DLC的数值可以是任意值。 3.错误帧 错误帧由两个不同的场组成, (1) 错误标志 主动(Active)错误标志。它由6个连续显性位组成。 被动(Passive)错误标志。它由6个连续隐性位组成。 (2)错误界定:错误界定符由8个隐性位组成。 4.帧间空间 帧间隔是用于分隔数据帧和遥控帧的帧。数据帧和遥控帧可通过插入帧间隔将本帧与前面的任何帧(数据帧、遥控帧、错误帧、过载帧)分开。 过载帧和错误帧前不能插入帧间隔。 5.过载帧 过载帧是用于接收单元通知其尚未完成接收准备的帧。过载帧由过载标志和过载界定符构成。 (1) 过载标志 6个位的显性位。 过载标志的构成与主动错误标志的构成相同。 (2) 过载界定符 8个位的隐性位。 过载界定符的构成与错误界定符的构成相同。 三. 波特率 CAN控制器只需进行少量设置就可以进行通信,其中较难设置部分就是波特率计算。CAN总线的波特率是一个范围。假如波特率为250KB/s,实际波特率可能为200~300KB/s.这样使得CAN总线有很强大容错性。 CAN的底层协议里将CAN数据的每一位时间(TBit)分为许多时间段(Tscl),这些时间段包括: A. 同步段(SYNC_SEG):位变化应该在此时间段内发生。只有一个时间片的固定长度(1 x tq) B. 位段1(BS1):定义采样点的位置。其持续长度可以在 1 到 16 个时间片之间调整 C. 位段2(BS2):定义发送点的位置。其持续长度可以在 1 到 8 个时间片之间调整 D. 同步跳转宽度(SJW):定义位段加长或缩短的上限。它可以在 1 到 4 个时间片之间调整 这个结合STM32cubeMX软件设置讲解一下CAN的波特率设置。 上面设置分频为Prescaler=9, BS1=5, BS2=6, SJW=1 CAN外接是接到APB1上面,设置系统时钟为216MHz时,APB1外设时钟为54MHz. 经过分频后的频率为54MHz / 9 =6MHz = ~ 166.666ns CAN波特率为 54MHz / 9 / (SJW+BS1 +BS2 ) = 54MHz /9 /12 = 500KHz = 2000ns 四. 标识符筛选 在CAN通信中接收到信息时,接收器节点会根据标识符的值来判断信息是否需要,若不需要则丢弃信息。 五. 新建工程 复制串口printf的工程,修改文件夹名。击STM32F746I.ioc打开STM32cubeMX的工程文件重新配置,开启CAN1,CAN2,管脚配置如下。 CAN1,CNA2只需配置时间参数,波特率为500KHz,其他为默认不作修改。 生成报告以及代码,编译程序。在can.c文件中可以看到CAN初始化函数。在stm327xx_hal_can.h文件后面可以看到CAN操作函数。 在main.c文件前面添加变量,sFilterConfig为CAN滤波器结构体变量,TxMessage,RxMessage分别存储CAN发送和接收的消息。 /* USER CODE BEGIN PV */ /* Private variables ---------------------------------------------------------*/ CAN_FilterConfTypeDef sFilterConfig; static CanTxMsgTypeDef TxMessage; static CanRxMsgTypeDef RxMessage; /* USER CODE END PV */ 在main函数中,初始化发送消息邮箱,设置为标准数据帧,数据长度为8个字节,数据为“CAN Test"。设置滤波器。 /* USER CODE BEGIN 2 */ hcan2.pTxMsg = &TxMessage; hcan1.pRxMsg = &RxMessage; printf("**** This is CAN test program ****\r\n\r\n"); /*##-1- Configure CAN2 Transmission Massage #####################################*/ hcan2.pTxMsg->StdId = 0x123; hcan2.pTxMsg->RTR = CAN_RTR_DATA; hcan2.pTxMsg->IDE = CAN_ID_STD; hcan2.pTxMsg->DLC = 8; hcan2.pTxMsg->Data[0] = 'C'; hcan2.pTxMsg->Data[1] = 'A'; hcan2.pTxMsg->Data[2] = 'N'; hcan2.pTxMsg->Data[3] = ' '; hcan2.pTxMsg->Data[4] = 'T'; hcan2.pTxMsg->Data[5] = 'e'; hcan2.pTxMsg->Data[6] = 's'; hcan2.pTxMsg->Data[7] = 't'; /*##-2- Configure the CAN1 Filter ###########################################*/ sFilterConfig.FilterNumber = 0; sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; sFilterConfig.FilterIdHigh = 0x0000; sFilterConfig.FilterIdLow = 0x0000; sFilterConfig.FilterMaskIdHigh = 0x0000; sFilterConfig.FilterMaskIdLow = 0x0000; sFilterConfig.FilterFIFOAssignment = 0; sFilterConfig.FilterActivation = ENABLE; sFilterConfig.BankNumber = 14; HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig); /* USER CODE END 2 */
在while循环中添加应用程序,CAN2发送信息给CAN1接收,正确接收到信息后打印输出。
编译程序并下载到开发板。将两个 SN65HVD230 CAN Board模块分别连接到板上的 CAN1 和 CAN2 接口。 用杜邦线连接两个 CAN 模块(CANL -> CANL, CANH -> CANH)。打开串口调试助手,设置波特率为115200,按下复位串口助手上面会显示如下信息。 |
: 为什么我的cubemx没有生成CanTxMsgTypeDef和CanRxMsgTypeDef这两个结构体?好奇怪
: 为什么我的cubemx没有生成CanTxMsgTypeDef和CanRxMsgTypeDef这两个结构体?好奇怪
: 你可以加下我的QQ,我看下是什么问题,28539 ...
: 用CubeMX生成的代码测试,normal模式不能发送
: 用CubeMX生成的代码,loopback模式失败