【LPC54616的自学之路-4】FDCAN

串口搞得差不多了,接下来研究下这个芯片的FDCAN

 54616的FDCAN模块

首先这个芯片是支持FDCAN和普通的CAN的。

 然后去隔壁的ST看看H743【同样支持FDCAN】的芯片看一看

 是不是有些类似呢,其实你仔细看手册,对比NXP和ST对FDCAN这个IP的实现和其手册的描述,你会发现很有意思的事情

基本上都是差不多的,甚至有些描述基本就是一样的,寄存器也是

除了有些细微的不同之外,大部分功能基本上都是一致的【ST的CAN1有TTCAN的功能,NXP这个就没有,都是FDCAN】

估计都是按照某个标准做的吧,可能要实现一个FDCAN的IP核都得这样子实现吧^_^

这么弄的话倒是很友好了,ST的手册是有中文版的,NXP就没得了,可以互相对照着看一看,很有参考的价值

 54616的CAN功能代码实现

这里我们先以基础的普通CAN功能来举例子,估计这个FDCAN的功能应该也是类似的

这里第一次探索性的实验,我们采用SDK配置工具生成代码的方式,这个比较方便

以后熟悉了可以研究研究寄存器如何实现

打开MCUexpress,打开配置工具

按图配置时钟树

打开CAN0的时钟,配置为90MHz

到引脚这边,配置CAN的GPIO

然后到外设部分配置CAN的底层驱动

我这里按500Kbps配置,注意我们现在弄正常的CAN,FDCAN的选项去掉

这里会有一个警告,但是我现在也不知道到底是什么意思,反正生成的代码可以用

注意CAN总线的时序参数一定要设置对,500Kbps就尽可能的设置到500Kbps

不然CAN盒子是接收不到的

它有辅助你设置时序的计算器在上方,很方便的

 

接下来是消息缓冲区的分配

关于这个可以看看我之前写的H743 FDCAN的过滤表设置

因为这两个芯片的FDCAN是很类似的

唯一有点不同的是,这款芯片的缓冲区是需要用程序的SRAM作为分配来源的,不像H743是专有SRAM

这里我使用RX FIFO0,分配了20个,标准帧过滤表1个

发送FIFO分配了20个 

过滤器我们试一试,标准帧范围过滤,范围内的进来

这个工具真的是太方便了

最后打开RX FIFO0中断

 

然后生成代码,接下来就是发送和接收实现了.

CAN的发送和接收功能实现

发送的步骤,简单说就3步

  1. 填发送数据结构体
  2. 发送数据结构体写入芯片内部的发送缓冲区
  3. 请求芯片发送

接收的步骤

  1. 打开指定的接收缓冲新数据到来中断
  2. 中断函数里面判断中断标志,中断标志出现以后,执行对应的数据接收到接收数据结构体的函数
  3. 清除对应的中断标志

#include <stdio.h>
#include "board.h"
#include "peripherals.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "LPC54616.h"
#include "fsl_common.h"
/* TODO: insert other include files here. */

/* TODO: insert other definitions and declarations here. */
volatile bool txComplete = false;
volatile bool rxComplete = false;
mcan_tx_buffer_frame_t txFrame;
mcan_rx_buffer_frame_t rxFrame;
uint8_t tx_data[8];
uint8_t rx_data[8];
mcan_buffer_transfer_t txXfer;
/* CAN0中断 */
void CAN0_INT_0_IRQHANDLER(void) {

	
	if ((CAN0->IR & (1 << 0)) != 0) {
		//新消息到来
		CAN0->IR |= 1 << 0;
		//清除中断标志
		//取出数据
		MCAN_ReadRxFifo(CAN0, 0, &rxFrame);
		//接收标记
		rxComplete = true;
	}
	/*  Place your code here */

	/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F
	 Store immediate overlapping exception return operation might vector to incorrect interrupt. */
#if defined __CORTEX_M && (__CORTEX_M == 4U)
	__DSB();
#endif
}

/*
 * @brief   Application entry point.
 */

void Delay_xMs(uint32_t i) {
	uint16_t cnt = 22727;
	while (i--) {
		cnt = 22727;
		while (cnt--) {
			__asm volatile ("nop");
		}
	}
}

int main(void) {
	/* Init board hardware. */
	BOARD_InitBootPins();
	BOARD_InitBootClocks();
	BOARD_InitBootPeripherals();

	printf("Hello World\n");

	/* Force the counter to be placed into memory. */
	volatile static int i = 0;
	/* Config TX frame data. */
	memset(tx_data, 0, sizeof(uint8_t) * 8);
	uint8_t cnt = 0;
	for (cnt = 0; cnt < 8; cnt++) {
		tx_data[cnt] = cnt;
	}
	//配置发送帧的ID和长度
	txFrame.xtd = kMCAN_FrameIDStandard;
	txFrame.rtr = kMCAN_FrameTypeData;
	txFrame.fdf = 0;
	txFrame.brs = 0;
	txFrame.dlc = 8U;
	txFrame.id = 1 << 18;//标准帧需要左移18位
	txFrame.data = tx_data;
	txFrame.size = 8;
	txXfer.frame = &txFrame;
	txXfer.bufferIdx = 0;

	/* Create MCAN handle structure and set call back function. */

	/* Enter an infinite loop, just incrementing a counter. */
	while (1) {

		Delay_xMs(100);//延时100ms
		MCAN_WriteTxBuffer(CAN0, 0, &txFrame);//发送数据结构体写到内部缓冲
		MCAN_TransmitAddRequest(CAN0, 0);//请求发送
		/*处理接收 */
		if (rxComplete) {
			rxComplete = false;
			uint8_t j = 0;
			printf("RX ID: 0x%x\r\n", (rxFrame.id >>18));
			for (j = 0; j < rxFrame.dlc; j++) {
				rx_data[j] = rxFrame.data[j];
				printf("0x%x\t", rxFrame.data[j]);
			}
			printf("\r\n");
		}

		memset(rx_data, 0, 8);

	}
	return 0;
}

以后用到FDCAN的功能时再来补充FDCAN

来试一试FDCAN吧

目前只把发送调出来了,接收还不行

我买的USB转FDCAN发送的数据,不仅我的板子收不到,我的逻辑分析仪也抓不到,不知道为啥

但是它收得到我发的

目前只弄出来速率不会变化的FDCAN【也就是数据域和仲裁域速率一致的FDCAN功能】

变速率的我还没有调出来,USB转FDCAN好像识别不出来,不知道为什么

FDCAN配置

我把SDK里面的配置截图,截取下来

我自己觉得是不是我的速率和位时序那里填的不对呢

虽然我配的是仲裁域500K,数据域1M

把变速率FDCAN打开

我接收器那边也确实按这个配了,但是依然有问题

但是我调成下图的不变速率,我的FDCAN接收器和逻辑分析仪那边就可以正常收到了

看看以后能不能有新发现

FDCAN发送代码

和之前差不多

我就贴不一样的部分

int main(void) {
	/* Init board hardware. */
	BOARD_InitBootPins();
	BOARD_InitBootClocks();
	BOARD_InitBootPeripherals();

	printf("Hello World\n");

	/* Force the counter to be placed into memory. */
	volatile static int i = 0;
	/* Config TX frame data. */
	memset(tx_data, 0, sizeof(uint8_t) * 8);
	uint8_t cnt = 0;
	for (cnt = 0; cnt < 64; cnt++) {
		tx_data[cnt] = cnt;//数据按1-64这样
	}
	txFrame.xtd = kMCAN_FrameIDStandard;
	txFrame.rtr = kMCAN_FrameTypeData;
	txFrame.fdf = 1;//FDCAN数据
	txFrame.brs = 0;//变速率关闭,打开我的USB转FDCAN收不到,不知道是不是那边配置有问题
	txFrame.dlc = 15;
	txFrame.id = 1 << 18;
	txFrame.data = tx_data;
	txFrame.size = 64;//64字节
	txXfer.frame = &txFrame;
	txXfer.bufferIdx = 0;

	/* Create MCAN handle structure and set call back function. */

	/* Enter an infinite loop, just incrementing a counter. */
	while (1) {

		Delay_xMs(500);
		MCAN_WriteTxBuffer(CAN0, 0, &txFrame);
		MCAN_TransmitAddRequest(CAN0, 0);
		/* Wait until message received. */
		if (rxComplete) {
			rxComplete = false;
			uint8_t j = 0;
			printf("RX ID: 0x%x\r\n", (rxFrame.id >>18));
			for (j = 0; j < rxFrame.dlc; j++) {
				rx_data[j] = rxFrame.data[j];
				printf("0x%x\t", rxFrame.data[j]);
			}
			printf("\r\n");
		}

		memset(rx_data, 0, 64);
		i++;
		/* 'Dummy' NOP to allow source level single stepping of
		 tight while() loop */
		__asm volatile ("nop");
	}
	return 0;
}

我买的USB转FDCAN的上位机截图

 这个速率不变的FDCAN是能够收到的

逻辑分析仪的部分截图

完整的一包截图【好像有一个Warning】 

 

CRC分隔符必须是隐性位

会不会还是那个位时序取得不合理导致的呢?暂时就不知道了 

以后再看看能不能分析出问题在哪里

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值