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

📄 新建 文本文档.txt

📁 自己编的SJA1000的CAN通信程序
💻 TXT
字号:
#include "type.h"
#include "sja.h"
#include "reg52.h"

BYTE RXBuffer[11];   //8051接收缓冲区
BYTE TXBuffer[11];   //8051发送缓冲区
/*注:现在暂时没有使用划出的8051发送缓冲区,以后如果有必要,可以使用*/

sbit LIGHT=P3^4;    //点灯
sbit CONTROL=P3^3;  //发送控制按键

char xdata *SJA_BCANAdr;  //定义一个全局指针变量,用于对sja内存的存取操作
BYTE xdata aa;

void main(void)
{
     BYTE ss;      //存储sja初始化结果
     BYTE kk;
     EA=0;
     LIGHT=0;
     Delay(1000);
     LIGHT=1;
	 retry:
     ss=sja_1000_Init();
	 if(ss!=0)    
	    goto retry;   //初始化失败,跳出,重新初始化

     /*主函数体*/
     main00: 
	 kk=receive();      //8051接收数据
	 if(kk!=0)    
	    goto retry;	 
	 Delay(10);
	 if(CONTROL==1)  //没按键则循环等待
	     goto main00;
	 else{           //按下键
	     do{
	     }while(CONTROL==0);
	     ctransmit();   //发送
		 goto main00;   //循环
		}
}

/****************************************************
**函数原型:   bit Sja_1000_Init(void)
**功    能:   初始化SJA10000
**入口参数:    无 
**返 回 值:     
      0: 初始化成功 
      1: 初始化失败
*****************************************************/
BYTE sja_1000_Init(void)
{
    bit s;

    SJA_BCANAdr = REG_MOD;           //置位复位请求
    *SJA_BCANAdr= 0x01;                 

    if((*SJA_BCANAdr)&0x01==0x01)
	   {
	      s=BCAN_SET_OUTCLK(0xc8);   //PeliCan
	         if(s==1) return 1;
	      s=BCAN_SET_OBJECT(0xaa,0xa0,0xaa,0a1,0x00,0x00,0x00,0x00);//验收码&屏蔽码
             if(s==1) return 1;
	      s=BCAN_SET_BANDRATE();     //波特率设置
	         if(s==1) return 1;
          SJA_BCANAdr=REG_OCR;       //输出控制    
          *SJA_BCANAdr=0x1a;
          s=BCAN_SET_INTERRUPT();    //中断禁能
             if(s==1) return 1;
	   	}
	 else
	    return 1;
     SJA_BCANAdr=REG_MOD;            //退出“复位模式”
     *SJA_BCANAdr=*SJA_BCANAdr&0xfe;
     if(*SJA_BCANAdr!=0x00)
	    return 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(0xaa,0xa0,0xa0,0xa1,0x00,0x00,0x00,0x00)  
*参数说明:                                                              *
*    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_BCAN_ACR0;     
  *SJA_BCANAdr=BCAN_ACR0;   
      
  SJA_BCANAdr=REG_BCAN_ACR1;
  *SJA_BCANAdr=BCAN_ACR1;
  
  SJA_BCANAdr=REG_BCAN_ACR2;  
  *SJA_BCANAdr=BCAN_ACR2;

  SJA_BCANAdr=REG_BCAN_ACR3; 
  *SJA_BCANAdr=BCAN_ACR3;  
      
  //写入接收屏蔽
  SJA_BCANAdr=REG_BCAN_AMR0;      
  *SJA_BCANAdr=BCAN_AMR0;     

  SJA_BCANAdr=REG_BCAN_AMR1;         
  *SJA_BCANAdr=BCAN_AMR1;

  SJA_BCANAdr=REG_BCAN_AMR2; 
  *SJA_BCANAdr=BCAN_AMR2;

  SJA_BCANAdr=REG_BCAN_AMR3; 
  *SJA_BCANAdr=BCAN_AMR3;

  return 0;
} 

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

  SJA_BCANAdr=REG_BTR1;             
  *SJA_BCANAdr=0xA5;
  ACC=*SJA_BCANAdr;
  //校验写入值
  if(ACC!=0xA5) return 1;
  
  return 0;
}

/************************************************************************
 *函数原型: bit BCAN_SET_INTERRUPT(void)                               *
 *参数说明: 设置SJA中断寄存器                                          *
 ************************************************************************/
bit BCAN_SET_INTERRUPT(void)
{
	 SJA_BCANAdr=REG_IER;     //将REG_IER的地址赋给指针
     *SJA_BCANAdr=0x00;       //禁能中断
     
	 if(*SJA_BCANAdr==0x00)
	    return 0;
	 else
	    return 1;
	}
	

/************************************************************************
 *函数原型: void Delay(unsigned char DelayTime)                        *
 *参数说明: 设定延时时间(ms)                                         *
 ************************************************************************/
void Delay(unsigned int DelayTime)
{ unsigned int j=0;
  for(;DelayTime>0;DelayTime--)
  { 
     for(j=0;j<125;j++)        //1ms
     {;}
  }
}

/************************************************************************
 *函数原型: void ctransmit(void)                             *
 *参数说明: 发送数据,查询法                                 *
 ************************************************************************/
void ctransmit(void)
{
     SJA_BCANAdr=REG_SR; //将状态寄存器的地址赋给指针
     do{                 //等待,直到发送缓冲器被释放
       }while((*SJA_BCANAdr&0x04)!=0x04);
     //释放发送缓冲器后,信息可写入缓冲器,发送一帧信息
     SJA_BCANAdr=Buffer0;//SFF,DLC=8
     *SJA_BCANAdr=0x08;
     
     SJA_BCANAdr=Buffer1;//ID1
     *SJA_BCANAdr=0xaa;
     SJA_BCANAdr=Buffer2;//ID2
     *SJA_BCANAdr=0xaa;

     SJA_BCANAdr=Buffer3;//Data1
     *SJA_BCANAdr=0x01;
     SJA_BCANAdr=Buffer4;
     *SJA_BCANAdr=0x02;
     SJA_BCANAdr=Buffer5;
     *SJA_BCANAdr=0x03;
     SJA_BCANAdr=Buffer6;
     *SJA_BCANAdr=0x04;
     SJA_BCANAdr=Buffer7;
     *SJA_BCANAdr=0x05;
     SJA_BCANAdr=Buffer8;
     *SJA_BCANAdr=0x06;
     SJA_BCANAdr=Buffer9;
     *SJA_BCANAdr=0x07;
     SJA_BCANAdr=Buffer10;
     *SJA_BCANAdr=0x08;

     SJA_BCANAdr=REG_CMR;//启动发送
     *SJA_BCANAdr=0x01;
     SJA_BCANAdr=REG_SR;//判断发送是否完毕   
     do{
     }while((*SJA_BCANAdr&0x08)!=0x08);
}

/************************************************************************
 *函数原型: BYTE receive(void)                               *
 *参数说明: 接收数据,查询法                                 *
 ************************************************************************/
//接收,查询法
BYTE receive(void)
{
     SJA_BCANAdr=REG_SR;
     ACC=*SJA_BCANAdr;
     if((*SJA_BCANAdr&0x01)==0x01)
        {
         ACC=*SJA_BCANAdr; 	 
         SJA_BCANAdr=Buffer3;       //接收数据,存入8051接收数组内
         RXBuffer[0]=*SJA_BCANAdr;
          if(*SJA_BCANAdr!=0x01) return 1;
         SJA_BCANAdr=Buffer4;
	     RXBuffer[1]=*SJA_BCANAdr;
          if(*SJA_BCANAdr!=0x02) return 1;
         SJA_BCANAdr=Buffer5;
	     RXBuffer[2]=*SJA_BCANAdr;
          if(*SJA_BCANAdr!=0x03) return 1;
         SJA_BCANAdr=Buffer6;
	     RXBuffer[3]=*SJA_BCANAdr;
          if(*SJA_BCANAdr!=0x04) return 1;
         SJA_BCANAdr=Buffer7;
	     RXBuffer[4]=*SJA_BCANAdr;
          if(*SJA_BCANAdr!=0x05) return 1;
         SJA_BCANAdr=Buffer8;
	     RXBuffer[5]=*SJA_BCANAdr;
          if(*SJA_BCANAdr!=0x06) return 1;
         SJA_BCANAdr=Buffer9;
	     RXBuffer[6]=*SJA_BCANAdr;
          if(*SJA_BCANAdr!=0x07) return 1;
         SJA_BCANAdr=Buffer10;
	     RXBuffer[7]=*SJA_BCANAdr;
          if(*SJA_BCANAdr!=0x08) return 1;

         light();     //点灯

//         ACC=RXBuffer[0];
         
         SJA_BCANAdr=REG_CMR;
	     *SJA_BCANAdr=(*SJA_BCANAdr|0x04);//置位"释放接收缓冲器"
        }
      return 0;
}

/************************************************************************
 *函数原型: void light(void)                                          *
 *函数说明:点灯。51的第14脚(T0/P3.4)置低电平,灯亮                    *
 ************************************************************************/
void light(void)
{
    LIGHT=0;
    Delay(1000);
    LIGHT=1;
    Delay(1000);
    LIGHT=0;
    Delay(1000);
    LIGHT=1;
    Delay(1000);
    LIGHT=0;
    Delay(1000);
    LIGHT=1;
}



⌨️ 快捷键说明

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