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

📄 selftest.c

📁 CAN总线编程。CAN自发自收例程 外中断1。可以参考
💻 C
字号:
#include "REG52.H"
#include "SJA_BCANCONF.H"
#include "VIIC_C51.h"
#include "ZLG7290.h"
#include "string.h"
#include "intrins.h"

void Init_Cpu(void);
void Init_T0(void);
void Sja_1000_Init(void);
void disp_ok(void);
void disp_err(void);
void delay(unsigned int k);
//void send(unsigned char a);
void display(unsigned char display_buffer[5]);


bit flag_sec;
unsigned char data a[5];
unsigned char data  send_data[10],rcv_data[10];
unsigned char databuf,sec_data,second;
unsigned char data  Tmod_data;
unsigned char bdata flag_init;
sbit	SDA=P1^0;
sbit	CLK=P1^1;
unsigned	char	code	led[20]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf,0x89,0x8C}; 


unsigned	char	data	display_bit;

sbit rcv_flag=flag_init^0;
sbit err_flag=flag_init^2;


void main(void)
{
	Sja_1000_Init();								//initialize Sja1000
	Init_T0();										//initialize T0
	Init_Cpu();										//initialize mcu
	flag_init=0x00;

	while(1)
	{
		if(rcv_flag)								//if there is receive interrupt
		{
			rcv_flag=0;
			BCAN_DATA_RECEIVE(rcv_data);
			BCAN_CMD_PRG(0x04);
			disp_ok();
		}
		if(flag_sec)								//
		{
			flag_sec=0;								//send data if reach 1 s
			//send_data[0]=0xaa;					//Basic can
			send_data[0]=0x08;						//Pelican
			send_data[1]=0xaa;
			send_data[2]=second;
			send_data[3]=second;
			BCAN_DATA_WRITE(send_data);
			BCAN_CMD_PRG(0x12);
		}
		if (err_flag)
		{
			err_flag=0;
			disp_err();
			Sja_1000_Init();
		}
	

		display(a);
		delay(200);
	}	
}


void ex0_int(void) interrupt 2 //using 1
{
	SJA_BCANAdr=REG_INTERRUPT;
	flag_init=*SJA_BCANAdr;
}

void T0_int(void) interrupt 1 //using 2
{
static unsigned char ii=0;
	TR0=0;
		TH0=0x80;
		TL0=0x60;
		ii++;
		if(ii>40)
		{
			flag_sec=1;
			ii=0;
		}
	TR0=1;
}

void Init_Cpu(void)
{
	PX1=1;
	IT1=1;
	EX1=1;
	ET0=1;
	EA=1;
	sec_data=0x10;
}


void Init_T0(void)
{
Tmod_data=TMOD;
Tmod_data&=0xf0;
Tmod_data|=0x01;
TMOD=Tmod_data;
TH0=0x80;
TL0=0x60;
TR0=1;
sec_data=0x20;
second=0x00;
}


void Sja_1000_Init(void)
{
	bit s;
	s=BCAN_CREATE_COMMUNATION();
	s=BCAN_ENTER_RETMODEL();
	s=BCAN_SET_OUTCLK(0xaa,0xc8);				//Pelican
	s=BCAN_SET_BANDRATE(0x04);
	s=BCAN_SET_OBJECT(0xaa,0xff);
	s=BCAN_SET_MOD();
	s=BCAN_QUIT_RETMODEL();
	SJA_BCANAdr=REG_IER;
	*SJA_BCANAdr=0x03;

}



void disp_ok(void)
{
	a[0]=0x01;
	a[1]=0x0D;
	a[2]=0x15;
	a[3]=0X15;
	a[4]=0X10;
}


void disp_err(void)
{
	a[0]=0x18;
	a[1]=0x15;
	a[2]=0x18;
	a[3]=0x18;
	a[4]=0x0E;
}



 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)
 {
    unsigned   char   TempData;
    SJA_BCANAdr  = REG_CONTROL;                   //访问地址指向控制寄存器 
    TempData=  *SJA_BCANAdr;                      //保存原始值
    *SJA_BCANAdr=(TempData|0x01);                 //置位复位请求
    if((*SJA_BCANAdr&0x01) == 1)
    {
       return   0;
    }
    else
    {
       return   1;
    }
    
 }


 bit   BCAN_QUIT_RETMODEL(void)
 {
    unsigned   char   TempData;
    SJA_BCANAdr = REG_CONTROL;                   //访问地址指向控制寄存器 
    TempData    = *SJA_BCANAdr;                  //保存原始值
    *SJA_BCANAdr=(TempData&0xfe);       		 //清除复位请求
    if((*SJA_BCANAdr&0x01) == 0)
    {
       return   0;                               //
    }
    else
    {
       return   1;                              //退出成功
    }

 }


unsigned  char	code	SJA_BTR_CODETAB[]={
    0x53,0x2F,		              //   ;20KBPS的预设值
    0x87,0xFF,                     //;40KBPS的预设值
    0x47,0x2F,                     //;50KBPS的预设值
    0x83,0xFF,                     //;80KBPS的预设值
    0x43,0x2f,                     //;100KBPS的预设值
    0x03,0x1c,                     //;125KBPS的预设值
    0x81,0xfa,                     //;200KBPS的预设值
    0x01,0x1c,                     //;250KBPS的预设值
    0x80,0xfa,                     //;400KBPS的预设值
    0x00,0x1c,                     //;500KBPS的预设值
    0x80,0xb6,                     //;666KBPS的预设值
    0x00,0x16,                     //;800KBPS的预设值
    0x00,0x14                     //;1000KBPS的预设值
   
};

bit   BCAN_SET_BANDRATE(unsigned char CAN_ByteRate)
{
  unsigned  char  BTR0_num,BTR1_num;
  BTR0_num = SJA_BTR_CODETAB[CAN_ByteRate*2];
  BTR1_num = SJA_BTR_CODETAB[CAN_ByteRate*2+1];
  //将波特率的的预设值装入sja1000的总线定时器
  SJA_BCANAdr=REG_BTR0;          		//访问地址指向总线定时寄存器0
  *SJA_BCANAdr=BTR0_num;      			//写入参数
  if(*SJA_BCANAdr != BTR0_num)			//校验写入值
  {
    return  1; 
  }
  SJA_BCANAdr=REG_BTR1;         		//访问地址指向总线定时寄存器0
  *SJA_BCANAdr=BTR1_num;      			//写入参数
  if(*SJA_BCANAdr != BTR1_num)			//校验写入值
  {
    return  1; 
  }

  return    0;
}  



bit    BCAN_SET_OBJECT(unsigned char  BCAN_ACR,unsigned char  BCAN_AMR)
{
  SJA_BCANAdr=REG_TxBuffer5;          		//访问地址指向验收屏蔽寄存器(AMR)
  *SJA_BCANAdr=BCAN_AMR;        		//写入参数
  *(SJA_BCANAdr+1)=BCAN_AMR;
  *(SJA_BCANAdr+2)=BCAN_AMR;
  *(SJA_BCANAdr+3)=BCAN_AMR;
  if(*SJA_BCANAdr != BCAN_AMR)  		//校验写入值
  {
    return  1; 
  }

  SJA_BCANAdr=REG_TxBuffer1;          		//访问地址指向验收代码寄存器(ACR)
  *SJA_BCANAdr=BCAN_ACR;        		//写入参数

  if(*SJA_BCANAdr != BCAN_ACR)  		//校验写入值
  {
    return  1; 
  }

  return    0;
}


bit  BCAN_SET_OUTCLK (unsigned char Out_Control,    
                     unsigned char  Clock_Out)
{
  SJA_BCANAdr=REG_OCR ;          		//访问地址指向输出控制寄存器
  *SJA_BCANAdr=Out_Control;      		//写入参数
  if(*SJA_BCANAdr != Out_Control)		//校验写入值
  {
    return  1; 
  } 
  SJA_BCANAdr=REG_CDR;          		//访问地址指向输出控制寄存器
  *SJA_BCANAdr=Clock_Out;        		//写入参数
   if(*SJA_BCANAdr != Clock_Out)		//校验写入值
  {
    return  1; 
  } 
  return    0;
}



 bit   BCAN_DATA_WRITE(unsigned char *SendDataBuf)
 {
   unsigned  char  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[0]&0x40)==0)        //判断RTR,从而得出是数据帧还是远程帧
   { 
     TempCount =(SendDataBuf[0]&0x0f)+3; //输入数据帧
   }

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

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



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

bit  BCAN_SET_MOD(void)
{
  unsigned   char   TempData;
  SJA_BCANAdr=REG_CONTROL;
  TempData=  *SJA_BCANAdr;
  *SJA_BCANAdr=(TempData|0x04);
  if ((*SJA_BCANAdr&0x04)==0)
  {
  	return 1;
  }
  SJA_BCANAdr=REG_EMLR;
 *SJA_BCANAdr=0xc0;

   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; 
     
 /*    case  GTS_CMD:                    //进入睡眠状态命令 
           return    0;
           break;*/ 
     default:
             return  1;
             break; 
   }
}

void	delay(unsigned int k)
	{	unsigned	int	i,j;
		for(i=0;i<k;i++)
		for(j=0;j<100;j++);
	}
	void	display(unsigned char display_buffer[5])
	{
		ZLG7290_SendBuf(display_buffer,5);
	}

⌨️ 快捷键说明

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