STM32的CAN总线传输过程主要分为三个步骤
- 初始化CAN线: 开启时钟、配置GPIO口、切换工作模式(睡眠初始化正常模式)、配置CAN的传输速率(CAN_BTR)、配置需要使用的过滤器、设置过滤器关联的FIFO、配置过滤器的规则
- 封装一个数据发送函数: 配置邮箱进行发送数据。完成对邮箱进行赋值过程。
- 封装一个接收数据的函数: 轮询判断状态位,判断是否收到数据,完成数据读取。
配置过程参考STM32手册一步一步来:
规则说明
标识符: 标准标识符(高11位)、扩展标识符
如传入的标识符为0x3,设置的屏蔽位为0xffc00000,
标识符寄存器(32): 0000 0000 011 1 1111 1111 1111 1111 1111
屏蔽寄存器 (32): 1111 1111 111 1 1111 1111 1111 1111 1111
屏蔽位1代表必须关心,所以1对应的标识符位必须和别处发送来的CAN报文标识符对应位相同
接收到的标识符与设置的标识符进行对比。
0x3
0x2
再如设置的标识符为0x7,屏蔽标识符是0xFF000000
0000 0000 111 0 0000 0000 0000 0000 0000
1111 1111 000 0 0000 0000 0000 0000 0000
那么可以接收到的CAN报文标识符为
0x1、2、3、4、5、6、7
我的代码
/*
函数功能:CAN初始化,PA11---CAN_RX PA12---CAN_TX
形参:id:可接收的标识符(写死为标准标识符11位),具体标识符根据屏蔽位标识符结合得到 mode1:普通模式、回环模式(1),mode2:正常模式,静默模式(0)
测试填模式为 1,0即可
返回值:0初始化成功
*/
//u8 CAN_Init(u16 id,u8 mode1,u8 mode2)
u8 CAN_Init(u16 id,u8 mode1)
{
u16 i=0;
//0.引脚初始化
RCC->APB2ENR |= 1<<2;
GPIOA->CRH &= 0xfff00fff;
GPIOA->CRH |= 0x000B8000;
GPIOA->ODR |= 3<<11;
/*1. 配置CAN寄存器*/
RCC->APB1ENR|=1<<25; //开启CAN时钟(APB1的时钟:36M)
RCC->APB1RSTR|=1<<25;
RCC->APB1RSTR&=~(1<<25); //关闭复位时钟
//2.退出睡眠模式,进入初始化模式
CAN