两块5K31的板子,进行CAN通讯,请问时序上应该如何设置?如果一个只负责发送数据,另一个只负责接收数据,又怎么解决? (新板子的移植程序,两块板子分别跟老板子都能够进行CAN通讯,且协议一致了,再将两块一直程序后的新板子直接上电通讯,没有反应)。 个人觉得应该是时序的问题,觉得作为发送一方,发送失败可以延迟一段时间,在复位重新发送;对于接收一方,也要不断判断是否有数据过来,进而接收。
总之,主要在中断处有问题。求解。
主函数如下:
uint8 systick_flag; // 主函数(程序入口) int main(void) { uint8 systick_bak; jtagWait(); // 防止JTAG失效,重要! clockInit(); // 时钟初始化:晶振,6MHz board_initialize(); // 初始化 SysTickPeriodSet(100000UL); // 设置SysTick计数器的周期值 2ms SysTickIntEnable(); // 使能SysTick中断 IntMasterEnable(); // 使能处理器中断 SysTickEnable(); // 使能SysTick计数器 serialInit(); CANConfigure(); for (;;) { if(systick_bak != systick_flag) // 2ms 定时到 { systick_bak = systick_flag; CANSend(); if(can_error_flag) { can_error_flag = 0; SysCtlDelay(15 * TheSysClock / 3000); CANConfigure(); } } } } // void SysTick_ISR(void) { // 硬件会自动清除SysTick中断状态 systick_flag += 1; }
#define _CAN_DEAL_C_ #include "config.h" #include "can_deal.h" #include "serial_com.h" tCANMsgObject g_MsgObjectRx; // CAN接收报文对象设置 tCANMsgObject g_MsgObjectTx; // CAN发送报文对象设置 tCANBitClkParms CANBitClkSettings[] = { /*50MHz*/ {5, 4, 3, 5}, /* CANBAUD_1M */ {5, 4, 3, 10}, /* CANBAUD_500K */ {5, 4, 3, 20}, /* CANBAUD_250K */ {5, 4, 3, 40}, /* CANBAUD_125K */ {5, 4, 3, 50}, /* CANBAUD_100k */ {11, 8, 4, 50}, /* CANBAUD_50k */ {11, 8, 4, 100}, /* CANBAUD_25k */ {11, 8, 4, 125}, /* CANBAUD_20k */ {11, 8, 4, 250}, /* CANBAUD_10k */ {11, 8, 4, 500}, /* CANBAUD_5k */ {11, 8, 4, 1000}, /* CANBAUD_2k5 */ }; uint8 can_recebuf[8]; uint8 can_sendbuf[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x51,0x0e}; uint8 cop_frame_addr; uint16 SendID,ReceID; /************************************************* 函数名称: CANConfigure 简要描述: 配置CAN0的外设 调用清单: 被调用清单: 输入: 输出: 返回: 其它: 修改日志: *************************************************/ void CANConfigure(void) { SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); // 使能GPIOD系统外设 SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN0); // 使能CAN控制器系统外设 GPIOPinConfigure(GPIO_PA6_CAN0RX); GPIOPinConfigure(GPIO_PB5_CAN0TX); GPIOPinTypeCAN(GPIO_PORTA_BASE, GPIO_PIN_6 ); GPIOPinTypeCAN(GPIO_PORTB_BASE, GPIO_PIN_5 ); CANInit(CAN0_BASE); // 初始化CAN节点 CANBitTimingSet(CAN0_BASE, (tCANBitClkParms *)&CANBitClkSettings[CANBAUD_50k]); // 对 CAN控制器位时序进行配置 CANEnable(CAN0_BASE); // 使能CAN控制器 CANIntEnable(CAN0_BASE, CAN_INT_MASTER | CAN_INT_STATUS | CAN_INT_ERROR); // 使能CAN控制器中断源 IntEnable(INT_CAN0); // 使能CAN控制器中断(to CPU) IntMasterEnable(); // 使能中断总开关 cop_frame_addr = 0; } /************************************************* 函数名称: CANRece 简要描述: 配置接收数据帧 调用清单: 被调用清单: 输入: 输出: 无 返回: 其它: 修改日志: *************************************************/ void CANRece(void) { g_MsgObjectRx.ulMsgID = 0x110; // 报文滤波ID g_MsgObjectRx.ulMsgIDMask = 0x00; // 报文ID掩码 g_MsgObjectRx.ulFlags = MSG_OBJ_RX_INT_ENABLE | MSG_OBJ_EXTENDED_ID | MSG_OBJ_USE_ID_FILTER |MSG_OBJ_DATA_LOST ; // 由tCANObjFlags列举的配置参数:使能或已使能接收中断 g_MsgObjectRx.pucMsgData = sizeof(can_recebuf); // 指向数据存储空间 g_MsgObjectRx.ulMsgLen = 8; // 设置数据域长度 CANMessageSet(CAN0_BASE, 3, &g_MsgObjectRx, MSG_OBJ_TYPE_RX); // 配置数据帧"接收报文对象" } /************************************************* 函数名称: CANSend 简要描述: 配置发送数据 调用清单: 被调用清单: 输入: 输出: 无 返回: 其它: 修改日志: *************************************************/ void CANSend(void) { g_MsgObjectTx.ulMsgID = SendID; //取得报文标识符 g_MsgObjectTx.ulMsgIDMask = 0x00; g_MsgObjectTx.ulFlags = MSG_OBJ_TX_INT_ENABLE; // 标记发送中断使能 g_MsgObjectTx.ulMsgLen = sizeof(can_sendbuf); // 标记数据域长度 CAN_ReceDeal(); if(cop_frame_addr == 0) { cop_frame_addr = 1; can_sendbuf[6] = 0x52; //参考原始 can_sendbuf[7] = crc_8(can_sendbuf,7); g_MsgObjectTx.pucMsgData = can_sendbuf; // 传递数据存放指针 CANRetrySet(CAN0_BASE, 1); // 启动发送失败重发 CANMessageSet(CAN0_BASE, 1, &g_MsgObjectTx, MSG_OBJ_TYPE_TX); // 配置1号报文对象为发送对象 } else { cop_frame_addr = 0; can_sendbuf[6] = 0x51; //参考原始 can_sendbuf[7] = crc_8(can_sendbuf,7); g_MsgObjectTx.pucMsgData = can_sendbuf; // 传递数据存放指针 CANRetrySet(CAN0_BASE, 1); // 启动发送失败重发 CANMessageSet(CAN0_BASE, 2, &g_MsgObjectTx, MSG_OBJ_TYPE_TX); // 配置2号报文对象为发送对象 } }
/************************************************* 函数名称: CANIntHandler 简要描述: CAN中断处理 调用清单: 被调用清单: 输入: 输出: 无 返回: 其它: 修改日志: *************************************************/ void CANIntHandler(void) { unsigned long ulStatus; ulStatus = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE); //读取CANMSGnINT寄存器的值 if(ulStatus == CAN_INT_INTID_STATUS) // Status Interrupt 状态中断 { CANStatusGet(CAN0_BASE, CAN_STS_CONTROL); } else if(ulStatus == 1||ulStatus == 2) { CANIntClear(CAN0_BASE, ulStatus); CANRece(); } else if(ulStatus == 3) { g_MsgObjectRx.pucMsgData = can_recebuf; CANMessageGet(CAN0_BASE, 3, &g_MsgObjectRx, 0); CANIntClear(CAN0_BASE, 3); CANSend(); } else { can_error_flag = 1; CANIntClear(CAN0_BASE, ulStatus); } } 有想法或者意见的,请多多指教!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
A号机发送数据,B号机是接收数据。具体流程应该如何:
A发送,进入中断判断是否发送成功,如果没有延迟时间重新复位发送?
B判断是否有数据发送,有则接收,无则等待?
两块板子之间的CAN通讯时序应该如何设置呢?
A号机发送数据,B号机是接收数据。具体流程应该如何:
A发送,进入中断判断是否发送成功,如果没有延迟时间重新复位发送?
B判断是否有数据发送,有则接收,无则等待?
[ 本帖最后由 benbending 于 2012-11-19 15:42 编辑 ]
|