打印
[CAN-bus/DeviceNet]

请教wxj1952前辈:Basic模式双节点通信接收不成功

[复制链接]
2400|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
桂电飞天鼠|  楼主 | 2007-4-8 00:58 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    SJA1000的驱动用了网上找的,已经详细看过,符合Basic的通信的要求(看不出有什么问题,跟周工网站提供的函数基本是一样的)初始化设置都设好了,中断全部使能。
    两个CAN模块(SJA1000+89S51,两模块是一样的,只是其中一个接了18B20,板上有两个LED,一个MAX7219驱动的四位数码管,一个蜂鸣器)。
    本实验的目的是:一块将测得的温度发送到另一块板上并显示。

    现在问题是:一块将测得的温度(18B20板上的)每隔10ms发送出去。有一个LED显示发送中断有效,不过闪烁频率时低时高(不断取反的);另一块接收模块,四位数码管显示0(即没收到数据),没有接收中断(已使能),交换两板也一样,即肯定是程序问题。但当复位接收的那个模块时(复位键),发送模块上的错误码中断指示LED亮,不过一会儿就灭了。后用接收模块上的MAX7219四位数据管的其中两位用来显示状态寄存器的值,其中接收状态位(RS)隔一段时间显示正在接收(跟发送模块的发送中断LED的闪烁频率有关),然后又不接收。
    不清楚表达清楚了没?我现在想知道,在basic模块下,接收中断出不来会是什么原因?谢谢了~~
    (手上有一老式20M双踪示波器,可以看到两条传输线都有占空比不同的方波(类似))。

相关帖子

沙发
wxj1952| | 2007-4-8 12:30 | 只看该作者

参考程序

1、别在中断程序里处理任务;
2、把10ms改为100ms,可行后逐渐缩短,发现问题。


while(!RBF){
receive();
.......
RBF=0;
}

void ex0int(void) interrupt 0 using 0
{
LED1=!LED1;
RBF=1;  
}

使用特权

评论回复
板凳
桂电飞天鼠|  楼主 | 2007-4-8 15:32 | 只看该作者

之前已试过不行

程序都是用中断改变标志,由主程序刷新标志的执行方式工作的。

现在是中断进不了,任何中断都没有发生(接收模块)。奇怪了~~不知道是不是验收/屏蔽没设好?

我再调试看看。

使用特权

评论回复
地板
桂电飞天鼠|  楼主 | 2007-4-8 16:04 | 只看该作者

确实是验收屏蔽没处理好!

我把AMR设为0xff,中断就正常了!
不过显示还是不正常,继续检错中。。。。

使用特权

评论回复
5
桂电飞天鼠|  楼主 | 2007-4-9 02:04 | 只看该作者

继续

继续调到现在,现在现象是:

在改变了一些参数(如波特率)之后,接收与发送模块的中断均正常。但接收模块的LED测试表明,远程与数据帧的那个位,接收模块接收到的是1(即远程帧,实际发送的为数据帧),后用接收模块上的数码管显示了接收到的高8位,PTR,低3位标识符,发现与发送模发送过来的差别很远,根本就是乱来了。
   波特率我没有认真算过,直接使用周工网站下载的计算器计算所得的,有网上**说该计算器计算值有误。模块使用24MHz晶振,(使用CLKOUT为MCU提供振荡信号),波特率设为100Kb,其它设置如下:

 //-----------------------定义总线定时寄存器的值--------------------------------------------------------
#define SJA_BTR0 0x57                                  //该值需要用户根据实际需要的波特率进行计算
#define SJA_BTR1 0x11                                  //具体计算见**说明
//-----------------------设置接收报文类型(标示符)--------------------------------------------------------
                                                      //该值需要用户根据实际需要重新配置
#define SJA_ACR 0xaa                                  //验收代码寄存器的值
#define SJA_AMR 0xff                                  //验收屏蔽寄存器的值
//-----------------------设置输出始终类型--------------------------------------------------------
                                                      //该值需要用户根据实际需要重新配置
#define SJA_OCR 0xaa                                  //输出控制寄存器的值
#define SJA_CDR 0x40                                  //始终分频寄存器的值


帧所用到的数据结构:


struct BASICCAN_BUFstruct{
               unsigned char FrameID_H  ;             //帧ID高8位
               unsigned char FrameLENTH ;             //帧数据长度
               unsigned char FrameKIND  ;             //数据帧或远程帧(0:数据;1:远程)
               unsigned char FrameID_L3 ;             //帧ID低3位
               unsigned char Frame_Data[8];             //数据缓冲区
               };




接收与发送部分的程序,觉得原来下载的不对,如下:


//------------------------------------------------------------------------------------------------------
// 函数类别   SJA1000基本操作
// 函数名称   Write_SJAsendBUF
// 入口函数   无
// 出口函数   setting_success
// 操作寄存器 发送缓存器(10-19)状态寄存器02
// 函数功能   写发送缓存器
// 特殊要求   只能在工作模式下写
//------------------------------------------------------------------------------------------------------
bit Write_SJAsendBUF(void)
{
    bit setting_success=0;  
    unsigned char i;
    while(SJA_workmode==0)
   {
      setting_SJA_workingmode();                   //设置SJA在工作模式
   }
    if((CANREG_read(0x02)&0x10)==0)
   {
       if((CANREG_read(0x02)&0x04)!=0)
      {
          CANREG_write(0x10,send_BUF.FrameID_H);
          CANREG_write(0x11,(send_BUF.FrameLENTH<<4)||(send_BUF.FrameKIND<<3)||(send_BUF.FrameID_L3));
          if(send_BUF.FrameKIND==0)
         {
              for(i=0;i<send_BUF.FrameLENTH,i<8;i++)
                CANREG_write(0x12+i,send_BUF.Frame_Data);
         }
         setting_success=1;                        //发送寄存器写成功
      }
  }
  return(setting_success);
}

//------------------------------------------------------------------------------------------------------
// 函数类别   SJA1000基本操作
// 函数名称   Write_SJAsendBUF
// 入口函数   无
// 出口函数   setting_success
// 操作寄存器 接收缓存器(20-29)状态寄存器02
// 函数功能   写发送缓存器
// 特殊要求   只能在工作模式下写
//------------------------------------------------------------------------------------------------------
bit read_SJAreceiveBUF(void)
{
     bit setting_success=0;  
     unsigned char i;
     while(SJA_workmode==0)
    {
        setting_SJA_workingmode();                   //设置SJA在工作模式
    }
     if((CANREG_read(0x02)&0x01)!=0)
    {
        if((CANREG_read(0x02)&0x10)==0)
       {
           receive_BUF.FrameID_H=CANREG_read(0x20);
           receive_BUF.FrameLENTH=((CANREG_read(0x21)&0xF0)>>4);
           receive_BUF.FrameKIND=((CANREG_read(0x21)&0x08)>>3);
           receive_BUF.FrameID_L3=(CANREG_read(0x21)&0x07);
           if(receive_BUF.FrameKIND==0)
          {
               for(i=0;i<receive_BUF.FrameLENTH,i<8;i++)
               receive_BUF.Frame_Data=CANREG_read(0x22+i);
          }
           setting_success=1;                        //接收寄存器读成功
       }
    }
    return(setting_success);
}




我修改的发送与接收函数:


//------------------------------------------------------------------------------------------------------
// 函数类别   SJA1000基本操作
// 函数名称   Write_SJAsendBUF
// 入口函数   无
// 出口函数   setting_success
// 操作寄存器 发送缓存器(10-19)状态寄存器02
// 函数功能   写发送缓存器
// 特殊要求   只能在工作模式下写
//------------------------------------------------------------------------------------------------------
bit Write_SJAsendBUF(void)
{
    bit setting_success=0;  
    unsigned char i;

//    while(SJA_workmode==0)
//   {
//      setting_SJA_workingmode();                   //设置SJA在工作模式
//   }

    if((CANREG_read(0x02)&0x10)==0)
   {
       if((CANREG_read(0x02)&0x04)!=0)
      {
          CANREG_write(0x10,send_BUF.FrameID_H);
          CANREG_write(0x11,(send_BUF.FrameLENTH)||(send_BUF.FrameKIND<<4)||(send_BUF.FrameID_L3<<5));
         
          if(send_BUF.FrameKIND==0)
         {
              for(i=0;i<send_BUF.FrameLENTH,i<8;i++)
                CANREG_write(0x12+i,send_BUF.Frame_Data);
              P1_7 = !P1_7;
         }
                                //发送寄存器写成功
         setting_success=1;
      }
       

  }
   else 
  {
     setting_success=0;
  }
   return(setting_success);
}
//------------------------------------------------------------------------------------------------------
// 函数类别   SJA1000基本操作
// 函数名称   Write_SJAsendBUF
// 入口函数   无
// 出口函数   setting_success
// 操作寄存器 接收缓存器(20-29)状态寄存器02
// 函数功能   写发送缓存器
// 特殊要求   只能在工作模式下写
//------------------------------------------------------------------------------------------------------
bit read_SJAreceiveBUF(void)
{
     bit setting_success=0;  
     unsigned char i;
//     while(SJA_workmode==0)
//    {
//        setting_SJA_workingmode();                   //设置SJA在工作模式
//    }
     if((CANREG_read(0x02)&0x01)!=0)
    {
        if((CANREG_read(0x02)&0x10)==0)
       {
           receive_BUF.FrameID_H=CANREG_read(0x20);
           receive_BUF.FrameLENTH=((CANREG_read(0x21)&0x0f));
           receive_BUF.FrameKIND=((CANREG_read(0x21)&0x10)>>4);
           receive_BUF.FrameID_L3=((CANREG_read(0x21)&0xe0)>>5);
           if(receive_BUF.FrameKIND==0)
          {
               for(i=0;i<receive_BUF.FrameLENTH,i<8;i++)
               receive_BUF.Frame_Data=CANREG_read(0x22+i);
          }
           setting_success=1;                        //接收寄存器读成功
       }
    }
     else 
    {
        setting_success=0;
    }
    return(setting_success);
}

使用特权

评论回复
6
wxj1952| | 2007-4-9 08:12 | 只看该作者

确实是乱了套

//-----------------------定义总线定时寄存器的值--------------------------------------------------------
#define SJA_BTR0 0x57                                  //该值需要用户根据实际需要的波特率进行计算
#define SJA_BTR1 0x11                                  //具体计算见**说明
//-----------------------设置接收报文类型(标示符)--------------------------------------------------------
                                                      //该值需要用户根据实际需要重新配置
#define SJA_ACR 0xaa                                  //验收代码寄存器的值
#define SJA_AMR 0xff                                  //验收屏蔽寄存器的值
//-----------------------设置输出始终类型--------------------------------------------------------
                                                      //该值需要用户根据实际需要重新配置
#define SJA_OCR 0xaa                                  //输出控制寄存器的值
#define SJA_CDR 0x40                                  //始终分频寄存器的值

问题:
1、这些寄存器只能在程序运行中(且只能复位模式下)写吧。能预定义?

2、 for(i=0;i<send_BUF.FrameLENTH,i<8;i++)   能行?反正我认为不可行。


可以在论坛上查找两篇**:

1、CAN波特率的简单计算 

2、SJA1000标准发送/接收实验C程序 

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

13

主题

273

帖子

0

粉丝