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);
}
例:
#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总线方案提供商_汽车CAN总线实验教学系统_CAN总线仿真开发工具 2012-07-15 22:35:49 作者:PFCEO 来源: 文字大小:[大][中][小] |
l SJW为PES1和PES2调整的最大长度; l SJW必须小于PES1和PES2的最小值; l SJW可以通过编程从1到Min(Phase_Seg1,4)取值。 同步跳转宽度如图4.11.7。
l 保证2倍信号在总线的延迟。
延迟时间的确认如图4.11.8。
位定时参数确定如图4.11.9。
l MCU晶振8MHz; l 位速率1Mbps; l 总线长度20m; l 单位总线延迟5ns/m; l 物理接口的发送接收延迟150ns@85C(样例From Freescale AN1798)。 位定时确定样例如图4.11.10。
1.1.1 同步CAN的同步包括硬同步和重同步两种同步方式,同步规则是: l 一个位时间内只允许一重同步方式; l 任何一个“隐性”到“显性”的跳变都可用于同步; l 硬同步发生在SOF,所有接收节点调整各自当前位的同步段,使其位于发送的SOF位内; l 重同步发生在一个帧的其他位场内,当跳变沿落在了同步段之外; l 在SOF到仲裁场有多个节点同时发送的情况下,发送节点对跳变沿不进行重同步。
发生在SOF位,所有接收节点调整各自当前位的同步段,调整宽度不限。 硬同步的原理如图4.12.1。
相位误差为正,跳变沿位于采样点之前,相位缓冲段1增长。 相位误差为正的重同步原理如图4.12.2。 相位误差为负,跳变沿位于前一个位的采样点之后,相位缓冲短缩短。 相位误差为负的重同步原理如图4.12.3。 |
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);