打印
[APM32F0]

如何快速使用F072 CAN模块

[复制链接]
26|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主

[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 个隐性位表示结束。

6.png

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),可以从总线接收数据。

2.png

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

3.png

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

4.png

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

5.png

3)睡眠模式

配置寄存器CAN_MCTRL 的SLEEPREQ 位置1 请求进入睡眠模式。睡眠模式下CAN 的时钟停止工作,软件可以正常访问邮箱寄存器,此时CAN 处 于低功耗状态

三、软件配置

1)初始化CAN GPIO管脚,需要特别注意的是072默认管脚都是GPIO功能,需要复用为CAN功能,查看数据手册可以看到GPIOA 11和12的复用功能模式4为CAN功能 1.png

  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外设的场景,同时操作简单。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

15

主题

20

帖子

1

粉丝