zynq之CAN调试

根据原理图,zynq IP配置CAN0 -- MIO10、11

使用USBCAN-E-U分析仪,配套的是ZCANPRO软件

https://blog.csdn.net/jpyjpy123/category_12463112.html

ZYNQ:PS-CAN总线功能应用_zynqcan驱动-CSDN博客

 ZYNQ CAN总线之CAN ID过滤器分析-CSDN博客

代码介绍

比较详细的介绍:(包括CAN相关概念&代码解析)

Xilinx-ZYNQ7000系列-学习笔记(26):CAN总线_zynq的can通信-CSDN博客

选择xcanps_intr_example模板,以下是CAN的配置:

#define CAN_DEVICE_ID		XPAR_XCANPS_0_DEVICE_ID
#define INTC_DEVICE_ID		XPAR_SCUGIC_SINGLE_DEVICE_ID
#define CAN_INTR_VEC_ID		XPAR_XCANPS_0_INTR

/* Maximum CAN frame length in word */
#define XCANPS_MAX_FRAME_SIZE_IN_WORDS (XCANPS_MAX_FRAME_SIZE / sizeof(u32))

#define FRAME_DATA_LENGTH	8 /* Frame Data field length */

/*
 * Message Id Constant.
 */
#define TEST_MESSAGE_ID		2000				

/*
 * Timing parameters to be set in the Bit Timing Register (BTR).
 * These values are for a 40 Kbps baudrate assuming the CAN input clock
 * frequency is 24 MHz.
 */
#define TEST_BTR_SYNCJUMPWIDTH		3
#define TEST_BTR_SECOND_TIMESEGMENT	2
#define TEST_BTR_FIRST_TIMESEGMENT	15

/*
 * The Baud rate Prescalar value in the Baud Rate Prescaler Register
 * needs to be set based on the input clock  frequency to the CAN core and
 * the desired CAN baud rate.
 * This value is for a 40 Kbps baudrate assuming the CAN input clock frequency
 * is 24 MHz.
 */
#define TEST_BRPR_BAUD_PRESCALAR	29		

/// Calculate baudrate = CAN_CLK / ((SYNCJUMPWIDTH + SECOND_TIMESEGMENT + FIRST_TIMESEGMENT ) * (PRESCALAR + 1))
/// 			40K   = 24M    / ((	3		   +		2			+		15			) * (	29	   + 1))

波特率 baudrate = CAN_CLK / ((SYNCJUMPWIDTH + SECOND_TIMESEGMENT + FIRST_TIMESEGMENT ) * (PRESCALAR + 1))

CAN_CLK在zynq IP配置界面设置。

s32 XCanPs_SelfTest(XCanPs *InstancePtr)
{
	u8 *FramePtr;
	s32 Status;
	u32 Index;
	u8 GetModeResult;
	u32 RxEmptyResult;

	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);

	XCanPs_Reset(InstancePtr);

	/*
	 * The device should enter Configuration Mode immediately after
	 * reset above is finished. Now check the mode and return error code if
	 * it is not Configuration Mode.
	 */
	if (XCanPs_GetMode(InstancePtr) != XCANPS_MODE_CONFIG) {
		Status = XST_FAILURE;
		return Status;
	}

    //波特率设置
	(void)XCanPs_SetBaudRatePrescaler(InstancePtr, (u8)29U);			
	(void)XCanPs_SetBitTiming(InstancePtr, (u8)3U, (u8)2U, (u8)15U);	

	/*
	 * Enter the loop back mode.
	 */
	XCanPs_EnterMode(InstancePtr, XCANPS_MODE_LOOPBACK);
	GetModeResult = XCanPs_GetMode(InstancePtr);
	while (GetModeResult != ((u8)XCANPS_MODE_LOOPBACK)) {
		GetModeResult = XCanPs_GetMode(InstancePtr);
	}

	// ID和端口    Length
	TxFrame[0] = (u32)XCanPs_CreateIdValue((u32)2000U, (u32)0U, (u32)0U, (u32)0U, (u32)0U);
	TxFrame[1] = (u32)XCanPs_CreateDlcValue((u32)8U);

	FramePtr = (u8 *)((void *)(&TxFrame[2]));
	for (Index = 0U; Index < 8U; Index++) {
		if(*FramePtr != 0U) {
			*FramePtr = (u8)Index;
			*FramePtr++;
		}
	}

	/*
	 * Send the frame.
	 */
	Status = XCanPs_Send(InstancePtr, TxFrame);
	if (Status != (s32)XST_SUCCESS) {
		Status = XST_FAILURE;
		return Status;
	}

	/*
	 * Wait until the frame arrives RX FIFO via internal loop back.
	 */
	RxEmptyResult = XCanPs_ReadReg(((InstancePtr)->CanConfig.BaseAddr),
			XCANPS_ISR_OFFSET) & XCANPS_IXR_RXNEMP_MASK;

	while (RxEmptyResult == (u32)0U) {
		RxEmptyResult = XCanPs_ReadReg(((InstancePtr)->CanConfig.BaseAddr),
				XCANPS_ISR_OFFSET) & XCANPS_IXR_RXNEMP_MASK;
	}

	/*
	 * Receive the frame.
	 */
	Status = XCanPs_Recv(InstancePtr, RxFrame);
	if (Status != (s32)XST_SUCCESS) {
		Status = XST_FAILURE;
		return Status;
	}

	/*
	 * Verify Identifier and Data Length Code.
	 */
	if (RxFrame[0] !=
		(u32)XCanPs_CreateIdValue((u32)2000U, (u32)0U, (u32)0U, (u32)0U, (u32)0U)) {
		Status = XST_FAILURE;
		return Status;
	}

	if ((RxFrame[1] & ~XCANPS_DLCR_TIMESTAMP_MASK) != TxFrame[1]) {
		Status = XST_FAILURE;
		return Status;
	}


	for (Index = 2U; Index < (XCANPS_MAX_FRAME_SIZE_IN_WORDS); Index++) {
		if (RxFrame[Index] != TxFrame[Index]) {
			Status = XST_FAILURE;
			return Status;
		}
	}

	/*
	 * Reset device again before returning to the caller.
	 */
	XCanPs_Reset(InstancePtr);

	Status = XST_SUCCESS;
	return Status;
}

ID为2000

详细代码:

CAN总线介绍及在ZYNQ 7020中的应用_zynq can-CSDN博客

驱动下载

CAN设备打不开:

设备管理器中是未知设备

广成科技USBCAN常见问题解答 - 百度文库

下载驱动试试看

如何安装USBCAN-E(2E)-U驱动?_360问答

更新驱动程序-->不选择搜索,选择从磁盘安装

可以识别到了:(用ECANTools的驱动就显示为ECANTOOLS_CAN(大概是这么个名字,反正就是从名字上可以看出它用的软件或者USBCAN硬件))

 看USBCAN-E-U的手册:SYS亮绿灯(之前亮红灯说明驱动不对)

ZCANPro软件(USBCAN-E-U配套的软件)

SDK操作

1. xilinx SDK如何退出Debug:

xilinx sdk退出Debug模式回到C开发布局_xilinx sdk step over 进入 .s-CSDN博客

 

2. 添加Linker script

 

右键工程,选择Properties

 

3. SDK打开界面:(vivado重新打开就好)

vivado SDK :Plu-in org.eclipse.cdt.ui was unable to load class org.eclipse.cdt.internal.ui.editor.CE_plug-in org.eclipse.cdt.ui was unable to load clas-CSDN博客 

 sdk debug 无法进入main,且无法单步调试

Xilinx SDK程序Debug无法在main函数入口处停住解决_sdk 调试不进main-CSDN博客 

ZYNQ SDK DEBUG 无法进入main函数_zynq cpu0不进入main-CSDN博客 

 有时候debug还会出现如下界面:

Xilinx Toos --> Generate linker script:(下面三个改成ram) (后面又改回来了)

 

 这里要选NO:(后面都选yes了,因为选no还会再出现)

然后就直接main跑完了。。。。

 但是改了以下设置,加了断点(没用),程序就跑飞了:

(到了汇编的界面了)

 Xilinx SDK程序Debug无法在main函数入口处停住解决_sdk 调试不进main-CSDN博客

关于zynq debug进入main函数或汇编函数的小技巧_使用 xilinx sdk 进行单步 debug 时,如何不让程序进入汇编代码?-CSDN博客

zynq IP很重要,但回去看了一下,配置也没有错误。

发现不是跑飞,因为Console可以看到printf的输出:

修改代码,while(1)让CAN一直发送数据

ZCANPRO能接收到。

那么现在看看接收数据的代码怎么写。

第一次接收,数据长度和ZCANPRO发送的不一致;强制修改data_length为8后

两次接收到的数据的顺序都乱了。

/*   接收后发送     */
canRevFrame.ID = ID_RECEIVED;
canRevFrame.remote = 0;
canRevFrame.len = 8;
/* TxFrame[1] = (u32)XCanPs_CreateDlcValue(frame.len); */
FramePtr = (u8 *)(&RxFrame[2]);
for (Index = 0; Index < 8; Index++) {
	canRevFrame.data[Index] = *FramePtr++;
}
Status = CAN0_SendFrame(canRevFrame);


/*   发送     */
FramePtr = (u8 *)(&TxFrame[2]);
for (Index = 0; Index < 8; Index++) {
	*FramePtr++ = data[Index];,
}

换成这样就可以了:

Status = XCanPs_Send(CanInstPtr, RxFrame);

  • 16
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值