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 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> STM32G474_FDCAN的普通CAN模式使用 -> 正文阅读

[嵌入式]STM32G474_FDCAN的普通CAN模式使用

由于鄙人比较懒,因此本文章只是对 FDCAN 的 经典模式 的简单使用介绍。对于我不需要使用的功能 我就没有深入研究,因此本文只是 CAN 的常用方式的笔记,深入研究的话可以详细阅读手册,本文章没有介绍。

如果有介绍错误的地方,希望各位大佬指正,鄙人一定修改,必要时删除本文章,防止误导他人。欢迎讨论!

FDCAN经典CAN 的最直观差别就是数据帧部分,FDCAN的数据帧波特率可变,并且数据大小不局限于 8 Bytes ,最高支持 64 Bytes 的数据传输。详细差别见 传送门: CAN FD 与 CAN协议区别–简单易懂协议详解

1. FDCAN的框图

在这里插入图片描述
根据上图可以看到,FDCAN 有两个时钟域,APB总线接口和CAN内核时钟。FDCAN的波特率取决于内核时钟,寄存器的配置、消息RAM等,走的是APB时钟。FDCAN的APB时钟在RCC_APB寄存器中配置,内核时钟在RCC_CCIPR寄存器中配置(下一章)。
FDCAN有两个中断线,这两个中断线可以单独的打开或关闭,在FDCAN_ILE寄存器中配置。
其他具体介绍参考DM00355726_ENV4手册的1947页(RM0440手册官方下载传送门)。

2. FDCAN的时钟与波特率

2.1 fdcan_clk

几乎所有通信都可在RCC中配置时钟选择,FDCAN的时钟(fdcan_clk)可在RCC_CCIPR寄存器中进行配置。

在这里插入图片描述

2.2 fdcan_tq_ck

根据系统框图可看到,系统输入的时钟可通过 fdcan_clk 分频得到 fdcan_tq_ck ,在 FDCAN_CKDIV 寄存器中配置分频系数。

这里是引用

2.3 波特率

FDCAN模块的bit采样分三段:

在这里插入图片描述


波特率公式如下:

波 特 率 = 1 t q + t B S 1 + t B S 2 波特率 = \frac{1}{t_q + t_{BS1} + t_{BS2}} =tq?+tBS1?+tBS2?1?

t q = ( B R P + 1 ) ? f d c a n _ c l k t_q = (BRP + 1)*fdcan\_clk tq?=(BRP+1)?fdcan_clk

注意:
1、由于 FDCAN 与 经典CAN 的帧格式有点差异,其数据帧波特率可变,因此在这里分出普通CAN和数据bit时间
2、数据 和 普通 bit 时间寄存器名称不一样,数据波特率寄存器 FDCAN_DBTP ,一般帧波特率寄存器为 FDCAN_NBTP

3. FDCAN的地址分布

3.1 总体分布

在这里插入图片描述

G474的FDCAN外设一共有3组(FDCAN1,FDCAN2,FDCAN3),寄存器配置分为3个,消息RAM也分为3组。
这里可以先把 消息RAM 的宏定义写好

#define FDCANs_MESSAGE_RAM_BASE		0x4000A400
#define FDCAN1_RAM_BASE				(FDCANs_MESSAGE_RAM_BASE)
#define FDCAN2_RAM_BASE				(FDCAN1_RAM_BASE + 0x00000400)
#define FDCAN3_RAM_BASE				(FDCAN2_RAM_BASE + 0x00000400)

3.2 Message RAM

在这里插入图片描述
1个 信息RAM 有 212 words 的大小,即 212 × 4 = 848 Bytes 。
根据该图,可以创建一个对应上述地址的结构体,方便后期地址的管理:

typedef struct
{
	uint32_t FILTER_11BIT[28];
	uint32_t FILTER_29BIT[16];
	uint32_t Rx_FIFO_0[54];
	uint32_t Rx_FIFO_1[54];
	uint32_t Tx_FIFO[6];
	uint32_t Tx_BUFFER[54];
}FDCAN_RAM_Struct;

4. FDCAN的筛选器

4.1 筛选器的特征

  1. 每个筛选器可配置为
    ? 范围筛选
    ? 指定ID筛选
    ? 屏蔽典型bit筛选
  2. 每个过滤器元件可配置为接受或拒绝过滤
  3. 每个过滤器元素可以单独启用/禁用
  4. 过滤器是按顺序检查的,执行在第一个匹配的过滤器元素时停止

相关的寄存器:全局筛选配置(RXGFC)、拓展ID和掩码(XIDAM

如果需要接收数据,一定要配置筛选器,否则会什么也接受不到。

4.2 11-bit 筛选器的格式

在这里插入图片描述
这里根据手册的翻译进行配置就好,29-bit 的筛选器也是如此,手册里全有,我就不放图片了,太占地方。

对于筛选器的掩码模式,可通过传送门了解到:CAN通讯难点———验收筛选器

通过配置筛选器,可以使FDCAN外设接收其他模块发来的信息,在筛选器中配置接收消息的FIFO或者拒收消息。配置筛选器是FDCAN接收的关键。

5. TX FIFO 的寄存器格式

在这里插入图片描述

具体说明见手册1969页,我就不复制了,翻一下就能懂每个BIT代表的意思。
根据上表,我们就可以写出对应各个标志位的结构体,方便后期指针使用。
由于其buffer支持 11-bit ID29-bit ID ,因此将其写为共同体。

typedef union
{
	uint32_t HallfWord[54];
	struct
	{
		uint32_t T0_ID:29;					// ID
		uint32_t T0_RTR:1;					//【0|发送数据帧】【1|发送远程帧】
		uint32_t T0_XTD:1;					//【0|11-bit】【1|29-bit】
		uint32_t T0_ESI:1;					// 
		
		uint32_t T1_Reserved1:16;
		uint32_t T1_DLC:4;					//【0~8|发送数据为0~8】【9~15|经典CAN为8,FDCAN为12/16/20/24/32/48/64】
		uint32_t T1_BRS:1;					//【0|无波特率切换】【1|有波特率切换】
		uint32_t T1_FDF:1;					//【0|经典CAN】【1|FDCAN】
		uint32_t T1_Reserved2:1;
		uint32_t T1_EFC:1;					//【0|不保存TX事件】【1|保存】
		uint32_t T1_MM:8;					// 

		uint32_t DataWord[16];
	}bit_29ID;
	struct
	{
		uint32_t T0_Reserved:18;
		uint32_t T0_ID:11;					// ID
		uint32_t T0_RTR:1;					//【0|发送数据帧】【1|发送远程帧】
		uint32_t T0_XTD:1;					//【0|11-bit】【1|29-bit】
		uint32_t T0_ESI:1;					// 
		
		uint32_t T1_Reserved1:16;
		uint32_t T1_DLC:4;					//【0~8|发送数据为0~8】【9~15|经典CAN为8,FDCAN为12/16/20/24/32/48/64】
		uint32_t T1_BRS:1;					//【0|无波特率切换】【1|有波特率切换】
		uint32_t T1_FDF:1;					//【0|经典CAN】【1|FDCAN】
		uint32_t T1_Reserved2:1;
		uint32_t T1_EFC:1;					//【0|不保存TX事件】【1|保存】
		uint32_t T1_MM:8;					// 

		uint32_t DataWord[16];
	}bit_11ID;
}FDCAN_Buffer_Union;

6. FDCAN的初始化

IO口配置我就不介绍了,想必大家都会配置IO。

6.1 配置时钟

  1. 首先在RCC->APB1RSTR1寄存器中使能RCC_APB1ENR1_FDCANEN,这样FDCAN的寄存器就可以配置了。
  2. 然后选择FDCAN内核时钟的时钟源,在RCC->CCIPR寄存器的RCC_CCIPR_FDCANSEL中配置。
  3. 置位INIT标志位,开始配置寄存器(只有INIT标志位置位,才可置位CCE标志位)
  4. 置位CCE标志位,解锁受保护的寄存器
  5. 配置时钟分频
  6. 配置波特率
  7. 配置中断
  8. 配置筛选器
  9. 清除INIT标志位

初始化代码见
附录1.1 RCC配置
附录1.2 FDCAN寄存器配置

7. 发送操作

7.1 FDCAN帧模式

FDCAN帧模式由下表各个标志位配置:

在这里插入图片描述

根据上表所示,可以通过 CCCR寄存器Tx Buffer 内部的标志位 配合,实现不同模式的CAN。
由于鄙人只想使用 经典CAN,因此将 CCCR寄存器 中的 FDOE 配置为 0,其他标志位我就不管了。

7.2 发送步骤

  1. 将要发送的数据写入 Tx Buffer 中(在这里可以配置发送长度、ID等信息)
  2. 置位发送请求
  3. 等待发送完成(可以不等待,配置发送完成中断使能后,在中断中置位发送完成标志来判断是否发送完毕)

示例代码见
附录2 发送函数
中断中判断是否发送完毕程序见
附录3 中断程序

8. 接收操作

首先配置筛选器来选择接收的消息和接收后存放的FIFO。

接收分为 覆盖模式阻塞模式
覆盖模式 顾名思义,就是当FIFO满了以后,接收到新消息后覆盖老消息。
阻塞模式 就是当FIFO满了之后,忽略新消息,保留老消息。

Rx FIFO 0 接收到消息后,将会在 FDCAN_RXF0S 寄存器中 F0GI 标志位指示新消息存储索引,当 CPU 读取这些消息后,务必将最后 F0GI 的值写入到 FDCAN_RXF0AF0AI 标志位,来确认来读取完毕,这会将 FDCAN_RXF0S寄存器中的索引标志位 F0GI 设置为 F0AI + 1 并更新 FIFO 0 的存储计数 (FDCAN_RXF0S 寄存器中 F0FL 标志位,范围0~3),如果不确认读取完毕,将会导致指示索引 F0GI 失效。

接收操作可以在中断中进行,通过配置 FDCAN_IE 寄存器中的相应 中断使能标志位 来开启中断。如:使能 FIFO0 接收新消息中断就置位 FDCAN_IE_RF0NE 标志位。

因此,接收操作的步骤为:

  1. 读取接收的数据
  2. 确认读取完毕

接收程序见
附录3 中断程序

9. 参考资料传送门

9.1 代码下载(0积分)

代码下载(0积分)

9.2 其他 CAN 知识了解

其他 CAN 知识了解

附录1 初始化

附录1.1 RCC配置

为方便其他模块配置,将其他模块的RCC列表了出来,方便当库文件使用

返回第6章

void RCC_Init(void)//
{
	//--------------------------------------------------------------------------------------//
	//---------------------------------------- AHB1 ----------------------------------------//
	//--------------------------------------------------------------------------------------//
	RCC->AHB1RSTR |= 0			//default: 0x0000 0000
					//	|RCC_AHB1RSTR_CRCRST		//bit12
					//	|RCC_AHB1RSTR_FLASHRST		//bit08
					//	|RCC_AHB1RSTR_FMACRST		//bit04
					//	|RCC_AHB1RSTR_CORDICRST		//bit03
					//	|RCC_AHB1RSTR_DMAMUX1RST	//bit02
					//	|RCC_AHB1RSTR_DMA2RST		//bit01
					//	|RCC_AHB1RSTR_DMA1RST		//bit00
					;
	RCC->AHB1RSTR &= 0xffffffff	//default: 0x0000 0000
					//	&~RCC_AHB1RSTR_CRCRST		//bit12
					//	&~RCC_AHB1RSTR_FLASHRST		//bit08
					//	&~RCC_AHB1RSTR_FMACRST		//bit04
					//	&~RCC_AHB1RSTR_CORDICRST	//bit03
					//	&~RCC_AHB1RSTR_DMAMUX1RST	//bit02
					//	&~RCC_AHB1RSTR_DMA2RST		//bit01
					//	&~RCC_AHB1RSTR_DMA1RST		//bit00
					;
	
	RCC->AHB1ENR |= 0			//default: 0x0000 0100
					//	|RCC_AHB1ENR_CRCEN			//bit12
					//	|RCC_AHB1ENR_FLASHEN		//bit08
					//	|RCC_AHB1ENR_FMACEN			//bit04
					//	|RCC_AHB1ENR_CORDICEN		//bit03
					//	|RCC_AHB1ENR_DMAMUX1EN		//bit02
					//	|RCC_AHB1ENR_DMA2EN			//bit01
					//	|RCC_AHB1ENR_DMA1EN			//bit00
					;
	//--------------------------------------------------------------------------------------//
	//---------------------------------------- AHB2 ----------------------------------------//
	//--------------------------------------------------------------------------------------//
	RCC->AHB2RSTR |= 0			//defualt: 0x0000 0000
					//	|RCC_AHB2RSTR_RNGRST		//bit26
					//	|RCC_AHB2RSTR_RNGRST		//bit24
					//	|RCC_AHB2RSTR_DAC4RST		//bit19
					//	|RCC_AHB2RSTR_DAC3RST		//bit18
					//	|RCC_AHB2RSTR_DAC2RST		//bit17
					//	|RCC_AHB2RSTR_DAC1RST		//bit16
						|RCC_AHB2RSTR_ADC345RST		//bit14
						|RCC_AHB2RSTR_ADC12RST		//bit13
					//	|RCC_AHB2RSTR_GPIOGRST		//bit06
						|RCC_AHB2RSTR_GPIOFRST		//bit05
						|RCC_AHB2RSTR_GPIOERST		//bit04
						|RCC_AHB2RSTR_GPIODRST		//bit03
						|RCC_AHB2RSTR_GPIOCRST		//bit02
						|RCC_AHB2RSTR_GPIOBRST		//bit01
						|RCC_AHB2RSTR_GPIOARST		//bit00
					;
	RCC->AHB2RSTR &= 0xffffffff	//defualt: 0x0000 0000
					//	&~RCC_AHB2RSTR_RNGRST		//bit26
					//	&~RCC_AHB2RSTR_RNGRST		//bit24
					//	&~RCC_AHB2RSTR_DAC4RST		//bit19
					//	&~RCC_AHB2RSTR_DAC3RST		//bit18
					//	&~RCC_AHB2RSTR_DAC2RST		//bit17
					//	&~RCC_AHB2RSTR_DAC1RST		//bit16
						&~RCC_AHB2RSTR_ADC345RST	//bit14
						&~RCC_AHB2RSTR_ADC12RST		//bit13
					//	&~RCC_AHB2RSTR_GPIOGRST		//bit06
						&~RCC_AHB2RSTR_GPIOFRST		//bit05
						&~RCC_AHB2RSTR_GPIOERST		//bit04
						&~RCC_AHB2RSTR_GPIODRST		//bit03
						&~RCC_AHB2RSTR_GPIOCRST		//bit02
						&~RCC_AHB2RSTR_GPIOBRST		//bit01
						&~RCC_AHB2RSTR_GPIOARST		//bit00
					;
	RCC->AHB2ENR = 0			//default: 0x0000 0000
					//	|RCC_AHB2ENR_RNGEN			//bit26
					//	|RCC_AHB2ENR_DAC4EN			//bit19
					//	|RCC_AHB2ENR_DAC3EN			//bit18
					//	|RCC_AHB2ENR_DAC2EN			//bit17
					//	|RCC_AHB2ENR_DAC1EN			//bit16
						|RCC_AHB2ENR_ADC345EN		//bit14
						|RCC_AHB2ENR_ADC12EN		//bit13
					//	|RCC_AHB2ENR_GPIOGEN		//bit06
						|RCC_AHB2ENR_GPIOFEN		//bit05
						|RCC_AHB2ENR_GPIOEEN		//bit04
						|RCC_AHB2ENR_GPIODEN		//bit03
						|RCC_AHB2ENR_GPIOCEN		//bit02
						|RCC_AHB2ENR_GPIOBEN		//bit01
						|RCC_AHB2ENR_GPIOAEN		//bit00
					;
	//--------------------------------------------------------------------------------------//
	//---------------------------------------- AHB3 ----------------------------------------//
	//--------------------------------------------------------------------------------------//
	RCC->AHB3RSTR |= 0			//default:0x0000 0000
					//	|RCC_AHB3RSTR_QSPIRST		//bit08
					//	|RCC_AHB3RSTR_FMCRST		//bit00
					;
	RCC->AHB3RSTR &= 0xffffffff	//default:0x0000 0000
					//	&~RCC_AHB3RSTR_QSPIRST		//bit08
					//	&~RCC_AHB3RSTR_FMCRST		//bit00
					;

	RCC->AHB3ENR |= 0			//default: 0x0000 0000
					//	|RCC_AHB3ENR_QSPIEN			//bit08
					//	|RCC_AHB3ENR_FMCEN			//bit00
					;
	//--------------------------------------------------------------------------------------//
	//---------------------------------------- APB1 ----------------------------------------//
	//--------------------------------------------------------------------------------------//
	RCC->APB1RSTR1 |= 0			//default: 0x0000 0000
					//	|RCC_APB1RSTR1_LPTIM1RST	//bit31
					//	|RCC_APB1RSTR1_I2C3RST		//bit30
					//	|RCC_APB1RSTR1_PWRRST		//bit28
						|RCC_APB1RSTR1_FDCANRST		//bit25
					//	|RCC_APB1RSTR1_USBRST		//bit23
					//	|RCC_APB1RSTR1_I2C2RST		//bit22
					//	|RCC_APB1RSTR1_I2C1RST		//bit21
					//	|RCC_APB1RSTR1_UART5RST		//bit20
					//	|RCC_APB1RSTR1_UART4RST		//bit19
					//	|RCC_APB1RSTR1_USART3RST	//bit18
					//	|RCC_APB1RSTR1_USART2RST	//bit17
					//	|RCC_APB1RSTR1_SPI3RST		//bit15
					//	|RCC_APB1RSTR1_SPI2RST		//bit14
					//	|RCC_APB1RSTR1_CRSRST		//bit08
						|RCC_APB1RSTR1_TIM7RST		//bit05
						|RCC_APB1RSTR1_TIM6RST		//bit04
					//	|RCC_APB1RSTR1_TIM5RST		//bit03
						|RCC_APB1RSTR1_TIM4RST		//bit02
						|RCC_APB1RSTR1_TIM3RST		//bit01
						|RCC_APB1RSTR1_TIM2RST		//bit00
					;
	RCC->APB1RSTR1 &= 0xffffffff//default: 0x0000 0000
					//	&~RCC_APB1RSTR1_LPTIM1RST	//bit31
					//	&~RCC_APB1RSTR1_I2C3RST		//bit30
					//	&~RCC_APB1RSTR1_PWRRST		//bit28
						&~RCC_APB1RSTR1_FDCANRST	//bit25
					//	&~RCC_APB1RSTR1_USBRST		//bit23
					//	&~RCC_APB1RSTR1_I2C2RST		//bit22
					//	&~RCC_APB1RSTR1_I2C1RST		//bit21
					//	&~RCC_APB1RSTR1_UART5RST	//bit20
					//	&~RCC_APB1RSTR1_UART4RST	//bit19
					//	&~RCC_APB1RSTR1_USART3RST	//bit18
					//	&~RCC_APB1RSTR1_USART2RST	//bit17
					//	&~RCC_APB1RSTR1_SPI3RST		//bit15
					//	&~RCC_APB1RSTR1_SPI2RST		//bit14
					//	&~RCC_APB1RSTR1_CRSRST		//bit08
						&~RCC_APB1RSTR1_TIM7RST		//bit05
						&~RCC_APB1RSTR1_TIM6RST		//bit04
					//	&~RCC_APB1RSTR1_TIM5RST		//bit03
						&~RCC_APB1RSTR1_TIM4RST		//bit02
						&~RCC_APB1RSTR1_TIM3RST		//bit01
						&~RCC_APB1RSTR1_TIM2RST		//bit00
					;

	RCC->APB1ENR1 |= 0			//default: 0x0000 0400
					//	|RCC_APB1ENR1_LPTIM1EN		//bit31
					//	|RCC_APB1ENR1_I2C3EN		//bit30
					//	|RCC_APB1ENR1_PWREN			//bit28
						|RCC_APB1ENR1_FDCANEN		//bit25
					//	|RCC_APB1ENR1_USBEN			//bit23
					//	|RCC_APB1ENR1_I2C2EN		//bit22
					//	|RCC_APB1ENR1_I2C1EN		//bit21
					//	|RCC_APB1ENR1_UART5EN		//bit20
					//	|RCC_APB1ENR1_UART4EN		//bit19
					//	|RCC_APB1ENR1_USART3EN		//bit18
					//	|RCC_APB1ENR1_USART2EN		//bit17
					//	|RCC_APB1ENR1_SPI3EN		//bit15
					//	|RCC_APB1ENR1_SPI2EN		//bit14
					//	|RCC_APB1ENR1_WWDGEN		//bit11
					//	|RCC_APB1ENR1_RTCAPBEN		//bit10
					//	|RCC_APB1ENR1_CRSEN			//bit08
						|RCC_APB1ENR1_TIM7EN		//bit05
						|RCC_APB1ENR1_TIM6EN		//bit04
					//	|RCC_APB1ENR1_TIM5EN		//bit03
						|RCC_APB1ENR1_TIM4EN		//bit02
						|RCC_APB1ENR1_TIM3EN		//bit01
						|RCC_APB1ENR1_TIM2EN		//bit00
					;


	RCC->APB1RSTR2 |= 0			//default: 0x0000 0000
					//	|RCC_APB1RSTR2_UCPD1RST		//bit08
					//	|RCC_APB1RSTR2_I2C4RST		//bit01
					//	|RCC_APB1RSTR2_LPUART1RST	//bit00
					;
	RCC->APB1RSTR2 &= 0xffffffff//default: 0x0000 0000
					//	&~RCC_APB1RSTR2_UCPD1RST	//bit08
					//	&~RCC_APB1RSTR2_I2C4RST		//bit01
					//	&~RCC_APB1RSTR2_LPUART1RST	//bit00
					;

	RCC->APB1ENR2 |= 0			//default: 0x0000 0000
					//	|RCC_APB1ENR2_UCPD1EN		//bit08
					//	|RCC_APB1ENR2_I2C4EN		//bit01
					//	|RCC_APB1ENR2_LPUART1EN		//bit00
					;
	//--------------------------------------------------------------------------------------//
	//---------------------------------------- APB2 ----------------------------------------//
	//--------------------------------------------------------------------------------------//
	RCC->APB2RSTR |= 0			//default: 0x0000 0000
				//	|RCC_APB2RSTR_HRTIM1RST		//bit26
				//	|RCC_APB2RSTR_SAI1RST		//bit21
				//	|RCC_APB2RSTR_TIM20RST		//bit20
					|RCC_APB2RSTR_TIM17RST		//bit18
					|RCC_APB2RSTR_TIM16RST		//bit17
					|RCC_APB2RSTR_TIM15RST		//bit16
				//  |RCC_APB2RSTR_SPI4RST		//bit15
					|RCC_APB2RSTR_USART1RST		//bit14
					|RCC_APB2RSTR_TIM8RST		//bit13
				//	|RCC_APB2RSTR_SPI1RST		//bit12
					|RCC_APB2RSTR_TIM1RST		//bit11
					|RCC_APB2RSTR_SYSCFGRST		//bit00
					;
	RCC->APB2RSTR &= 0xffffffff	//default: 0x0000 0000
					//	&~RCC_APB2RSTR_HRTIM1RST	//bit26
					//	&~RCC_APB2RSTR_SAI1RST		//bit21
					//	&~RCC_APB2RSTR_TIM20RST		//bit20
						&~RCC_APB2RSTR_TIM17RST		//bit18
						&~RCC_APB2RSTR_TIM16RST		//bit17
						&~RCC_APB2RSTR_TIM15RST		//bit16
					//	&~RCC_APB2RSTR_SPI4RST		//bit15
						&~RCC_APB2RSTR_USART1RST	//bit14
						&~RCC_APB2RSTR_TIM8RST		//bit13
					//	&~RCC_APB2RSTR_SPI1RST		//bit12
						&~RCC_APB2RSTR_TIM1RST		//bit11
						&~RCC_APB2RSTR_SYSCFGRST	//bit00
					;

	RCC->APB2ENR |= 0			//default: 0x0000 0000
					//	|RCC_APB2ENR_HRTIM1EN		//bit26
					//	|RCC_APB2ENR_SAI1EN			//bit21
					//	|RCC_APB2ENR_TIM20EN		//bit20
						|RCC_APB2ENR_TIM17EN		//bit18
						|RCC_APB2ENR_TIM16EN		//bit17
						|RCC_APB2ENR_TIM15EN		//bit16
					//	|RCC_APB2ENR_SPI4EN			//bit15
						|RCC_APB2ENR_USART1EN		//bit14
						|RCC_APB2ENR_TIM8EN			//bit13
					//	|RCC_APB2ENR_SPI1EN			//bit12
						|RCC_APB2ENR_TIM1EN			//bit11
						|RCC_APB2ENR_SYSCFGEN		//bit00
					;

	RCC->CCIPR |= 0
					// |(0 << RCC_CCIPR_ADC345SEL_Pos)		//
					// |(0 << RCC_CCIPR_ADC12SEL_Pos)		//
					// |(0 << RCC_CCIPR_CLK48SEL_Pos)		//
					|(0 << RCC_CCIPR_FDCANSEL_Pos)		//HSE 8MHz 
					// |(0 << RCC_CCIPR_I2S23SEL_Pos)		//
					// |(0 << RCC_CCIPR_SAI1SEL_Pos)		//
					// |(0 << RCC_CCIPR_LPTIM1SEL_Pos)		//
					// |(0 << RCC_CCIPR_I2C3SEL_Pos)		//
					// |(0 << RCC_CCIPR_I2C2SEL_Pos)		//
					// |(0 << RCC_CCIPR_I2C1SEL_Pos)		//
					// |(0 << RCC_CCIPR_LPUART1SEL_Pos)	//
					// |(0 << RCC_CCIPR_UART5SEL_Pos)		//
					// |(0 << RCC_CCIPR_UART4SEL_Pos)		//
					// |(0 << RCC_CCIPR_USART3SEL_Pos)		//
					// |(0 << RCC_CCIPR_USART2SEL_Pos)		//
					// |(0 << RCC_CCIPR_USART1SEL_Pos)		//
					;
}

返回第6章

附录1.2 FDCAN寄存器配置

返回第6章

void FDCAN1_Function_Init(void)
{
	//在RCC_CCIPR寄存器中选择FDCAN时钟为HSE,即8MHz
	//
	FDCAN1->CCCR |= 0
					|FDCAN_CCCR_CCE					//bit01: 【1|允许配置受保护的寄存器,INIT标志位必须置位】
					|FDCAN_CCCR_INIT				//bit00: 【1|初始化开始】
					;
	FDCAN1->CCCR |= 0
					// |FDCAN_CCCR_NISO				//bit15: 【0|ISO11898-1】【1|CANFD v1.0】
					// |FDCAN_CCCR_TXP					//bit14: 【1|在下上一个成功帧后暂停两个bit再起始】
					// |FDCAN_CCCR_EFBI				//bit13: 【1|同步检测边沿需要两个显性tq】
					// |FDCAN_CCCR_PXHD				//bit12: 【0|启动协议异常处理】【1|禁用协议异常处理】
					// |FDCAN_CCCR_BRSE				//bit09: 【1|启用波特率切换】
					// |FDCAN_CCCR_FDOE				//bit08: 【0|FD操作禁止】【1|FD操作使能】
					// |FDCAN_CCCR_TEST				//bit07: 【1|测试模式使能】
					|FDCAN_CCCR_DAR					//bit06: 【0|启用发送失败后自动重传】【1|禁止自动重传】
					// |FDCAN_CCCR_MON					//bit05: 【0|总线监控模式禁止】【1|总线监控模式使能】
					// |FDCAN_CCCR_CSR					//bit04: 【0|无时钟停止请求】【1|时钟停止请求,当时钟停止请求发生,先置位INIT在置位CSA在所有传输请求完成并且CAN总线空闲】
					// |FDCAN_CCCR_CSA					//bit03: 【0|没有时钟停止】【1|FDCAN可通过停止APB时钟和内核时钟来进行掉电】
					// |FDCAN_CCCR_ASM					//bit02: 【1|启用限制模式,限制模式下不会主动发送数据】
					// |FDCAN_CCCR_CCE					//bit01: 【1|允许配置受保护的寄存器,INIT标志位必须置位】
					// |FDCAN_CCCR_INIT				//bit00: 【1|初始化开始】
					;
	FDCAN_CONFIG->CKDIV = FDCAN_CKDIV_PDIV;			// 1分频
	FDCAN1->DBTP = 0								//数据帧的波特率
					|FDCAN_DBTP_TDC					//bit23: 【1|收发延时补偿使能】
					|(0 << FDCAN_DBTP_DBRP_Pos)		//bit[20:16]: tq = (BRP + 1)*fdcan_clk
					|(22 << FDCAN_DBTP_DTSEG1_Pos)	//bit[12:08]: 一阶段采样			8000000
					|(7 << FDCAN_DBTP_DTSEG2_Pos)	//bit[07:04]: 二阶段采样 波特率 = 8000000/(3+DTSEG1+DTSEG2) = 8000000/32 = 250k
					|(7 << FDCAN_DBTP_DSJW_Pos)		//bit[03:00]: 同步脉宽
					;
	FDCAN1->NBTP = 0
					|(7 << FDCAN_NBTP_NSJW_Pos)		//bit[31:25]: 同步脉宽
					|(0 << FDCAN_NBTP_NBRP_Pos)		//bit[24:16]: BRP
					|(22 << FDCAN_NBTP_NTSEG1_Pos)	//bit[15:08]: 一阶段采样
					|(7 << FDCAN_NBTP_NTSEG2_Pos)	//bit[06:00]: 二阶段采样
					;
	FDCAN1->IE |= 0
					// |FDCAN_IE_ARAE					//bit23: 访问保留地址使能
					// |FDCAN_IE_PEDE					//bit22: 数据阶段协议错误
					// |FDCAN_IE_PEAE					//bit21: 仲裁阶段协议错误
					// |FDCAN_IE_WDIE					//bit20: 看门狗使能
					// |FDCAN_IE_BOE					//bit19: 总线关闭使能
					// |FDCAN_IE_EWE					//bit18: 警告状态中断使能
					// |FDCAN_IE_EPE					//bit17: 错误被动中断使能
					// |FDCAN_IE_ELOE					//bit16: 错误记录语出中断使能
					// |FDCAN_IE_TOOE					//bit15: 超时中断使能
					// |FDCAN_IE_MRAFE					//bit14: 信息RAM访问失败中断使能
					// |FDCAN_IE_TSWE					//bit13: 时间戳重复中断使能
					// |FDCAN_IE_TEFLE					//bit12: TX事件FIFO元素丢失中断使能
					// |FDCAN_IE_TEFFE					//bit11: TX时间FIFO满中断使能
					// |FDCAN_IE_TEFNE					//bit10: TX事件FIFO新元素进入中断使能
					// |FDCAN_IE_TFEE					//bit09: TXFIFO空中断使能
					// |FDCAN_IE_TCFE					//bit08: 发送取消完成中断使能
					|FDCAN_IE_TCE					//bit07: 传输完成中断使能
					// |FDCAN_IE_HPME					//bit06: 高优先级消息中断使能
					// |FDCAN_IE_RF1LE					//bit05: RXFIFO1报文丢失中断使能
					// |FDCAN_IE_RF1FE					//bit04: RXFIFO1消息满中断使能
					|FDCAN_IE_RF1NE					//bit03: RXFIFO1新消息中断使能
					// |FDCAN_IE_RF0LE					//bit02: RXFIFO0报文丢失中断使能
					// |FDCAN_IE_RF0FE					//bit01: RXFIFO0消息满中断使能
					|FDCAN_IE_RF0NE					//bit00: RXFIFO0新消息中断使能
					;
	FDCAN1->ILE = 0x00000000
					|FDCAN_ILE_EINT1					//bit01: 中断总线 fdcan_intr1_it 使能
					|FDCAN_ILE_EINT0					//bit00: 中断总线 fdcan_intr0_it 使能
					;
	FDCAN1->RXGFC = 0
					// |(0 << FDCAN_RXGFC_LSE_Pos)		//bit[27:24]: 列表信息拓展【0|无拓展消息过滤】【1|1~8拓展消息】【>8|被解释为8】
					// |(0 << FDCAN_RXGFC_LSS_Pos)		//bit[20:16]: 【0|无标准消息ID过滤】【1~28|标准消息ID元素过滤数量】【>28|被解释为28】
					// |FDCAN_RXGFC_F0OM				//bit09: FIFO0模式:覆盖或者堵塞【0|阻塞模式】【1|覆盖模式】
					// |FDCAN_RXGFC_F1OM				//bit08: FIFO1模式:覆盖或者堵塞【0|阻塞模式】【1|覆盖模式】
					// |(0 << FDCAN_RXGFC_ANFS_Pos)	//bit[05:04]: 定义如何处理接收到的id为11位且与筛选器列表中的任何元素不匹配的消息。【0|在FIFO0中接收】【1|在FIFO1中接收】【2~3|拒绝】
					// |(0 << FDCAN_RXGFC_ANFE_Pos)	//bit[03:02]: 定义如何处理接收到的id为29位且与筛选器列表中的任何元素不匹配的消息。【0|在FIFO0中接收】【1|在FIFO1中接收】【2~3|拒绝】
					// |FDCAN_RXGFC_RRFS				//bit01: 【1|拒绝所有11位ID远程标准帧】
					// |FDCAN_RXGFC_RRFE				//bit00: 【1|拒绝所有29位ID远程标准帧】
					;
	FDCAN1->XIDAM = 0x1FFFFFFF;						//FDCAN 扩展 ID 和屏蔽寄存器 
	FDCAN1->TXBTIE = 0
					// |0x00000004						//bit02: TxBuffer【1|发送中断使能】
					// |0x00000002						//bit01: TxBuffer【1|发送中断使能】
					 |0x00000001						//bit00: TxBuffer【1|发送中断使能】
					;
	FDCAN1->TXBCIE = 0
					// |0x00000004						//bit02: TxBuffer【1|取消中断使能】
					// |0x00000002						//bit01: TxBuffer【1|取消中断使能】
					// |0x00000001						//bit00: TxBuffer【1|取消中断使能】
					;

	FDCAN1_RAM->FILTER_11BIT[0] = 0x00000000			//配置滤波器,当前选择为指定11-bit ID
								|(1 << FDCANx_RAM_FILTER11_S0_SFT_Pos)
								|(1 << FDCANx_RAM_FILTER11_S0_SFEC_Pos)
								|(0x209 << FDCANx_RAM_FILTER11_S0_SFID1_Pos)
								|(0x609 << FDCANx_RAM_FILTER11_S0_SFID2_Pos)
								;

	// FDCAN1_RAM->FILTER_11BIT[1] = 0x00000000
	// 							|(1 << FDCANx_RAM_FILTER11_S0_SFT_Pos)
	// 							|(1 << FDCANx_RAM_FILTER11_S0_SFEC_Pos)
	// 							|(0x209 << FDCANx_RAM_FILTER11_S0_SFID1_Pos)
	// 							|(0x609 << FDCANx_RAM_FILTER11_S0_SFID2_Pos)
	// 							;

	FDCAN1->RXGFC = 0x00000000
					|(0 << FDCAN_RXGFC_LSE_Pos)			//bit[27:24]: 29-bit ID列表大小【0|无拓展帧ID滤波】【1~8|29bitID列表大小数】【>8|认为是8】
					|(1 << FDCAN_RXGFC_LSS_Pos)			//bit[20:16]: 11-bit ID列表大小【0|无拓展帧ID滤波】【1~28|11bitID列表大小数】【>28|认为是28】
					|FDCAN_RXGFC_F0OM					//bit09: FIFO0的接收模式(【0|阻塞】或【1|覆盖】)
					|FDCAN_RXGFC_F1OM					//bit08: FIFO1的接收模式(【0|阻塞】或【1|覆盖】)
					|(1 << FDCAN_RXGFC_ANFS_Pos)		//bit[05:04]: 不匹配的29-bitID接收配置【0|FIFO0接收】【1|FIFO1接收】【2~3|拒绝】
					|(1 << FDCAN_RXGFC_ANFE_Pos)		//bit[03:02]: 不匹配的11-bitID接收配置【0|FIFO0接收】【1|FIFO1接收】【2~3|拒绝】
					// |FDCAN_RXGFC_RRFS					//bit01: 拒绝远程帧【1|拒绝所有带有 11 位标准 ID 的远程帧】
					// |FDCAN_RXGFC_RRFE					//bit00: 拒绝远程拓展帧【1|拒绝所有带有 29 位标准 ID 的远程帧】
					;

	FDCAN1->CCCR &= ~FDCAN_CCCR_INIT;
}

返回第6章

附录2 发送函数

返回第7章

/**
 * @description: 经典CAN模式,11-bit地址,发送数据帧或远程帧
 * @param {uint16_t} ID		11位ID
 * @param {uint8_t} RTR		【0|发送数据帧】【1|发送远程帧】
 * @param {uint8_t} DLC		【0~8|发送数据数量为0~8】
 * @param {uint8_t} *buffer	数据地址
 * @return {*}
 */
void FDCAN1_TxBuffer1_SendData_11ID(uint16_t ID,uint8_t RTR,uint8_t DLC,Buffer_64Byte_Struct *buffer)
{
	FDCAN1_TXBUFFER1->bit_11ID.T0_ESI = 0;//
	FDCAN1_TXBUFFER1->bit_11ID.T0_XTD = 0;//【0|11-bit】【1|29-bit】
	FDCAN1_TXBUFFER1->bit_11ID.T0_RTR = 0;//【0|发送数据帧】【1|发送远程帧】
	FDCAN1_TXBUFFER1->bit_11ID.T0_ID = ID;

	FDCAN1_TXBUFFER1->bit_11ID.T1_MM = 0;
	FDCAN1_TXBUFFER1->bit_11ID.T1_EFC = 0;//【0|不保存TX事件】【1|保存】
	FDCAN1_TXBUFFER1->bit_11ID.T1_FDF = 0;//【0|经典CAN】【1|FDCAN】(CCCR寄存器中的FDOE配置为0,因此此位无意义)
	FDCAN1_TXBUFFER1->bit_11ID.T1_BRS = 0;//【0|无波特率切换】【1|有波特率切换】(CCCR寄存器中的FDOE配置为0,因此此位无意义)
	FDCAN1_TXBUFFER1->bit_11ID.T1_DLC = DLC;//【0~8|发送数据为0~8】【9~15|经典CAN为8,FDCAN为12/16/20/24/32/48/64】

	FDCAN1_TXBUFFER1->bit_11ID.DataWord[0] = buffer->DataWord[0];
	FDCAN1_TXBUFFER1->bit_11ID.DataWord[1] = buffer->DataWord[1];

	FDCAN1->TXBAR |= 0x00000000	//置位发送请求
					// |BIT2
					// |BIT1
					|BIT0
					;
}

返回第7章

附录3 中断程序

返回第7章
返回第8章


void FDCAN1_IT0_IRQHandler(void)
{
	if(FDCAN1->IR & FDCAN_IR_RF0N)//判断中断线
	{
		FDCAN1->IR |= FDCAN_IR_RF0N;//清除中断标志
		switch((FDCAN1->RXF0S & FDCAN_RXF0S_F0GI) >> FDCAN_RXF0S_F0GI_Pos)//读取数据索引
		{
			case 0://索引0
				CAN_Rxbuffer[0] = FDCAN1_RAM->Rx_FIFO_0[0];
				CAN_Rxbuffer[1] = FDCAN1_RAM->Rx_FIFO_0[1];//如果只有8 Bytes 读到这就行了
				CAN_Rxbuffer[2] = FDCAN1_RAM->Rx_FIFO_0[2];
				CAN_Rxbuffer[3] = FDCAN1_RAM->Rx_FIFO_0[3];
				CAN_Rxbuffer[4] = FDCAN1_RAM->Rx_FIFO_0[4];
				CAN_Rxbuffer[5] = FDCAN1_RAM->Rx_FIFO_0[5];
				CAN_Rxbuffer[6] = FDCAN1_RAM->Rx_FIFO_0[6];
				CAN_Rxbuffer[7] = FDCAN1_RAM->Rx_FIFO_0[7];
				CAN_Rxbuffer[8] = FDCAN1_RAM->Rx_FIFO_0[8];
				CAN_Rxbuffer[9] = FDCAN1_RAM->Rx_FIFO_0[9];
				CAN_Rxbuffer[10] = FDCAN1_RAM->Rx_FIFO_0[10];
				CAN_Rxbuffer[11] = FDCAN1_RAM->Rx_FIFO_0[11];
				CAN_Rxbuffer[12] = FDCAN1_RAM->Rx_FIFO_0[12];
				CAN_Rxbuffer[13] = FDCAN1_RAM->Rx_FIFO_0[13];
				CAN_Rxbuffer[14] = FDCAN1_RAM->Rx_FIFO_0[14];
				CAN_Rxbuffer[15] = FDCAN1_RAM->Rx_FIFO_0[15];
				CAN_Rxbuffer[16] = FDCAN1_RAM->Rx_FIFO_0[16];
				CAN_Rxbuffer[17] = FDCAN1_RAM->Rx_FIFO_0[17];//读取数据
				FDCAN1->RXF0A = 0;//确认读取完毕
				break;
			case 1:
				CAN_Rxbuffer[0] = FDCAN1_RAM->Rx_FIFO_0[18];
				CAN_Rxbuffer[1] = FDCAN1_RAM->Rx_FIFO_0[19];//如果只有8 Bytes 读到这就行了
				CAN_Rxbuffer[2] = FDCAN1_RAM->Rx_FIFO_0[20];
				CAN_Rxbuffer[3] = FDCAN1_RAM->Rx_FIFO_0[21];
				FDCAN1->RXF0A = 1;//确认读取完毕
				break;
			case 2:
				CAN_Rxbuffer[0] = FDCAN1_RAM->Rx_FIFO_0[36];
				CAN_Rxbuffer[1] = FDCAN1_RAM->Rx_FIFO_0[37];//如果只有8 Bytes 读到这就行了
				CAN_Rxbuffer[2] = FDCAN1_RAM->Rx_FIFO_0[38];
				CAN_Rxbuffer[3] = FDCAN1_RAM->Rx_FIFO_0[39];
				FDCAN1->RXF0A = 2;//确认读取完毕
				break;
			default:break;
		}
	}
	else if(FDCAN1->IR & FDCAN_IR_TC)//发送完毕中断标志
	{
        FDCAN1->IR |= FDCAN_IR_TC;//清除中断标志
		//FDCAN1_TxBuffer1_SendData_11ID(0x209,0,8,&CAN_Txbuffer);
	}
}

返回第7章
返回第8章

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-09-05 11:11:07  更:2021-09-05 11:13: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 1:48:02-

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