当前位置:网站首页>STM32 CAN 介绍以及相关配置
STM32 CAN 介绍以及相关配置
2022-08-02 03:33:00 【@C#&】
STM32有两组CAN 控制器,CAN1是主设备,CAN2是从设备,存储访问控制器由CAN1控制,CAN2不能直接访问存储区域,所以使用CAN2的时候必须使能CAN1的外设时钟。
禁止收发任然可以访问FIFO里面的数据。
发送错误和接收错误的次数达到一定的值时,就会进入离线状态,在离线状态下,CAN是不能接收和发送报文的。
ABOM:自动离线管理
AWUM:发送报文时,总线会自动唤醒
NART:报文发送失败,会自动重传,直到成功为止
RFLM:锁定接收FIFO,锁定后,当接收FIFO溢出时,就会丢弃接收到的报文;不锁定,新的报文覆盖旧的报文
TXFP:报文优先级判定方法,当CAN外设中有多发送报文时,TXFP控制会根据报文的ID优先级挂还是报文存进邮箱的顺序来发送
CAN 初始化结构体
typedef struct
{
uint16_t CAN_Prescaler; /* 配置CAN 外设的时钟分频,可设置为1~1024 */
uint8_t CAN_Mode; /* 配置CAN 的工作模式,回环或正常模式 */
uint8_t CAN_SJW; /* 配置SJW 极限值, 可设置为1~4tq */
uint8_t CAN_BS1; /* 配置BS1段长度,可设置为1~16tq */
uint8_t CAN_BS2; /* 配置BS2段长度 ,可设置为1~8tq */
FunctionalState CAN_TTCM; /* 是否使能TTCM时间触发功能 */
FunctionalState CAN_ABOM; /* 是否使能ABOM 自动离线管理功能 */
FunctionalState CAN_AWUM; /* 是否使能 AWUM 自动唤醒功能 */
FunctionalState CAN_NART; /* 是否使能 NART 自动重传功能 */
FunctionalState CAN_RFLM; /* 是否使能 RFLM 锁定FIFO功能 */
FunctionalState CAN_TXFP; /* 配置TXFP 报文优先级的判定方法 */
} CAN_InitTypeDef;
CAN 发送结构体
typedef struct
{
uint32_t StdId; /* 存储报文的标准标识符11位,0~0x7FF. */
uint32_t ExtId; /* 存储报文的扩展标识符29位,0~0x1FFFFFFF */
uint8_t IDE; /* 存储IDE扩展标志*/
uint8_t RTR; /* 存储RTR远程帧标志 */
uint8_t DLC; /* 存储报文数据段的长度,0~8 */
uint8_t Data[8]; /* 存储报文数据段的内容 */
} CanTxMsg;
CAN 接收结构体
typedef struct
{
uint32_t StdId; /* 存储报文的标准标识符11位,0~0x7FF */
uint32_t ExtId; /* 存储报文的扩展标识符29位,0~0x1FFFFFFF */
uint8_t IDE; /* 存储IDE扩展标志 */
uint8_t RTR; /* 存储RTR远程帧标志 */
uint8_t DLC; /* 存储报文数据段的长度,0~8 */
uint8_t Data[8]; /* 存储报文数据段的内容 */
uint8_t FMI; /* 存储报文是由经过筛选器存储进 FIFO 的,0xFF*/
} CanRxMsg;
CAN 筛选器结构体
typedef struct
{
uint16_t CAN_FilterIdHigh; /* CAN_FxR1寄存的器的高16位 */
uint16_t CAN_FilterIdLow; /* CAN_FxR1寄存的器的低16位 */
uint16_t CAN_FilterMaskIdHigh; /* CAN_FxR2寄存的器的高16位 */
uint16_t CAN_FilterMaskIdLow; /* CAN_FxR2寄存的器的低16位 */
uint16_t CAN_FilterFIFOAssignment; /* 设置经过筛选后数据存储到哪个接收FIFO */
uint8_t CAN_FilterNumber; /* 筛选器编号,范围 0~27 */
uint8_t CAN_FilterMode; /* 筛选器模式 */
uint8_t CAN_FilterScale; /* 设置筛选器的尺度 */
FunctionalState CAN_FilterActivation; /* 是否使能本筛选器 */
} CAN_FilterInitTypeDef;
下面是自己配置的CAN外设
void can1_mode_Init()
{
GPIO_InitTypeDef GPIO_InitStructure;
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用功能
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //100Hz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/************复用*******************/
GPIO_PinAFConfig(GPIOA, GPIO_PinSource11, GPIO_AF_CAN1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource12, GPIO_AF_CAN1);
/************CAN总线的配置*******************/
CAN_InitStructure.CAN_TTCM = DISABLE; //时间触发通讯,1:使能,0:禁止
CAN_InitStructure.CAN_ABOM = ENABLE; //1:发生错误后,总线关闭,硬件自动恢复,0:由软件恢复
CAN_InitStructure.CAN_AWUM = ENABLE; //1:自动退出睡眠模式,0:由软件退出睡眠模式
CAN_InitStructure.CAN_NART = DISABLE; //1:不管成败只发送一次,0:发送失败会重发
CAN_InitStructure.CAN_RFLM = DISABLE; //1:保留最初的消息,0:覆盖旧消息更新最新消息
CAN_InitStructure.CAN_TXFP = DISABLE; //1:按发送请求顺序优先发送,0:按标识符优先发送
CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
CAN_InitStructure.CAN_SJW = CAN_SJW_2tq;
CAN_InitStructure.CAN_BS1 = CAN_BS1_4tq; //Tbs1范围CAN_BS1_1tq ~ CAN_BS1_16tq
CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq; //Tbs2范围CAN_BS2_1tq ~ CAN_BS2_8tq
CAN_InitStructure.CAN_Prescaler = 6; //brp CAN BaudRate 42/(4+2+1)=1Mbps
CAN_Init(CAN1, &CAN_InitStructure);
/******CAN总线的过滤配置(接收配置)********/
CAN_FilterInitStructure.CAN_FilterNumber = 0;
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
CAN_FilterInit(&CAN_FilterInitStructure);
CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn; //中断配置
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //响应优先级 0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
初次学习CAN,有错误的欢迎在下方评论区指正!
边栏推荐
猜你喜欢
GM8775C MIPI转LVDS调试资料分享
【LeetCode】链表相加 进位
Basic IO (on): file management and descriptors
简单的RC滤波电路
Pylon CLI 低成本的本地环境管控工具应用实例
USB HUB USB集线器电路设计
D类音频功放NS4110B电路设计
How to remotely debug PLC?
Personal image bed construction based on Alibaba Cloud OSS+PicGo
Comparative analysis of mobile cloud IoT pre-research and Alibaba Cloud development
随机推荐
关于IIC SDA毛刺的那些事
list:list的介绍和模拟实现
Modify hosts file using batch script
AD8307对数检波器
判断子序列 —— LeetCode-392
TQP3M9009电路设计
【plang 1.4.4】编写贪吃蛇脚本
Comparative analysis of mobile cloud IoT pre-research and Alibaba Cloud development
Typora use
联阳IT66121FN提供SDI转HDMI方案分享
【LeetCode】合并
path 修补文件命令
Host your own website with Vercel
MPU6050 accelerometer and gyroscope sensor is connected with the Arduino
Lightly 支持 Markdown 文件在线编写(文中提供详细 Markdown 语法)
增量编译技术在Lightly中的实践
【详解】线程池及其自定义线程池的实现
WebApp 在线编程成趋势:如何在 iPad、Matepad 上编程?
蛮力法求解凸包问题
idea中创建jsp项目详细步骤