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

📄 basiccan.c

📁 基于51单片机的CAN总线节点程序
💻 C
📖 第 1 页 / 共 3 页
字号:
}  


/************************************************************************
;*函数原型:    BCAN_SET_OBJECT                                          *
*参数说明:                                                              *
 *    BCAN_ACR:存放验收代码寄存器(ACR)的参数设置                      *
 *    BCAN_AMR:存放接收屏蔽寄存器(AMR)的参数设置                      *
;*返回值:                                                               *
;*           0 ;通信对象设置成功                                        *
;*           1 ;通信对象设置失败                                        *
;*                                                                      * 
;*说明:设置CAN节点的通讯对象,允许接收的报文ID号的高8位(D10--D3) 。     *
;*     允许接收的报文,是由AMR和ACR共同决定的.                           *  
;*    满足以下条件的ID号的报文才可以被接收                              *
;*[(ID.10-ID.3)≡(AC.7-AC.0)]||(AM.7-AM.0)≡11111111              *
;*    该子程序只能用于复位模式                                          *                                                                                                                     *             
;************************************************************************/
bit    BCAN_SET_OBJECT(uchar  BCAN_ACR,uchar  BCAN_AMR)
{
   SJA_BCANAdr=REG_ACR;          		//访问地址指向验收代码寄存器(ACR)
  *SJA_BCANAdr=BCAN_ACR;        		//写入参数
  if(*SJA_BCANAdr != BCAN_ACR)  		//校验写入值
  {
    return  1; 
  }
  SJA_BCANAdr=REG_AMR;          		//访问地址指向验收屏蔽寄存器(AMR)
  *SJA_BCANAdr=BCAN_AMR;        		//写入参数
  if(*SJA_BCANAdr != BCAN_AMR)  		//校验写入值
  {
    return  1; 
  }

  return    0;
}



/************************************************************************
;*函数原型: bit  BCAN_SET_OUTCLK (uchar Out_Control, 	        *
                                  uchar  Clock_Out);            *
;*参数说明:										      					*
 *    Out_Control:存放输出控制寄存器 (OC)  的参数设置                   *
 *    Clock_Out:存放时钟分频寄存器 (CDR) 的参数设置                     *
 *                                                                      *   
;*返回值:                                                               *
;*           0 ;设置成功                                                *
;*           1 ;设置失败                                                *
;*                                                                      * 
;*说明:设置SJA1000的输出模式和时钟分频 。该子程序只能用于复位模式       *                                                                                                                     *             
;************************************************************************/
bit  BCAN_SET_OUTCLK (uchar Out_Control,    
                     uchar  Clock_Out)
{
  SJA_BCANAdr=REG_OCR ;          		//访问地址指向输出控制寄存器
  *SJA_BCANAdr=Out_Control;      		//写入参数
  if(*SJA_BCANAdr != Out_Control)		//校验写入值
  {
    return  1; 
  } 
  SJA_BCANAdr=REG_CDR;          		//访问地址指向时钟分频寄存器,主要用于设置CAN模式
  *SJA_BCANAdr=Clock_Out;        		//写入参数
  return    0;
}

                       
/************************************************************************
 *函数原型:  bit   BCAN_DATA_WRITE(uchar *SendDataBuf)*
 *参数说明:  特定帧各式的数据?                                         *
 *返回值:                                                               *
 *           0    ; 表示将数据成功的送至发送缓冲区                      *
 *           1	  ; 表示上一次的数据正在发送,                          *
 *                ; 表示发送缓冲区被锁定,不能写入数据                  *
 *                ; 表示写入数据错误                                    * 
 *说明: 将待发送特定帧各式的数据,送入SJA1000发送缓存区中,然后启动     *
 *        SJA1000发送。                                                 *
 *   特定帧格式为:开始的两个字节存放 '描述符' ,以后的为数据             *
 *   描述符包括11位长的ID(标志符)\1位RTR\4位描述数据长度的DLC共16位    *
 *                                                                      *
 *注:本函数的返回值仅指示,将数据正确写入SJA1000发送缓存区中与否。     *
 *    不指示SJA1000将该数据正确发送到CAN总线上完毕与否                  *
 ************************************************************************/ 

 bit   BCAN_DATA_WRITE(uchar *SendDataBuf) reentrant   //只是将数据写入SJA1000的发送缓存区
 {
   uchar  TempCount;
   SJA_BCANAdr = REG_STATUS;            //访问地址指向状态寄存器
   if((*SJA_BCANAdr&0x08) == 0)         //判断上次发送是否完成
   {
    return	1;
   }  

   if((*SJA_BCANAdr&0x04)==0)          //判断发送缓冲区是否锁定
   {
     return	1;
   }  
 
   SJA_BCANAdr = REG_TxBuffer1;        //访问地址指向发送缓冲区1
   if((SendDataBuf[1]&0x10)==0)        //判断RTR,从而得出是数据帧还是远程帧
   { 
     TempCount =(SendDataBuf[1]&0x0f)+2; //输入数据帧
   }

   else
   {
     TempCount =2;                     //远程帧
   }

  memcpy(SJA_BCANAdr,SendDataBuf,TempCount);
   return 0;
}



/************************************************************************
 *函数原型:  bit BCAN_DATA_RECEIVE(uchar *RcvDataBuf);       *
 *参数说明:  RcvDataBuf,存放微处理器保存数据缓冲区                      *
 *返回值:    0;接收成功                                                 *
 *           1;接收失败                                                 * 
 *说明:CAN控制器接收数据,仅限于接收数据                                 *
 ************************************************************************/

 bit BCAN_DATA_RECEIVE(uchar *RcvDataBuf)    //把数据接收之后出入RcvDataBuf
 {
   uchar  TempCount; 
   SJA_BCANAdr = REG_STATUS;                //访问地址指向状态寄存器
   if((*SJA_BCANAdr&0x01)==0)               //判断报文是否有效
   {
      return 1;
   }
   
   SJA_BCANAdr = REG_RxBuffer2;             //访问地址指向接收缓冲区2
   if((*SJA_BCANAdr&0x10)==0)               //如果是数据帧
   {
     TempCount=(*SJA_BCANAdr&0x0f)+2;       //计算报文中数据的个数
   }
   
   else
   {
    TempCount=2;
   }
   SJA_BCANAdr = REG_RxBuffer1;             //访问地址指向接收缓冲区1
   memcpy(RcvDataBuf,SJA_BCANAdr,TempCount);//读取接收缓冲区的报文
   return  0;
 }



/************************************************************************
 *函数原型:  bit  BCAN_CMD_PRG(uchar cmd)             *
 *参数说明:  cmd:sja1000运行的命令字                                    *
 *             01:发送请求                                              *
 *             02:中止发送                                             *
 *             04:释放接收缓冲区                                       *
 *             08:清除超载状态                                         *
 *             0x10:进入睡眠状态                                        *
 *                                                                      *
 *返回值:                                                               *
 *           0 ; 表示命令执行成功                                       *
 *           1 ; 表示命令执行失败                                       *
 *                                                                      * 
 *说明:      执行sja1000命令                                            * 
 ************************************************************************/ 

 bit  BCAN_CMD_PRG(uchar cmd)
 {
   SJA_BCANAdr=REG_COMMAND;            //访问地址指向命令寄存器
   *SJA_BCANAdr=cmd;                   //启动命令字
   switch(cmd)
   {
     case  TR_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; 
     
     case  GTS_CMD:                    //进入睡眠状态命令 
           return    0;
           break; 
     default:
             return  1;
             break; 
   }

 }


//初始化SJA_1000,设置相关参数
 uchar  SJA_1000_Init(void)
{ 
	uchar data status=0;
	delay_ms(10);

	BandRateBuf = ByteRate_1000k;//默认波特率为1000k

	BCAN_ENTER_RETMODEL();//使CAN控制器进入复位工作模式

	if(BCAN_CREATE_COMMUNATION())//检测CAN控制器的接口是否正常,若返回1,则不正常
    {
		status = CAN_INTERFACE_ERR;
		return(status);
	}

	if(BCAN_SET_BANDRATE(BandRateBuf))//初始化系统默认值波特率1000kbps,若返回1,表示波特率未能设置
	{
		status=CAN_INITBTR_ERR;
		return(status);
	}

	if(BCAN_SET_OBJECT(0xaa,0xff))//设置检收代码寄存器(ACR)、接收屏蔽寄存器(AMR)的参数
                                //0xff表示检收代码寄存器所有的位对检收滤波器是“无关的”
	{
    	status =CAN_INITOBJECT_ERR;
    	return(status);
  	}

//输出控制寄存器OCR=0xaa表示采用正常输出模式,TX1悬空,时钟分频寄存器CDR=0x48表示采用BasicCAN模式,CBP被置位,
//只有RX0起作用。CLOCK OFF置1使外部CLKOUT引脚失效 
	if(BCAN_SET_OUTCLK(0xaa,0x48))//设置SJA1000的输出模式和时钟分频
	{
    	status =CAN_INITOUTCTL_ERR;
    	return(status);
	}

	if(BCAN_QUIT_RETMODEL())//使CAN控制器退出复位工作模式
	{
    	status = CAN_QUITRESET_ERR;
    	return(status);
	}
  
	SJA_BCANAdr=REG_CONTROL;//设置控制寄存器,在操作模式进行
	*SJA_BCANAdr=0X1E;//开启溢出中断、错误中断、发生和接收中断
  
	return  status; 
}

 
//将数据显示到LED上
void display_s(void)
{
	uchar num=6;
	while(num)
	{
		P0=code_led[SetSystemBuf[3]] | 0x80;
		P14=0;//选通第一个LED
		P15=0;
		P17=1;
    	P17=0;
		delay_ms(1);

		P0=code_led[SetSystemBuf[2]];
		P14=1;//选通第二个LED
		P15=0;
		P17=1;
    	P17=0;
		delay_ms(1);

		P0=code_led[SetSystemBuf[1]];
		P14=0;//选通第三个LED
		P15=1;
		P17=1;
    	P17=0;
		delay_ms(1);

⌨️ 快捷键说明

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