IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> STM32 CAN通讯配置 -> 正文阅读

[嵌入式]STM32 CAN通讯配置

CAN总线收发,中断方式接收

平台:战舰mini板,STM32F103RB
STM32CUBEMX V5.3
TrueSTUDIO V9.3


配置CAN

CAN的波特率最大为1Mbps。
波特率计算方法:时钟主频 / 分频 / (tq1 + tq2 + swj)
stm32f103的CAN的时钟主频是36M,分9频就是4M,在除以(5 + 2 + 1)得到500K的波特率。
注意:stm32cubemx生成的CAN代码是不带过滤器的,需要自己手动添加。

在这里插入图片描述
在这里插入图片描述

代码修改

CAN初始化

CAN_HandleTypeDef hcan1;
CAN_FilterTypeDef sFilterConfig;

//CAN初始化:

/* CAN init function */
void MX_CAN_Init(void)
{
	hcan1.Instance = CAN1;
	hcan1.Init.Prescaler = 9;
	hcan1.Init.Mode = CAN_MODE_LOOPBACK;					// 回环模式,测试用。
	hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
	hcan1.Init.TimeSeg1 = CAN_BS1_5TQ;
	hcan1.Init.TimeSeg2 = CAN_BS2_2TQ;
	hcan1.Init.TimeTriggeredMode = DISABLE;					// 时间触发通信模式禁能
	hcan1.Init.AutoBusOff = DISABLE;						// 软件自动离线管理禁能
	hcan1.Init.AutoWakeUp = DISABLE;						// 睡眠模式自动唤醒禁能
	hcan1.Init.AutoRetransmission = DISABLE;				// 报文自动重传禁能
	hcan1.Init.ReceiveFifoLocked = DISABLE;					// 报文锁定禁能,新报文覆盖旧报文
	hcan1.Init.TransmitFifoPriority = ENABLE;				// 使能优先级由报文标识符决定
	if (HAL_CAN_Init(&hcan1) != HAL_OK)
	{
		Error_Handler();
	}

	sFilterConfig.FilterBank = 0;									// 使用过滤器0
	sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;				// 屏蔽位模式
	sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;				// 32位宽
	sFilterConfig.FilterIdHigh = 0x0000;							// ID高十六位
	sFilterConfig.FilterIdLow = 0x0000;								// ID低十六位
	sFilterConfig.FilterMaskIdHigh = 0x0000;						// ID掩码高十六位
	sFilterConfig.FilterMaskIdLow = 0x0000;							// ID掩码低十六位
	sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;				// 过滤器0关联到FIFO0
	sFilterConfig.FilterActivation = ENABLE;						// 激活过滤器0
	sFilterConfig.SlaveStartFilterBank = 14;
	if (HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig) != HAL_OK)
	{
		Error_Handler();
	}

	if (HAL_CAN_Start(&hcan1) != HAL_OK)
	{
		Error_Handler();
	}

	if (HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)		// 使能FIFO0数据中断接收
	{
		Error_Handler();
	}
}

覆写接收中断回调函数

(注意:上面的配置我们使用的式FIFO0,所以要覆写FIFO0的中断回调函数):

void can_msg_info(CAN_RxHeaderTypeDef* hdr, const void* data)
{
	printf("IDE     : %s\r\n",
			hdr->IDE == CAN_ID_STD ? "CAN_ID_STD" : "CAN_ID_EXT");
	printf("RTR     : %s\r\n",
			hdr->RTR == CAN_RTR_DATA ? "CAN_RTR_DATA" : "CAN_RTR_REMOTE");
	printf("DLC     : %ld\r\n", hdr->DLC);
	printf("StdId   : 0x%X\r\n", hdr->StdId);
	printf("ExtId   : 0x%X\r\n", hdr->ExtId);
	printf("Data    : %s\r\n", (char *) data);
}

void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
	if (hcan->Instance == hcan1.Instance)
	{
		uint8_t buf[8];
		CAN_RxHeaderTypeDef CAN_RX_HDR;
		if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &CAN_RX_HDR, buf)			// 获得接收到的数据头和数据
				== HAL_OK)
		{
			can_msg_info(&CAN_RX_HDR, buf);
			HAL_CAN_ActivateNotification(hcan, CAN_IT_RX_FIFO0_MSG_PENDING);	// 再次使能FIFO0接收中断
		}
	}
}

CA发送函数:

uint8_t CAN_Transmit(const void* buf, uint32_t len)
{
	uint32_t txmailbox = 0;
	uint32_t offset = 0;
	CAN_TxHeaderTypeDef hdr;

	hdr.IDE = CAN_ID_STD;				// 帧ID:标准帧
	hdr.RTR = CAN_RTR_DATA;				// 帧类型:数据帧
	hdr.StdId = 0x12;					// 标准帧ID,最大11位,也就是0x7FF
	hdr.ExtId = 0x12;					// 扩展帧ID,最大29位,也就是0x1FFF
	hdr.TransmitGlobalTime = DISABLE;

	while(len != 0)
	{
		hdr.DLC = len > 8 ? 8 : len;		// 数据长度
		if(HAL_CAN_AddTxMessage(&hcan1, &hdr, ((uint8_t *)buf) + offset, &txmailbox) != HAL_OK)
			return 1;
		offset += hdr.DLC;
		len -= hdr.DLC;
	}
	return 0;
}

附注:stm32cubemx can配置参数详解:

配置参数

参数意思
Prescaler预分频,即位时序提到的APB1 peripheral clocks继续分一次频
Time Quantum最小时间单位Tq,自动计算出来的,不需要填写
Time Quanta in Bit Segment 1PBS1段长度
Time Quanta in Bit Segment 2PBS2段长度
ReSynchronization Jump Width重同步跳跃宽度,即位时序提到的SJW
Time Triggered Communication Mode是否使能时间触发
Automatic Bus-Off Management是否使能自动离线管理
Automatic Wake-Up Modet是否使能自动唤醒
Qutomatic Retransmission是否使能自动重传
Receive Fifo Locked Mode是否使能锁定FIFO
Transmit Fifo Priority配置报文优先级的判断方法
Oprating Mode操作模式
  1. 这些参数也可以在can.c中自行修改
  2. 中断(NVIC)设置,根据需要设置,一般勾上CAN1 RX0 Interrupt

8.1.2 协议层

位时序

意义:为了实现正确的总线电平采样,确保通讯正常。最小单位是Tq(Time Quantum),一个完整位由8~25个Tq组成
组成:SS段、PTS 段、PBS1段、PBS2段

段名意义作用
SS(1Tq)同步段补偿物理延时,是传播时间、收发器延时之和的两倍
PTS(1~8Tq)传播时间段补偿变压阶段误差
PBS1(1~8Tq)相位缓冲段1使总线各节点同步
PBS2(2~8Tq)相位缓冲段2补偿边沿阶段误差
SJW(1~4Tq)再同步补偿宽度补偿时钟频率偏差、传输延迟等

例如
在这里插入图片描述

通讯波特率的计算:CAN使用的时钟线是APB1 peripheral clocks(假设是APC),即一般是SYSCLK的四分频。而CAN通讯还要对此进行预分频(假设是Prescaler),则一个Tq为 Prescaler / APC(单位s)。而一个数据位占(SS+PTS+PBS1+PBS2+SJW)个Tq。则一秒可以传输的位数就是1 T q ? 一 个 位 得 T q 数 \frac{1}{Tq一个位得Tq数}Tq?一个位得Tq数1
例如:在时钟树查得APB1 peripheral clocks是45MHz,预分频为5,则一个Tq为 4 45 M H z = 111.1111 … ( n s ) \frac{4}{45MHz}=111.1111\dots(ns)45MHz4=111.1111…(ns) ,上图中有19个Tq,则此时波特率为1 19 ? 111.11 ? 1 0 ? 9 ≈ 473689 ( b p s ) \frac{1}{19
111.11*10^{-9}}\approx473689(bps)19?111.11?10?91≈473689(bps)

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-03-30 18:41:35  更:2022-03-30 18:42:29 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 6:51:14-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码