两块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 编辑 ]
此帖出自
小平头技术问答
移植的时候,时序是一定要考虑的,首先应该考虑两块板子的主频是否一样,如果主频不一样,则有些延时、时序等待等的时间要重新计算
一周热门 更多>