[i=s] 本帖最后由 lc115647 于 2025-6-21 19:32 编辑 [/i]<br />
<br />
[i=s] 本帖最后由 lc115647 于 2025-6-21 19:31 编辑 [/i]
一、什么是CAN
CAN(Controller Area Network,控制器局域网)协议是一种广泛应用于汽车电子、工业自动化等领域的串行通信协议,由德国博世(Bosch)公司在1980年代开发,主要用于设备间的实时、可靠数据交换。以下是其核心要点:
1.1 基本特点
- 多主通信:所有节点均可主动发送数据,无需中心控制器,通过仲裁机制解决冲突。
- 高可靠性:采用差分信号(CAN_H/CAN_L)抗干扰,CRC校验、错误帧重传等机制保障数据完整性。
- 实时性强:基于优先级(ID决定)的非破坏性仲裁,高优先级消息优先传输。
- 拓扑灵活:支持总线型拓扑,节点通过双绞线连接,最大速率1 Mbps(40米内),距离越长速率越低。
1.2 帧类型
- 数据帧:携带实际数据,包含以下字段:
仲裁字段:标识符(ID)决定优先级(数值越小优先级越高)。控制字段:数据长度(DLC,0-8字节)。
数据字段:实际传输的数据(最多8字节)。
- CRC字段:循环冗余校验码。
- 远程帧:请求其他节点发送对应ID的数据(无数据字段)。
- 错误帧:节点检测错误时主动发送,通知全网。
- 过载帧:用于延迟后续帧。
1.3 仲裁机制
- 非破坏性仲裁:多个节点同时发送时,通过ID逐位比对,优先级高的继续发送,低的自动退出发送(无需重试,避免冲突)。
1.4 错误处理
- 错误检测:包括CRC错误、格式错误、应答错误等。
- 错误恢复:节点进入“错误被动”或“总线关闭”状态,避免持续影响通信。
1.5 版本演进
CAN 2.0A:标准帧(11位ID)。
CAN 2.0B:扩展帧(29位ID,兼容标准帧)。
CAN FD(Flexible Data Rate):提速(最高5 Mbps)、数据字段扩展(最多64字节),兼容传统CAN。
二、F072 CAN外设介绍
2.1 主要特征
1)支持CAN协议2.0A和2.0B
2)通信波特率最大为1Mbit/s
3)发送功能:有 3个发送邮箱;发送报文优先级可配置;可记录发送时间
4)接收功能:有 2个 3级深度的接收 FIFO;有 14个过滤器组 ;可记录接收时间
5)三个主要的工作模式:初始化模式、正常模式和睡眠模式。
2.2报文结构
(1) 帧起始:用来通知各个节点将有数据传输。
(2) 仲裁段:有多个报文被发送时,用来决定哪个报文能被传输。此段主要内容是ID 信息,标准
格式下ID 为11 位,扩展格式下ID 为29 位。
(3) 控制段:此段最主要的是数据长度码(DLC),用来表示报文中的数据段有多少个字节。数据段
最多8 个字节。
(4) 数据段:包含节点要发送的数据信息。
(5) CRC 段:CRC 校验码用来确保报文正确传输。
(6) ACK 段:此段包含ACK 槽位和ACK 界定符位,ACK 槽中发送节点发送隐性位,接收节点将
在这一位发送显性位表示应答。
(7) 帧结束:由发送节点发送的7 个隐性位表示结束。

2.3模式工作特点
1)初始化模式
配置寄存器CAN_MCTRL 的INITREQ 位置1 请求进入初始化模式,INIT 位清0 确认进入初始化模式。
配置寄存器CAN_MCTRL 的INITREQ 位清0 请求退出初始化模式,INIT 位清0 确认退出初始化模式。
初始化模式下,禁止报文接收和发送
2)正常模式
通过软件配置寄存器CAN_MCTRL 的INITREQ 位清0 请求从初始化模式进入正常模式,等待硬件对INIT 位清0 确认进入正常模式。正常模式下,可以正常接收和发送报文。可配置为四种通讯模式:静默模式、环回模式、静默环回模式和正常模式。需要特别注意的是只能在初始化模式下选择不同的通信模式。**
静默模式:配置寄存器CAN_BITTIM 的SILMEN 位置1,选择静默模式。该模式下,只能向总线发送隐性位(逻辑1),不能发送显性位(逻辑0),可以从总线接收数据。

环回模式:配置寄存器CAN_BITTIM 的LBKMEN 位置1,选择环回模式。该模式下,发送的数据直接传到输入端接收,不从总线上接收数据,可以向总线发送所有数据

静默环回模式:配置寄存器CAN_BITTIM 的LBKMEN 和SILMEN 位同时置1,选择环回静默模式。该模式下,发送的数据直接传到输入端接收,不从总线上接收数据,只能向总线发送隐性位(逻辑1),不能发送显性位(逻辑0)。

正常模式:该模式下,可以向总线发送数据和接收数据。

3)睡眠模式
配置寄存器CAN_MCTRL 的SLEEPREQ 位置1 请求进入睡眠模式。睡眠模式下CAN 的时钟停止工作,软件可以正常访问邮箱寄存器,此时CAN 处
于低功耗状态
三、软件配置
1)初始化CAN GPIO管脚,需要特别注意的是072默认管脚都是GPIO功能,需要复用为CAN功能,查看数据手册可以看到GPIOA 11和12的复用功能模式4为CAN功能

void CAN_GPIO_Init(void){
GPIO_Config_T gpioConfig;
/* Enable the GPIO_A Clock */
RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_GPIOA);
GPIO_ConfigPinAF(GPIOA, GPIO_PIN_SOURCE_12, GPIO_AF_PIN4);
GPIO_ConfigPinAF(GPIOA, GPIO_PIN_SOURCE_11, GPIO_AF_PIN4);
/* Configure the GPIO pin */
gpioConfig.pin = GPIO_PIN_12;
gpioConfig.mode = GPIO_MODE_AF;
gpioConfig.outtype = GPIO_OUT_TYPE_PP;
gpioConfig.speed = GPIO_SPEED_50MHz;
gpioConfig.pupd = GPIO_PUPD_NO;
GPIO_Config(GPIOA, &gpioConfig);
gpioConfig.pin = GPIO_PIN_11;
gpioConfig.mode = GPIO_MODE_AF;
gpioConfig.pupd = GPIO_PUPD_NO;
gpioConfig.speed = GPIO_SPEED_50MHz;
GPIO_Config(GPIOA, &gpioConfig);
}
2)初始化CAN外设模块
void CAN_Init(void)
{
CAN_Config_T canConfig;
CAN_FilterConfig_T filterConfig;
CAN_Reset();
/* Enable CAN clock */
RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_CAN);
CAN_GPIO_Init();
/* CAN configuration */
CAN_ConfigStructInit(&canConfig);
canConfig.autoBusOffManage = ENABLE;
canConfig.autoWakeUpMode = DISABLE;
canConfig.nonAutoRetran = DISABLE;
canConfig.timeTrigComMode = DISABLE;
canConfig.txFIFOPriority = ENABLE;
canConfig.rxFIFOLockMode = DISABLE;
canConfig.mode = CAN_MODE_NORMAL;
canConfig.syncJumpWidth = CAN_SJW_1;
canConfig.timeSegment1 = CAN_TIME_SEGMENT1_2;
canConfig.timeSegment2 = CAN_TIME_SEGMENT2_3;
canConfig.prescaler = 16;
CAN_Config(&canConfig);
/* CAN filter configuration */
filterConfig.filterIdHigh = 0x0000;
filterConfig.filterIdLow = 0x0000;
filterConfig.filterMaskIdHigh = 0x0000;
filterConfig.filterMaskIdLow = 0x0000;
filterConfig.filterFIFO = CAN_FIFO_0;
filterConfig.filterNumber = CAN_FILTER_NUMBER_1;
filterConfig.filterMode = CAN_FILTER_MODE_IDMASK;
filterConfig.filterScale = CAN_FILTER_SCALE_32BIT;
filterConfig.filterActivation = ENABLE;
CAN_ConfigFilter(&filterConfig);
}
3)发送例程
int main(void)
{
CAN_Tx_Message TxMessage;
CAN_Init();
/* CAN Tx Message configuration */
TxMessage.stanID = 0x0000;
TxMessage.extenID = 0x1111;
TxMessage.typeID = CAN_TYPEID_EXT;
TxMessage.remoteTxReq = CAN_RTXR_DATA;
TxMessage.dataLengthCode = 2;
TxMessage.data[0] = 0x55;
TxMessage.data[1] = 0xAA;
while (1)
{
TxMessage.data[0] = 0x55;
TxMessage.data[1] = 0xAA;
CAN_TxMessage(&TxMessage);
for(uint16_t i=0;i<0xffff;i++){}
}
}
四、总结
F072作为一颗低成本的M0内核32位处理器,具备基本的CAN功能,适用于两三轮车仪表、BMS保护板等需要CAN外设的场景,同时操作简单。