AXI_CAN IP 简单使用。(仿真、microblaze)
1.IP 简介
Core Options 界面
1.验收滤波器数量:这指定了CAN内核使用的验收滤波器对的数量。每个验收滤波器对由一个掩码寄存器和一个ID寄存器组成。这些寄存器可配置为接收特定标识符或一定范围的标识符。有效范围为0到4。
2. 发送先进先出(TX FIFO)深度:发送先进先出深度以CAN消息的数量来衡量。例如,深度为2的发送先进先出最多可容纳2条CAN消息。
注意:只有当MTBF触发器的CAN到AXI域选择设置为4时,深度8、16、32和64才有效。
3. 接收先进先出缓冲区深度:接收先进先出缓冲区深度以CAN消息的数量来衡量。例如,深度为2的接收先进先出缓冲区最多可容纳2条CAN消息。
注意:只有当MTBF触发器的CAN到AXI域选择设置为4时,深度8、16、32和64才有效。
4. 平均无故障时间触发器 CAN 到 AXI 域:用于同步从 CAN 域到 AXI 域的信号的平均无故障时间触发器数量。
选择4这个值可以提高内核的平均无故障时间(MTBF)。
时钟:
can_clk的频率可以为8至24 MHz。
s_axi_aclk的频率可以为8至100 MHz。
can_clk和s_axi_aclk可以是异步的,也可以由同一时钟源提供时钟。
简单测试
配置如下,不使用验收滤波器。
然后打开官方例程如下
使用AXI Traffic Generator 通过AXI_lite接口配置can ip 。
addr.coe ctrl.coe data.coe mask.coe
这四个文件中的每一行都是相互对应的,共同构成一个完整的事务。
例如,第一行数据:
ctrl.coe中的值 00000001表示:“这是一个写操作”。
addr.coe中的值 40000000表示:“写入的地址是 0x40000000”。
data.coe中的值 00000001表示:“要写入的数据是 0x00000001”。
mask.coe中的值 FFFFFFFF表示:“所有4个字节都有效”。
IP核会按照这个顺序,逐行读取这些文件,生成相应的AXI-Lite总线流量。因此,确保这四个文件的行数一致、数据匹配是正确使用该IP核的关键。
接下来就是根据手册配置寄存器。部分寄存器地址如下。
我只用来仿真验证这个ip 所以配置为回环模式。
首先:
无论处于何种运行模式,当执行以下任一操作时,CAN内核都会进入配置模式:
• 向SRR寄存器的CEN位写入0。
• 向SRR寄存器的软件复位(SRST)位写入1。内核在软件复位后立即进入配置模式。
• 将s_axi_aresetn输入驱动为0。只要s_axi_aresetn为0,内核就会一直处于复位状态。当s_axi_aresetn被置为1后,内核进入配置模式。
所以上电复位之后默认处于配置模式。
1. 软件复位寄存器 SSR(0x000)
上电复位之后处于配置模式CEN为0,后面需设置 CEN为1,SRST为0从而进入其他模式。
0x000 0x00
2. MSR(0x04)
向模式选择寄存器(MSR)写入数据可使CAN内核进入休眠、环回或正常模式。在正常模式下,CAN内核参与正常的总线通信。若SLEEP位被置为1,CAN内核将进入休眠模式。若LBACK位被置为1,CAN内核将进入环回模式。
3. 传输层配置寄存器(BRPR BTR)
有两个传输层配置寄存器:波特率预分频器寄存器(BRPR)和位定时寄存器(BTR)。只有当SRR中的CEN位为0时,才能对这些寄存器进行写入操作。
波特率预分频寄存器(BRPR)地址0x008
位定时寄存器(BTR)0x00C
其中 TS1、TS2、SJW 的实际值都要比写入值多 1。
通过选择合适的 BRP、TS1、TS2、SJW 即可实现所需 CAN 总线速率和采样点。
例程:BRPR写入0x01,BTR写入0xb8
波特率计算:
3. 中断使能寄存器(IER 0x20)
IER(Interrupt Enable Register) 仅用于控制是否向外部中断输出线(p2bus_intrevent)产生中断,也就是决定 CPU 是否会收到中断信号。
4.读写数据
• 标准帧:标准帧有一个11位的标识符字段,称为标准标识符。只有ID[28:18]、软件复位寄存器/远程传输请求(SRR/RTR)和IDE位有效。ID[28:18]是11位标识符。SRR/RTR位用于区分数据帧和远程帧。标准帧的IDE位为0。其他位字段未被使用。
• 扩展帧:扩展帧除了标准标识符外,还有一个18位的标识符扩展。所有位字段均有效。远程传输请求(RTR)位用于区分数据帧和远程帧(所有扩展帧的替代远程请求(SRR)/远程传输请求(RTR)位以及标识符扩展(IDE)位均为1)。
DLC 0-8 表示 接下来数据DB0到DB几有效
仿真
先看官方例程:
复位之后进入配置模式,然后设置寄存器,在向TX_fifo里面写数据,模式是回环模式。
上图是写的第一组数据,
这是rx_fifo里面的数据,因为是回环模式,所以写到tx_fifo里面的数据会之间发送到rx_fifo里面。
仿照例程可以自己学习一下怎么配置寄存器。
addr.coe
memory_initialization_radix=16;
memory_initialization_vector=
00000004,
00000008,
0000000C,
00000000,
00000030,
00000034,
00000038,
0000003c,
00000030,
00000034,
00000038,
0000003c,
0000001c,
00000050,
00000054,
00000058,
0000005c,
00000024,
0000001c,
00000050,
00000054,
00000058,
0000005c,
FFFFFFFF;
ctrl.coe
memory_initialization_radix=16;
memory_initialization_vector=
00010100,
00010201,
00010302,
00010403,
00010504,
00010605,
00010706,
00010807,
00010908,
00010a09,
00010b0a,
00010c0b,
00000d0c,
00000e0d,
00000f0e,
0000100f,
00001110,
00011211,
00001312,
00001413,
00001514,
00001615,
00001716,
00000000;
data.coe
memory_initialization_radix=16;
memory_initialization_vector=
00000002,
00000001,
000000b8,
00000002,
4b200000,
80000000,
0eafac43,
cb000000,
4b200000,
80000000,
01234563,
12000000,
00000090,
4b200000,
80000000,
0eafac43,
cb000000,
00000000,
00000090,
4b200000,
00000000,
00000000,
00000000,
00000000;
mask.coe
memory_initialization_radix=16;
memory_initialization_vector=
00000000,
00000000,
00000000,
00000000,
00000000,
00000000,
00000000,
00000000,
00000000,
00000000,
00000000,
00000000,
00000090,
FFFFFFFF,
FFFFFFFF,
FFFFFFFF,
FFFFFFFF,
00000000,
00000090,
FFFFFFFF,
00000000,
00000000,
00000000,
00000000;
结果如下:
micro blaze+axi_can
搭建一个简单的软核。
打开sdk选择带中断的例程
int XCan_SelfTest(XCan *InstancePtr)
{u8 *FramePtr;u32 Result;u32 Index;Xil_AssertNonvoid(InstancePtr != NULL);Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);/* Reset device first */XCan_Reset(InstancePtr);/** 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) {return XST_FAILURE;}/** Setup Baud Rate Prescaler Register (BRPR) and Bit Timing Register* (BTR) such that CAN baud rate equals 40Kbps, given the CAN clock* equal to 24MHz.*/XCan_SetBaudRatePrescaler(InstancePtr, 29);XCan_SetBitTiming(InstancePtr, 3, 2, 15);/* Enter loopback mode */XCan_EnterMode(InstancePtr, XCAN_MODE_LOOPBACK);while (XCan_GetMode(InstancePtr) != XCAN_MODE_LOOPBACK);/** Create a frame to send with known values so we can verify them* on receive.*/TxFrame[0] = XCan_CreateIdValue(TEST_MESSAGE_ID, 0, 0, 0, 0);TxFrame[1] = XCan_CreateDlcValue(TEST_CAN_DLC);FramePtr = (u8 *) (&TxFrame[2]);for (Index = 0; Index < 8; Index++) {*FramePtr++ = (u8) Index;}/* Send the frame. */Result = XCan_Send(InstancePtr, TxFrame);if (Result != XST_SUCCESS) {return XST_FAILURE;}/* Wait until the frame arrives RX FIFO via internal loop back */while (XCan_IsRxEmpty(InstancePtr) == TRUE);/* Receive the frame */Result = XCan_Recv(InstancePtr, RxFrame);if (Result != XST_SUCCESS) {return XST_FAILURE;}/* Compare received frame with sent frame */for (Index = 0; Index < XCAN_MAX_FRAME_SIZE_IN_WORDS; Index++) {if (RxFrame[Index] != TxFrame[Index]) {return XST_FAILURE;}}/* Reset device again before return to the caller */XCan_Reset(InstancePtr);return XST_SUCCESS;
}
模式是回环模式,寄存器配置什么的跟上面仿真差不多。
debug一下可以看到发送数据
ID:0x8000000
DLC:0x80000000
data:0001020304050607
接收的一样。