ZYNQ:PL-CAN总线功能应用
流程背景
前期基本实现PS端的CAN总线功能,现阶段的主要目的是实现PL端的CAN总线功能,需要采用CAN IP。
PL系统搭建
PL外设时钟源
搭建完vivado系统后,需要在sdk编程。但是在配置PL-CAN时,意识到CAN时钟值不清楚,于是检查zynq系统,发现PL-CAN外设的时间来自于FCLK-CLK0。这个时钟值与CAN外设的关系是可以在block design看到的。配置表显示FCLK-CLK0为50Mhz,编程可以按照这个值。
下载失效:
再次出现下载程序,zynq开发板没有反应的情况。下载的程序是LED,以前应用时也没有特别的问题。考虑到explorer包含大多的应用工程,于是删除了无关的工程,重新实现特定的功能。
run as program FPGA配置:
前期下载程序时,有时program FPGA无法点击。这可能也是下载程序不成功的原因,可以考虑从这个现象入手。
XCan_GetMode error:
运行以下程序时,发现XCan_SelfTes无法获得配置模式。因此需要定位外设到底哪里出现问题。
if (XCan_GetMode(InstancePtr) != XCAN_MODE_CONFIG) {print("test1\r\n");return XST_FAILURE;}
定位问题到XCan_GetMode,获得状态码为normal mode而不是configuration mode。 其中,xil_printf能够进入参数化输出,print无法实现。这说明模块本身就出现问题,无法在重置后,顺利进入配置模式。
#define XCAN_MODE_CONFIG 0x00000001 /**< Configuration mode */
#define XCAN_MODE_NORMAL 0x00000002 /**< Normal mode */
#define XCAN_MODE_LOOPBACK 0x00000004 /**< Loop Back mode */
#define XCAN_MODE_SLEEP 0x00000008 /**< Sleep mode *//** The device should enter Configuration Mode immediately after the* reset above is finished. Now check the mode and return error code if* it is not Configuration Mode.*/if (XCan_GetMode(InstancePtr) != XCAN_MODE_CONFIG) {value = XCan_GetMode(InstancePtr);xil_printf("getmode error:\r\n");xil_printf("getMode:%d\r\n",value);return XST_FAILURE;}
即使在重置函数后添加EnterMode函数,也无法顺利进入**配置模式。面对这种问题,感觉远处着手。
/* Reset device first */XCan_Reset(InstancePtr);XCan_EnterMode(InstancePtr, XCAN_MODE_CONFIG);/** The device should enter Configuration Mode immediately after the* reset above is finished. Now check the mode and return error code if* it is not Configuration Mode.*/if (XCan_GetMode(InstancePtr) != XCAN_MODE_CONFIG) {print("get mode error\n\r");return XST_FAILURE;}
由于这是一个新的工程,我选择先测试自己编写代码,测试一下PS-CAN外设。在这个基础上,慢慢定位PL-CAN的问题。在初始化PS-CAN时,selftest功能正常,这说明问题主要出现在CAN控制器外部。想到以前在microblaze平台测试CAN IP功能,是通过【学习了自动补全功能,alt+/感觉不错】
在编写CAN发送程序时,需要了解CAN帧的发送信息结构。按照其CAN帧的库函数逻辑,编写如下代码。可惜,逻辑分析仪现象如前期一样,单个CAN帧周期,却出现多个CAN的解码。虽然可能是波特率较小所致,但是调整波特率为80K时,仍然无法解析。编码值全为1,而且整个解码的长度是跟单个CAN帧周期的长度是一致。换言之,可能在没有CAN收发器的情况下,逻辑分析仪的接收波特率都变小的。虽然实际配置的波特率为500K。~虽然可以利用跳线使用野火开发板的CAN收发器,但是实际没有效果,不知道什么环节出现问题。
//测试can 功能自测status = XCanPs_SelfTest(&Can);print("self test point\r\n");if(status != XST_SUCCESS){print("self test error\n\r");}//配置波特率XCanPs_EnterMode(&Can, XCANPS_MODE_CONFIG);XCanPs_SetBaudRatePrescaler(&Can,3);XCanPs_SetBitTiming(&Can,3,2,15);//发送CAN数据XCanPs_EnterMode(&Can,XCANPS_MODE_NORMAL);while(XCanPs_GetMode(&Can) != XCANPS_MODE_NORMAL){print("normal mode error\r\n");sleep(1);};//装填Can帧数据TxFrame[0] = (u32)XCanPs_CreateIdValue((u32)2000,0,0,0,0);TxFrame[1] = (u32)XCanPs_CreateDlcValue((u32)8);FramePtr = (u8*)(&TxFrame[2]);for(i = 0;i<8;i++){*FramePtr++ = (u8)8;}//CAN发送while(XCanPs_IsTxFifoFull(&Can) == TRUE){print("IsTxFifoFull error\r\n");};XCanPs_Send(&Can,TxFrame);
工具问题:
考虑到没有相关工具,打算回到学校,拿到CAN-BUS逻辑分析仪以及CAN收发器之后,再做相关测试。这提醒我在做准备时,掉东西的巨大影响