zynqCAN中断梳理

1、根据硬件定义设备的ID和地址

/*
* The configuration table for devices
*/

XCanPs_Config XCanPs_ConfigTable[] =
{
	{
		XPAR_PS7_CAN_0_DEVICE_ID,
		XPAR_PS7_CAN_0_BASEADDR
	}
};

2、根据设备地址初始化XCanPs结构体,包括设备的ID和设备的基址还有中断的处理的回调函数

s32 XCanPs_CfgInitialize(XCanPs *InstancePtr, XCanPs_Config *ConfigPtr,
				u32 EffectiveAddr)
{
	s32 Status;
	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(ConfigPtr != NULL);

	/*
	 * Set some default values for instance data, don't indicate the device
	 * is ready to use until everything has been initialized successfully.
	 */
	InstancePtr->IsReady = 0U;
	InstancePtr->CanConfig.BaseAddr = EffectiveAddr;
	InstancePtr->CanConfig.DeviceId = ConfigPtr->DeviceId;

	/*
	 * Set all handlers to stub values, let user configure this data later.
	 */
	InstancePtr->SendHandler = (XCanPs_SendRecvHandler) StubHandler;
	InstancePtr->RecvHandler = (XCanPs_SendRecvHandler) StubHandler;
	InstancePtr->ErrorHandler = (XCanPs_ErrorHandler) StubHandler;
	InstancePtr->EventHandler = (XCanPs_EventHandler) StubHandler;

	/*
	 * Indicate the component is now ready to use.
	 */
	InstancePtr->IsReady = XIL_COMPONENT_IS_READY;

	/*
	 * Reset the device to get it into its initial state.
	 */
	XCanPs_Reset(InstancePtr);

	Status = XST_SUCCESS;
	return Status;
}

3、配置CAN device,设置波特率,设置同步位和同步时间 2 3 15 49

static void Config(XCanPs *InstancePtr)
{
	// Enter Configuration Mode if the device is not currently in  Configuration Mode.
	XCanPs_EnterMode(InstancePtr, XCANPS_MODE_CONFIG);
	while(XCanPs_GetMode(InstancePtr) != XCANPS_MODE_CONFIG);

	// Setup Baud Rate Prescaler Register (BRPR) and Bit Timing Register (BTR) .
	XCanPs_SetBaudRatePrescaler(InstancePtr, BRPR_BAUD_PRESCALAR);
	XCanPs_SetBitTiming(InstancePtr, BTR_SYNCJUMPWIDTH,
					BTR_SECOND_TIMESEGMENT,
					BTR_FIRST_TIMESEGMENT);

	// Set the threshold value for the Rx FIFO Watermark interrupt.
	XCanPs_SetRxIntrWatermark(InstancePtr, RX_THRESHOLD);
}

zynqCAN中断梳理_第1张图片

zynqCAN中断梳理_第2张图片

例:

#define BTR_SYNCJUMPWIDTH        3
#define BTR_SECOND_TIMESEGMENT    2 (TS2)
#define BTR_FIRST_TIMESEGMENT    15 (TS1)

#define BRPR_BAUD_PRESCALAR    49

freqCAN_REF_CLK == 100M

100M / ((49+1)* (3+2+15))  =  100K

CAN总线同步跳转宽度 (以下是转载对SJW的理解)

汽车CAN总线方案提供商_汽车CAN总线实验教学系统_CAN总线仿真开发工具   2012-07-15 22:35:49 作者:PFCEO 来源: 文字大小:[大][中][小]

zynqCAN中断梳理_第3张图片

  1.          同步跳转宽度(Synchronization Jump Width

l         SJWPES1PES2调整的最大长度;

l         SJW必须小于PES1PES2的最小值;

l         SJW可以通过编程从1MinPhase_Seg14)取值。

同步跳转宽度如图4.11.7。

zynqCAN中断梳理_第4张图片

  1.          延迟时间的确定

l         保证2倍信号在总线的延迟。

 

延迟时间的确认如图4.11.8。

 

zynqCAN中断梳理_第5张图片

  1.          位定时参数确定

位定时参数确定如图4.11.9。

zynqCAN中断梳理_第6张图片

  1.          位定时确定的样例

l         MCU晶振8MHz;

l         位速率1Mbps;

l         总线长度20m;

l         单位总线延迟5ns/m;

l         物理接口的发送接收延迟150ns@85C(样例From Freescale AN1798)。

位定时确定样例如图4.11.10。

zynqCAN中断梳理_第7张图片

 

1.1.1    同步

CAN的同步包括硬同步和重同步两种同步方式,同步规则是:

l         一个位时间内只允许一重同步方式;

l         任何一个“隐性”到“显性”的跳变都可用于同步;

l         硬同步发生在SOF,所有接收节点调整各自当前位的同步段,使其位于发送的SOF位内;

l         重同步发生在一个帧的其他位场内,当跳变沿落在了同步段之外;

l         在SOF到仲裁场有多个节点同时发送的情况下,发送节点对跳变沿不进行重同步。

  1.          硬同步

发生在SOF位,所有接收节点调整各自当前位的同步段,调整宽度不限。

硬同步的原理如图4.12.1。

zynqCAN中断梳理_第8张图片

  1.          重同步

相位误差为正,跳变沿位于采样点之前,相位缓冲段1增长。

相位误差为正的重同步原理如图4.12.2。

zynqCAN中断梳理_第9张图片

相位误差为负,跳变沿位于前一个位的采样点之后,相位缓冲短缩短。

相位误差为负的重同步原理如图4.12.3。

zynqCAN中断梳理_第10张图片

 4、设置回调函数的实现处的地址

	// Set the interrupt handlers.
	XCanPs_SetHandler(CanInstPtr, XCANPS_HANDLER_SEND,	(void *)SendHandler, (void *)CanInstPtr);
	XCanPs_SetHandler(CanInstPtr, XCANPS_HANDLER_RECV,	(void *)RecvHandler, (void *)CanInstPtr);
	XCanPs_SetHandler(CanInstPtr, XCANPS_HANDLER_ERROR,	(void *)ErrorHandler, (void *)CanInstPtr);
	XCanPs_SetHandler(CanInstPtr, XCANPS_HANDLER_EVENT,	(void *)EventHandler, (void *)CanInstPtr);

 5、根据中断号和CAN结构体来连接中断Controller

	// Connect to the interrupt controller.
	Status = IntMapFunc(CanIntrId, (INT_FUNC_HANDLE_T)XCanPs_IntrHandler, (void *)CanInstPtr);

 6、滤波器设置、中断使能、进入正常运行模式

XCanPs_AcceptFilterSet(CanInstPtr, XCANPS_AFR_UAF1_MASK, XCANPS_IDR_ID1_MASK, VEHICLE_SPEED_ID << XCANPS_IDR_ID1_SHIFT);

	XCanPs_AcceptFilterSet(CanInstPtr, XCANPS_AFR_UAF2_MASK, XCANPS_IDR_ID1_MASK, VEHICLE_GEAR_DIRECTION_ID << XCANPS_IDR_ID1_SHIFT);

	XCanPs_AcceptFilterEnable(CanInstPtr, XCANPS_AFR_UAF1_MASK | XCANPS_AFR_UAF2_MASK);

	//	Enable the Receive FIFO Not Empty Interrupt and the	New Message Received Interrupt.
	XCanPs_IntrEnable(CanInstPtr, XCANPS_IXR_RXFWMFLL_MASK);

	// Enter Normal Mode
	XCanPs_EnterMode(CanInstPtr, XCANPS_MODE_NORMAL);

7、深刻理解中断的响应过程(以接收为例)

Status = IntMapFunc(CanIntrId, (INT_FUNC_HANDLE_T)XCanPs_IntrHandler, (void *)CanInstPtr);

a、中断响应第一步:

XCanPs_IntrHandler 函数被触发

    if (((PendingIntr & (XCANPS_IXR_RXFWMFLL_MASK |
            XCANPS_IXR_RXNEMP_MASK)) != (u32)0) &&
        (CanPtr->RecvHandler != NULL)) {


        CanPtr->RecvHandler(CanPtr->RecvRef);
    }

b、CanInstPtr 中的接收handler被调用,这个函数我们上边已经绑定了实例化的函数。

XCanPs_SetHandler(CanInstPtr, XCANPS_HANDLER_RECV,    (void *)RecvHandler, (void *)CanInstPtr);

 

 

你可能感兴趣的:(zynq)