两块板子之间的CAN通讯

2019-03-24 13:12发布

      两块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 编辑 ] 此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
2条回答
tiankai001
1楼-- · 2019-03-24 17:56
< CAN通讯不大懂,
移植的时候,时序是一定要考虑的,首先应该考虑两块板子的主频是否一样,如果主频不一样,则有些延时、时序等待等的时间要重新计算
benbending
2楼-- · 2019-03-24 23:24
 精彩回答 2  元偷偷看……

一周热门 更多>

相关问题

    相关文章