首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

求助:两块飞思卡尔开发板间的CAN通信

求助:两块飞思卡尔开发板间的CAN通信

这个问题已经困扰我很久了,希望这里有达人能够为我指点迷津!!
硬件环境:两块飞思卡尔S12XDP512、DB9线一根、BDM仿真盒
软件环境:CW 4.7
如下是我的程序,分为node1_rx和node2_tx
发送部分:
unsigned short ID2=0x16d; //这是我要发送报文的ID
const unsigned char Data2[] = "who";
const unsigned char DataLenth2 = 3;
void delay(int num)
{
    int i,j;
    for(i=num;i>0;i--)
    for(j=0;j<200;j++);
}
            
void caninit(void)
{
    CAN0CTL1 |= (1 << 7);    //MSCAN12模块使能
                             //初始化模式请求,并判断初始化应答位,INITACK为1则CAN模块已进入初始化
    CAN0CTL0 |= (1 << 0);    // INITRQ=1,初始化请求
                             //等待应答
    while ((CAN0CTL1 & (1<<0)) == 0)
    {
    }
   
    CAN0CTL1 &= 0xbf;     //MSCAN12时钟源选择外部晶振fmscan=16M
   
    CAN0BTR0 = 0xc7;    //同步跳转宽度为1,预分频因子为8
    CAN0BTR1 = 0xa3;    //将位速率设置成 250 kbps
    CAN0IDAC = 0x00;    //两个32位验收过滤器
   
    CAN0CTL0 &= ~(1<<0);   //INITRQ=0,退出初始化模式
    //等待应答
    while ((CAN0CTL1 | (1<<0)) == 1)
    {
    }
   
    CAN0TIER = 0x07;      //设置中断方式
}
unsigned char GetSNDBUF(void)
{   
   unsigned char bufbit = 0xFF;         //空闲区号
   //查找空闲的发送缓冲区
   if ((CAN0TFLG & (1 << 0)) != 0)
   {  //发送缓冲区0空      
      bufbit = 0;  
   }
   else if ((CAN0TFLG & (1 << 1)) != 0)
   {  //发送缓冲区1空      
      bufbit = 1;
   }
   else if ((CAN0TFLG & (1 << 2)) != 0)
   {  //发送缓冲区2空
      bufbit = 2;
   }  
   return bufbit;//返回空闲区号
}

//CANSND1DFRM:CAN发送1帧数据-----------------------------------------------*
//功  能:CAN发送1帧数据(数据长度<=8)                                       *
//参  数:ID---报文标识符                                                   *
//       DataBUF---报文数据区首址                                          *
//       LEN---报文数据长度                                                *
//返  回:INT8U CANsnd1DFrm --- 发送成功与否标志,                          *
//       =0,没有空闲发送缓冲区,发送不成功;=1,发送成功                  *
//说明:在发送数据之前,先查询是否有空闲发送缓冲区,若无则不能发送,返回0   *
//-------------------------------------------------------------------------*
unsigned char CANSND1DFRM(unsigned short ID,unsigned char * DataBUF, unsigned char LEN)
{
    unsigned char i;
    unsigned char * addr;               //发送缓冲区
    unsigned char BufNum = 0xFF;        //空闲的发送缓冲区号
    BufNum = GetSNDBUF();       //查找空闲的发送缓冲区   
    if (BufNum == 0xFF)         //若返回0xff,则没有空闲的发送缓冲区
        return 0;               //没有空闲的发送缓冲区,发送不成功,返回0
    switch(BufNum)
    {
    case 0:
        CAN0TBSEL |= (1<<0);    //选中发送缓冲区0
        break;
    case 1:
        CAN0TBSEL |= (1<<1);    //选中发送缓冲区1
        break;
    case 2:
        CAN0TBSEL |= (1<<2);    //选中发送缓冲区2
        break;
    default:
        break;
    }
    addr=(unsigned char *)(&CAN0TXIDR0);  //获得发送前台缓冲区首地址
    //---------------------------------------------------------------------
    //将报文按CAN格式进行封装并存入空闲发送缓冲区等待发送
   addr[0]=ID>>3;
   addr[1]=ID<<5;
   addr[2]=0;
   addr[3]=0;
    for(i = 0; i < LEN; i++)
    addr[i+4] = DataBUF;     //数据赋值   
    addr[12] = LEN;             //数据长度
    //---------------------------------------------------------------------
    //发送缓冲区相应TXE位写1清除该位来通知MSCAN12发送数据
    switch(BufNum)
    {
    case 0:
        CAN0TFLG |= (1<<0);       //发送缓冲区0准备就绪
        break;
    case 1:
        CAN0TFLG |= (1<<1);       //发送缓冲区1准备就绪
        break;
    case 2:
        CAN0TFLG |= (1<<2);       //发送缓冲区2准备就绪
        break;
    default:
        break;
    }
    return (1);                 //数据成功写入空闲缓冲区,返回1
}        
              
void main (void)
{
    caninit();
    DDRB=0xff;
    PORTB=0xff;
    EnableInterrupts;
}
#pragma CODE_SEG __NEAR_SEG NON_BANKED
void interrupt 39 can_node1_tx_int()
{
     CAN0TFLG=0xff;
     CANSND1DFRM(ID2,(unsigned char *)(Data2),DataLenth2);   
}                     
在另一块单片机里写入如下接收程序:
byte data0,data1,data2,data3,data4,data5,data6,data7,len;
void delay(int num)
{
    int i,j;
    for(i=num;i>0;i--)
    for(j=0;j<200;j++);
}
void set_rx_id(unsigned short ID)
{
    unsigned char id4,id3,id2,id1;

    id4=ID>>3;
    id3=ID<<5;
   
    CAN0IDAR0=id4;
    CAN0IDAR1=id3;
}
void caninit(void)
{
    CAN0CTL1 |= (1 << 7);    //MSCAN12模块使能
                             //初始化模式请求,并判断初始化应答位,INITACK为1则CAN模块已进入初始化
    CAN0CTL0 |= (1 << 0);    // INITRQ=1,初始化请求
                             //等待应答
    while ((CAN0CTL1 & (1<<0)) == 0)
    {
    }
   
    CAN0CTL1 &= 0xbf;     //MSCAN12时钟源选择外部晶振fmscan=16M
   
    CAN0BTR0 = 0xc7;    //同步跳转宽度为1,预分频因子为8
    CAN0BTR1 = 0xa3;    //将位速率设置成 250 kbps
    CAN0IDAC = 0x00;    //两个32位验收过滤器
   
    set_rx_id(0x16d);
   
    CAN0IDAR4 = 0x00;   
    CAN0IDAR5 = 0x00;
    CAN0IDAR6 = 0x00;
    CAN0IDAR7 = 0x00;
   
    CAN0IDMR0 = 0x00;    //给接收验证屏蔽寄存器0-1赋值
    CAN0IDMR1 = 0x00;
    CAN0IDMR2 = 0x00;
    CAN0IDMR3 = 0x00;
   
    CAN0IDMR4 = 0x00;
    CAN0IDMR5 = 0x00;
    CAN0IDMR6 = 0x00;
    CAN0IDMR7 = 0x00;
   
    CAN0CTL0 &= ~(1<<0);   //INITRQ=0,退出初始化模式
    //等待应答
    while ((CAN0CTL1 | (1<<0)) == 1)
    {
    }
   
    CAN0RIER = 0x01;      //设置中断方式
}
void main(void)
{
    caninit();
    DDRB=0xff;
    PORTB=0xff;
    EnableInterrupts;
    while(1);
}
#pragma CODE_SEG __NEAR_SEG NON_BANKED
void interrupt 38 can_node2_rx_int()
{
     CAN0CTL0_RXFRM=1;
     
     data0=CAN0RXDSR0;
     data1=CAN0RXDSR1;
     data2=CAN0RXDSR2;
     data3=CAN0RXDSR3;
     data4=CAN0RXDSR4;
     data5=CAN0RXDSR5;
     data6=CAN0RXDSR6;
     data7=CAN0RXDSR7;
     len=CAN0RXDLR;
      
     PORTB=~PORTB;
     delay(3000);
     
     CAN0RFLG_RXF=1;
      
}   

当发送部分写入第一块板子里后,通过中断发送一个报文,ID为0x16d,是标准的11位
接收部分同样接收该ID的报文。
但是始终无法接收到,到底错在哪里?
望达人不惜赐教!!
大哥,我问两个问题:
1.nod2中断程序里CAN0RXDSR0是XD系列单片机才有的吗?我用的是MC9S12DP256,貌似没见过这几个寄存器
2.set_rx_id子程序里id3,id4是啥呢?
3.退出初始化模式那while循环语句里逻辑判断好像有误(是否是照搬的S12例程里的呢)?
其他的问题暂时不说了,感觉问题不少啊,呵呵
大哥,我问两个问题:
1.nod2中断程序里CAN0RXDSR0是XD系列单片机才有的吗?我用的是MC9S12DP256,貌似没见过这几个寄存器
2.set_rx_id子程序里id3,id4是啥呢?
3.退出初始化模式那while循环语句里逻辑判断好像有误(是否是照搬的S12例程里的呢)?
其他的问题暂时不说了,感觉问题不少啊,呵呵
大哥,我问两个问题:
1.nod2中断程序里CAN0RXDSR0是XD系列单片机才有的吗?我用的是MC9S12DP256,貌似没见过这几个寄存器
2.set_rx_id子程序里id3,id4是啥呢?
3.退出初始化模式那while循环语句里逻辑判断好像有误(是否是照搬的S12例程里的呢)?
其他的问题暂时不说了,感觉问题不少啊,呵呵
返回列表