⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sja1000.txt

📁 这是sja1000的读写程序
💻 TXT
字号:
[单片机应用]CAN节点(SJA1000)的通讯程序 
沙漠风雨 发表于 2008-1-26 9:58:20  
以下是我做的CAN节点的测试程序, 实现两个节点传送数据,程序主要分三部分 SJA1000 的初始化,接收数据,发送数据. 

以下程序如要转载,请注明出处

/****************************************************
**函数原型:   bit Sja_1000_Init(void)
**功    能:   初始化SJA10000
**入口参数:    无 
**返 回 值:     
               0: 初始化成功 
      1: 复位失败 
      2:  测试sja1000失败 
      3: 设置失败 
      4: 设置验收滤波器失败
      5: 设置波特率失败     
*****************************************************/

unsigned char Sja_1000_Init(void)
{
 bit s; 
 EA=0;
   s=BCAN_ENTER_RETMODEL();
 if (s==1) return 1; 
    s=BCAN_CREATE_COMMUNATION();
    if (s==1) return 2;

  s=BCAN_SET_OUTCLK(0xc0);//Pelican
 if (s==1) return 3;

 s=BCAN_SET_OBJECT(0xFF,0x4E,0x16,0x00,0xff,0x00,0x00,0x00); 

 if (s==1) return 4;

 s=BCAN_SET_BANDRATE(CAN_BPS_1M);   
    if (s==1) return 5;
    
 SJA_BCANAdr=REG_OCR ;    
    *SJA_BCANAdr=0x1a;        
    SJA_BCANAdr=REG_IER;      

 *SJA_BCANAdr=0x03;
    
     s=BCAN_SET_CONTROL(0x08);
 if (s==1) return 6;

    EA=1;
 return 0;   
} 

}
/************************************************************************
*函数原型: bit BCAN_SET_OUTCLK( unsigned char Clock_Out)            *
*参数说明:                                                             *
*      Clock_Out:存放时钟分频寄存器(CDR)的参数设置                     *
*返回值:                                                               *
*           0 ;设置成功                                                *
*           1 ;设置失败                                                *
*说明:设置SJA1000的时钟分频 。该子程序只能用于复位模式                      
************************************************************************/
bit BCAN_SET_OUTCLK(unsigned char Clock_Out)
{
  SJA_BCANAdr=REG_CDR;           

  *SJA_BCANAdr=Clock_Out;        
  if(*SJA_BCANAdr != Clock_Out)
     return 1; 
   else 
     return 0;
} 

/************************************************************************
*函数原型: bit BCAN_SET_OBJECT(unsigned char  BCAN_ACR0,BCAN_ACR1,BCAN_ACR2,BCAN_ACR3     
                                              BCAN_AMR0, BCAN_AMR1, BCAN_AMR2, BCAN_AMR3     
*参数说明:                                                              *
*    BCAN_ACR(0-3):存放验收代码寄存器(ACR)的参数设置                  *
*    BCAN_AMR(0-3):存放接收屏蔽寄存器(AMR)的参数设置                  *
*返回值:                                                                *
*           0 ;设置成功                                                 *
*           1 ;设置失败                                                 *
*说明:设置CAN节点的通讯对象,允许接收的报文,是由AMR和ACR共同决定的.     *
*************************************************************************/ 
bit BCAN_SET_OBJECT(unsigned char  BCAN_ACR0,BCAN_ACR1,BCAN_ACR2,BCAN_ACR3,BCAN_AMR0,BCAN_AMR1,BCAN_AMR2,BCAN_AMR3)
{
  SJA_BCANAdr=REG_TxBuffer1;     

  *SJA_BCANAdr=BCAN_ACR0;        //写入参数
   
  SJA_BCANAdr=REG_TxBuffer2;
  *SJA_BCANAdr=BCAN_ACR1;

  SJA_BCANAdr=REG_TxBuffer3;  
  *SJA_BCANAdr=BCAN_ACR2;
   
  SJA_BCANAdr=REG_TxBuffer4; 
  *SJA_BCANAdr=BCAN_ACR3;  
 
  //校验写入值
  if(*SJA_BCANAdr != BCAN_ACR3)  return 1; 
  
  SJA_BCANAdr=REG_TxBuffer5;      

  *SJA_BCANAdr=BCAN_AMR0;     //写入参数
  
  SJA_BCANAdr=REG_TxBuffer6;         
  *SJA_BCANAdr=BCAN_AMR1;

  SJA_BCANAdr=REG_TxBuffer7; 
  *SJA_BCANAdr=BCAN_AMR2;

  SJA_BCANAdr=REG_TxBuffer8; 
  *SJA_BCANAdr=BCAN_AMR3;
  //校验写入值
  if(*SJA_BCANAdr != BCAN_AMR3) return 1; 

  return 0;
} 

/********************************************************************
;*函数原型:  bit BCAN_SET_BANDRATE(unsigned char CAN_ByteRate)       *
;*返回值:                                                               *
;*           0 ;波特率设置成功                                          *
;*           1 ;波特率设置失败                                          *
;*                                                                      * 
;*说明:设置CAN控制器SJA1000通讯波特率.SJA1000的晶振必须为16MHZ,         *
;*     其它晶体的频率的值的波特率,需自己计算 。该子程序只能用于        *
;*     复位模式                                                         *  
;************************************************************************/ 
bit BCAN_SET_BANDRATE(unsigned int CAN_ByteRate)
{
  //将波特率的的预设值装入sja1000的总线定时器
  SJA_BCANAdr =REG_BTR0;               
  *SJA_BCANAdr =CAN_ByteRate>>8;       // 取CAN_ByteRate的高8位写入 写入参数
  
  //校验写入值
  if(*SJA_BCANAdr !=(CAN_ByteRate>>8)) return 1; 
 
  SJA_BCANAdr=REG_BTR1;             
  *SJA_BCANAdr=CAN_ByteRate;           
  //校验写入值
  if(*SJA_BCANAdr !=CAN_ByteRate) return 1; 
   return 0;
} 
/************************************************************************
 *函数原型: bit BCAN_SET_CONTROL(unsigend char CMD)                    *
 *参数说明: 设置控制寄存器                                              *
 ************************************************************************/
bit BCAN_SET_CONTROL(unsigned char CMD)
{  unsigned char TempData;
 
  SJA_BCANAdr=REG_CONTROL;   //SJA_BaseAdr+0x00  控制寄存器
  TempData=  *SJA_BCANAdr; 
 
  *SJA_BCANAdr=CMD;
 
  if (*SJA_BCANAdr == CMD)
    return 0;
  else
    return 1;

}
/************************************************************************
 *函数原型:  bit   BCAN_CREATE_COMMUNATION(void)                        * 
 *参数说明:  无                                                         *
 *返回值:                                                               *
 *           0 ; 表示SJA1000接口正常                                    *
 *           1 ; 表示SJA1000与处理器接口不正常                          *
 *说明:该函数用于检测CAN控制器的接口是否正常                            *
 ************************************************************************/
 bit BCAN_CREATE_COMMUNATION(void)
 {  
    SJA_BCANAdr=REG_TEST;      
    *SJA_BCANAdr=0xaa;     //写入测试值
    if(*SJA_BCANAdr == 0xaa)
       return 0;          //读测试正确
    else
       return 1;
     
 }

 /************************************************************************
 *函数原型:      bit   BCAN_ENTER_RETMODEL(void)                         *
 *参数说明:  无                                                         *
 *返回值:                                                               *
 *           0 ; 表示成功进入复位工作模式                               *
 *           1 ; 表示不能进入复位工作模式                               *
 *                                                                      * 
 *说明:      CAN控制器进入复位工作模式                                  *
 ************************************************************************/ 
 bit   BCAN_ENTER_RETMODEL(void)     //置位复位请求
 {
    unsigned   char   TempData;
    SJA_BCANAdr  = REG_CONTROL;   

  TempData=  *SJA_BCANAdr;       
    *SJA_BCANAdr=0x01;                 //置位复位请求
    if((*SJA_BCANAdr&0x01) == 1)
     return   0;
    else
      return   1;   
 } 

/****************************************************
**函数原型:  void ex0_int(void) interrupt 0 //using 1
**功    能:  中断接收函数
**入口参数:   无 
**出口参数:   RevceData[]数组   
**说    明:   当sja1000 收到正确的报文时,会产生int中断           
*****************************************************/
void ex0_int(void) interrupt 0 //using 1
{  unsigned char tt;  
 SJA_BCANAdr=REG_INTERRUPT;
 if((*SJA_BCANAdr)&0x01) //产生了接收中断
 {  
    SJA_BCANAdr=REG_RxBuffer1;
    tt=*SJA_BCANAdr;
     
     if ((tt&0x40)!=0x40) //数据帧   = 为远程帧
        {  memcpy(REG_RxBuffer6,RevceData,8); 

         send_char_com(RevceData[1]);//以下代码是发送到串口
        send_char_com(RevceData[2]);
     send_char_com(RevceData[3]);
     send_char_com(RevceData[4]);
     send_char_com(RevceData[5]);
     send_char_com(RevceData[6]);
     send_char_com(RevceData[7]);
     send_char_com(RevceData[8]);  
     }

     BCAN_CMD_PRG(4);//释放SJA1000接收缓冲区

 }
} 

unsigned char BCAN_DATA_WRITE(unsigned char *SendDataBuf)
 {  unsigned char temp;
   
    SJA_BCANAdr = REG_STATUS;    
 temp=*SJA_BCANAdr;

  if ((temp&0x08)==0) return  1;    //上次发送未完成
    if ((temp&0x04)==0) return  2;    //发送缓冲区是否锁定 
    if ((temp&0x10)==0x10) return 3;  //判断是否正在接收   

    SJA_BCANAdr = REG_TxBuffer1;      //访问地址指向发送缓冲区1

    memcpy(SJA_BCANAdr,SendDataBuf,13);   
     BCAN_CMD_PRG(0x03);   
    return 0;
}


bit  BCAN_CMD_PRG(unsigned char cmd)
 {
   SJA_BCANAdr=REG_COMMAND;            //访问地址指向命令寄存器
   *SJA_BCANAdr=cmd;                   //启动命令字
 
   switch(cmd)
   {    case  TR_CMD:                    

           return    0;
           break;

  case  SRR_CMD:      

      return 0;
     break;
    
  case  AT_CMD:                  

            SJA_BCANAdr = REG_STATUS;   //访问地址指向状态寄存器   
           if((*SJA_BCANAdr & 0x20)==0)//判断是否正在发送
             return  0;
           else
             return  1;              
           break; 
     case  RRB_CMD:                   
           SJA_BCANAdr = REG_STATUS;   //访问地址指向状态寄存器   
           if((*SJA_BCANAdr & 0x01)==1)
              return  1;
           else           
              return  0;               
           break;  
     case  COS_CMD:                  

           SJA_BCANAdr = REG_STATUS;   
           if((*SJA_BCANAdr & 0x02)==0)//判断清除超载是否成功
             return  0; 
           else
             return  1;             
           break; 
     default:
             return  1;
             break; 
   }
}

主程序部分:

void main(void)
{  unsigned char temptt,ss;

   CS=0;
 
   Init_Cpu(); 
   EA=0;
   //initialize Sja1000      
   ss=Sja_1000_Init();
   if (ss!=0)//初始化失败
      send_string_com("init fail!");
   else
     EA=1; //初始化成功,开中断
   
   RECOK=0;
 
  send_data[0]=Send_CAN_Info_ID[0];
  send_data[1]=Send_CAN_Info_ID[1];
  send_data[2]=Send_CAN_Info_ID[2];
  send_data[3]=Send_CAN_Info_ID[3];
  send_data[4]=Send_CAN_Info_ID[4];

   while(1) 
   { 
     SJA_BCANAdr = REG_STATUS;    
        temptt=*SJA_BCANAdr;         
     
  if ((temptt&0x40)==0x40) 

    {  
    Sja_1000_Init();
    send_char_com(0xee);    
  }
    
   if (RECOK==1)
  {   RECOK=0;
   
   SJA_BCANAdr = REG_STATUS;    
         temptt=*SJA_BCANAdr; 
   if((temptt&0x04)==0x04) //可以向发送缓冲器写数据
       {           
          
      send_data[5]=Com_RecBuff[0];
     send_data[6]=Com_RecBuff[1];
   send_data[7]=Com_RecBuff[2];
   send_data[8]=Com_RecBuff[3];
   send_data[9]=Com_RecBuff[4];
   send_data[10]=Com_RecBuff[5];
     send_data[11]=Com_RecBuff[6];
   send_data[12]=Com_RecBuff[7]; 
    
      ss=BCAN_DATA_WRITE(send_data);
   if (ss==0)   //发送正常
      send_char_com(0x11);
    else
    {
       send_char_com(0xFF);
    send_char_com(ss);
       SJA_BCANAdr= REG_ECC;
       send_char_com(*SJA_BCANAdr);    
    }       
       } 
  }
   }      

}

 以上程序只能做为试验使用!!! 如要转载,请注明出处
 
 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -