阅读引言: 本篇博文想给需要的人介绍一下CAN总线, 这个也算是我从B站学习记得笔记分享吧也算是。简单的介绍了CAN总线的大致内容, 简述支持CAN功能的STM32的简单使用例程。本视频的中的图片内容均来自B站爱上半导体博主的内容。
CAN高质量教学视频
目录
1.CAN总线详细讲解
2.STM32的CAN总线通信的简单引入
CAN通讯总线的简单介绍
Can 总线应用最多的是汽车领域,Can 是Control every network 的首字母缩写,意思是控制器局域网
控制器局域网, 该通信总线应用最多的是汽车领域。
局域网,想必大家都很熟悉,就是把几台电脑连到一个路由器上, 这样这几台电脑就可以通讯了
那CAN 和这个也类似,这里的控制器在汽车中的专业术语叫Ecu, 电子控制单元
意思是电子控制单元,它可以看作是一台超小型的计算机,它内部集成了供电系统,单片机驱动系统是汽车里面最小的控制模块,为了能让Ecu之间进行通讯,
为了能让ECU之间能够进行通信, 人们设计了can通讯, 为了减少线束的数量
而如果不使用看总线,ECU之间是点对点通信的, 那将使用数倍长的铜线,而且线数还非常杂乱,而通过Can 这么多Ecu 只需要挂载到看总线上就可以组成局域网通讯了,大大减少了线束的长度,那接下来我们就来说,一下看总线到底是如何通讯的。
CAN的通讯实现
要进行看通讯,需要专门的看收发芯片,这是单片机的发送和接收线,它的逻辑一是高电平逻辑理应是低电平,这种普通逻辑我们很好理解
但是经过CAN收发器之后,普通信号就会被转化成差分信号,差分线是用2根线表示一个信号
如果我们使用单片机给CAN收发器发送一个低电平,它的2根线分别输出3.5伏和1.5伏,它们的电压差是两伏,这是显示电平表示逻辑零而当我们给它发送高电平,平时,它的2根线输出的都是2.5伏压差,电压差是零伏,表示逻辑一,这就是差分信号
同样的看收发器,也可以把接收到的差分信号转化成普通电瓶信号,然后再发给单片机,那采用差分信号有什么好处呢?
那这样有什么好处呢?如果只有一根线,但某一点受到干扰,它的电瓶就会发生跳变,这样就会导致传输出现错误,所以不能进行长距离传输,而看通讯采用的差分信号是2根线共同作用
而CAN通讯采用的时两根线共同作用,而且是双脚线缠绕,这样即使是受到干扰,也是2根线同时受到干扰,它们的压差也会保持不变,这样就能保证传递的信息不受干扰,所以看信号可以传输的距离很长,可达1000米
CAN的数据帧
那接下来我们来说一下CAN通讯到底在传递什么可以看一下,这是一帧标准的数据帧
第一位是起始位,它一定得是逻辑0
接下来的11位是识别码根据是11位识别码就能知道这一张信息是发给哪一个设备呢,每一个设备都有属于自己的11位识别码
接下来的一位是用来区分数据帧或者远程请求帧,如果是远程请求帧,这一位是一,而我们这是一串数据帧,这里就必须得是零
接下来的6位是控制码,它是控制数据长度的,先说它的第一位, IDE位,第一位用来区分标准格式和拓展格式,
在标准格式当中,有11位识别码,这一位是逻辑零而在拓展格式中,它的识别码有11位,这一位是逻辑0
下面一位是预留位,它是逻辑零
接下来的4位是DLC 位及数据长度代码,它的二进制编码是零到八,
如果是一则后面的数据位,就只有一个字节8位,而如果它的值是八则后面的数据位就是8个字节64位
接下来是16位Crc 码及循环冗余校验位,它是为了确保数据的准确性而设置的,首先是15位Crc 校验码设备接收端会根据数据计算出它的Crc 位,如果计算出来的和接收到的Crc 不一致,说明数据存在问题,就会重新发送一遍,数据帧下面一位是Crc 的界定符,他是逻辑一目的是为了把后面的信息隔开
然后是2位Ac k 码,第一位是Ac k 确认操发送端发送的是逻辑一而接收端,回复的是逻辑0应来表示应答,第2位是Ac k 界定位,它一定是逻辑一作用是把后面的数据隔开
最后是7位结束位,这7位都是逻辑一表示数据帧传输结束
这就是一串标准数据帧,如果用差分信号表示它的电瓶是这样的。
因为看总线上挂载了很多设备,如果是2个设备同时发送信息,此时哪一个设备发送的信息优先呢,这就得看11位的识别码了,它不仅是设备的唯一识别码,而且还代表了优先级,比如这两帧数据是同时发出的
应该以哪一个为准呢,当总线上同时出现逻辑零和逻辑一的时候,总线会被制为逻辑零,此后上面那个数据帧就不会再发送了好了,这就是我对开通讯的理解,希望对你理解有帮助
CAN(Controller Area Network)是一种高级串行通信总线,常用于工业控制、汽车电子等领域。STM32微控制器系列中的许多型号都内置了CAN控制器,能够方便地实现CAN总线通信。本文将介绍STM32的CAN总线通信原理以及如何在STM32上实现CAN通信的方法。
CAN总线通信基本原理:
CAN总线是一种基于多主机、分布式、多节点的串行通信系统,支持高速数据传输和优先级控制。CAN总线使用两根不同的线路:CANH和CANL,以差分信号的形式传输数据。CAN总线采用CSMA/CD(Carrier Sense Multiple Access/Collision Detection)的冲突检测机制,可以避免冲突发生。
要在STM32上实现CAN总线通信,首先需要对CAN硬件进行配置和初始化,然后可以使用相应的API函数进行数据的发送和接收。
以下是一个使用STM32的CAN总线实现数据发送和接收的示例代码:
#include "stm32xxxx.h"
CAN_HandleTypeDef hcan1;
void CAN_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
// 使能CAN时钟
__HAL_RCC_CAN1_CLK_ENABLE();
// 配置CAN引脚
GPIO_InitStruct.Pin = GPIO_PIN_11 | GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF_CAN1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
// 配置CAN控制器
hcan1.Instance = CAN1;
hcan1.Init.Mode = CAN_MODE_NORMAL;
hcan1.Init.AutoBusOff = ENABLE;
hcan1.Init.AutoWakeUp = DISABLE;
hcan1.Init.AutoRetransmission = DISABLE;
hcan1.Init.ReceiveFifoLocked = DISABLE;
hcan1.Init.TransmitFifoPriority = DISABLE;
hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan1.Init.TimeSeg1 = CAN_BS1_3TQ;
hcan1.Init.TimeSeg2 = CAN_BS2_2TQ;
HAL_CAN_Init(&hcan1);
}
void CAN_SendData(uint8_t* pData, uint32_t size)
{
CAN_TxHeaderTypeDef TxHeader;
TxHeader.StdId = 0x123;
TxHeader.ExtId = 0;
TxHeader.IDE = CAN_ID_STD;
TxHeader.RTR = CAN_RTR_DATA;
TxHeader.DLC = size;
TxHeader.TransmitGlobalTime = DISABLE;
uint32_t TxMailbox;
HAL_CAN_AddTxMessage(&hcan1, &TxHeader, pData, &TxMailbox);
// 等待发送完成
while (HAL_CAN_GetTxMailboxesFreeLevel(&hcan1) != 3) {}
}
void CAN_ReceiveData(void)
{
CAN_RxHeaderTypeDef RxHeader;
uint8_t RxData[8];
HAL_CAN_GetRxMessage(&hcan1, CAN_RX_FIFO0, &RxHeader, RxData);
// 处理接收到的数据
}
int main(void)
{
HAL_Init();
CAN_Init();
while (1)
{
// 主循环代码
// 发送数据
uint8_t data[8] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
CAN_SendData(data, sizeof(data));
// 接收数据
CAN_ReceiveData();
}
}
在上述代码中,我们首先初始化了CAN硬件(通过CAN_Init函数)。然后,我们使用HAL_CAN_AddTxMessage函数发送数据,使用HAL_CAN_GetRxMessage函数接收数据。在主循环中,我们可以编写其他代码并调用CAN_SendData和CAN_ReceiveData函数来进行数据的发送和接收。
通过配置CAN的控制器和引脚,以及编写相应的代码,我们可以轻松地在STM32上实现CAN总线通信。使用CAN总线可以实现高速的分布式数据通信,适用于许多应用领域,如工业控制、汽车电子等。