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

📄 can-second.c

📁 很完整的CAN总线项目应用例子
💻 C
字号:
#include <REGX52.H>
#include <intrins.h>    
#include <absacc.H>
#include <LCD24064.h>
#include <SJA1000.h>
#include <KEY8255.h>
#include <ADC0809.h>
#include <6264.h>
#define  uint      unsigned int
#define  uchar     unsigned char
#define  ulong     unsigned long 

bit     manu1=0,manu2=0;                   // 显示汉字循环右移界面 标志位
bit     flag_data=0;                       //接收新数据标志
uchar   buf[10],ID2[4];   ////接收数据缓冲区和ID符区
uchar   add=10;

/***********************************************************
                        主函数
************************************************************/
void main(void)                                                
{    
     uchar key,temp[8]={0x00,0x00,99,99,99,99,99,99};  ////temp[0]为实验序号变量
	 uchar code ID_send[4]={0,0,0,0};
	 uchar num=22;
	 bit double2=0,ok=0;
     init_8255();
     LcmInit();
	 LcmClear(0);
	////init_sja(); 		//SJA1000初始化////////////////////////////////////////////////////////////
     EX0=1;                       //外部中断0允许控制位
     IT0=1;                       //外部中断0触发方式选择位:IT0=0为低电平触发,IT0=1为下降沿触发
     EA=1;                        //开总中断
	 P1_0=0;					  //关蜂鸣器

     manu_init(0x11); 				  //显示初始化界面/////showword(xia_x,0x12,0);画线
	 Delay(1000);

 while(1)
  {
 	   key=key_scan();
  	   if(key==11)  { manu1=0; ok=0; manu2=0;double2=0; num=22; }  //修改处理
   if(manu1==0)      		//选择实验序号
    {	LcmClear(0);
		manu_init(0x10);
    	manu_select();
		while(manu1==0)
  		 { key=key_scan();
  		   if(key!=0xff&&key>=0&&key<10) 	
			{  temp[(num-22)]=key;  PutData(num++,5,key); }
			if(num>=24) { manu1=1;  temp[0]=temp[0]*10+temp[1]; }		//PutData2(5,5,e_num);
     	}
     }////if(manu1==0) 
   if(manu1==1)
	{
	 while(ok==0)
	 {
	   key=key_scan();
  	   if(key==10&&double2==0) 
		{  PutChar(26,5,0x2f);
		   PutChar(27,5,0x2b);
		   PutChar(28,5,0x1f);
		   double2=1;
		}
	   else if(key==10&&double2==1) 
		{  temp[1]=99;
		  /// send_dframe(ID_send,temp);	///////////////////////////////////////需加入
		   PutChar(28,5,0x01);
		   ok=1;
		   manu2=1;       ///选择完 标志
		   Delay(1000);
		}
	  }
  	  ////PutData2(5,5,temp[0]);///检验实验设置OK否,此时manu1==1,ok==1,manu2==1
	}/////if(manu1==1)
	if(manu2==1)//空闲时显示初始化界面
	{
	 LcmClear(0);
	 manu_init(0x11); 
	 manu2=0;
	}////////if(manu2==1)
/////////////////////////////////////接收数据处理/////////////////////////////////////////////////

	if(flag_data==1)
	{
	 LcmClear(0);
     manu_data();
	 flag_data=0;
    // manu2=1;//////空闲时显示初始化界面
	}//if(flag_data==1)


  }//while(1)
}//main() 




void manu_xinxi(void)
{
     uchar xx,yy;
	  LcmClear(0);
	  PutData2(8,1,ID2[0]);
	  PutChar(11,1,0x03);
	  showword(shi, 0x60,0); 
 	  showword(yan,0x70,0); 
      showword(tai_2,0x80,0); //显示实验台序号

	  showword(shi, 0x01,0);
	  showword(yan,0x11,0);
	  showword(mao_2,0x21,0);//显示实验序号
	  PutData2(4,3,ID2[1]);

	  showword(cao_2, 0x02,0);
	  showword(zuo_2,0x12,0);
	  showword(zhe_2,0x22,0);
	  showword(mao_2,0x32,0);//显示操作者
	  for(xx=0,yy=0;xx<6;yy+=2,xx++)//只读6个字节的学号
	    PutData2(6+yy,5,buf[xx]);   
	  showword(lian_2, 0x53,0);
	  showword(jie_2,0x63,0);
	  showword(cheng_2,0x73,0);
	  showword(gong_2,0x83,0);//显示连接成功
}
	      
void  manu_data(void)
{
  if(ID2[1]==0x01)		//第一个实验
	{
	   switch (ID2[2])
		 {
		  case 0x01: step_one();   break;
	  	  //case 0x02: step_two();   break;
		  //case 0x03: step_three(); break;
		  //case 0x04: step_four();  break;
		  }
	}
/*
	if(ID2[1]==0x02)		//第二个实验
	{
	   switch (ID[2])
		 {
		  case 0x01: return(9);  break;
	  	  case 0x02: return(0);  break;
		  case 0x03: return(10); break;//确认健
		  case 0x04: return(11); break;//修改健
		  case 0x05: return(12); break;//向右健
		  }
	}*/

}

void  step_one(void)///实验一 步骤一 显示操作者,测量数据
{
	  ulong ad;
	  //////uchar buf[4]={111,222,51,255};///测试用
	  uchar dat[4],n;
	  uchar code str1[]={'I'-32,'c'-32,'q'-32,'='-32,'0'-32,'.'-32,'0'-32,'0'-32,'0'-32,'m'-32,'A'-32,0},str2[]={'V'-32,'b'-32,'q'-32,'='-32,'0'-32,'.'-32,'0'-32,'0'-32,'0'-32,'V'-32,0};
	  uchar code str3[]={'V'-32,'e'-32,'q'-32,'='-32,'0'-32,'.'-32,'0'-32,'0'-32,'0'-32,'V'-32,0},str4[]={'V'-32,'c'-32,'q'-32,'='-32,'0'-32,'.'-32,'0'-32,'0'-32,'0'-32,'V'-32,0};
  	  uchar code str0[]={'S'-32,'t'-32,'e'-32,'p'-32,'0'-32,'1'-32,0};
	  LcmClear(0);

	  PutData2(9,1,ID2[0]);
	  PutChar(12,1,0x03);
	  showword(shi, 0x70,0); 
 	  showword(yan,0x80,0); 
      showword(tai_2,0x90,0); //显示实验台序号

	  PutString(10,2,str0);
	  PutString(0,3,str1);
	    ////数据折算Icq
		ad=buf[0];
		ad=ad*5000/255;
	    dat[3]=ad%10;
	    dat[2]=ad/10%10;
	    dat[1]=ad/100%10;
	    dat[0]=ad/1000;
		PutData(4,3,dat[0]);
	    for(n=1;n<4;n++)
	    PutData(5+n,3,dat[n]);
	  PutString(0,4,str2);
	  ////数据折算
	    ad=buf[1];
		ad=ad*5000/255;
	    dat[3]=ad%10;
	    dat[2]=ad/10%10;
	    dat[1]=ad/100%10;
	    dat[0]=ad/1000;
		PutData(4,4,dat[0]);
	    for(n=1;n<4;n++)
	    PutData(5+n,4,dat[n]);
	  PutString(0,5,str3);
	  ////数据折算
	    ad=buf[2];
		ad=ad*5000/255;
	    dat[3]=ad%10;
	    dat[2]=ad/10%10;
	    dat[1]=ad/100%10;
	    dat[0]=ad/1000;
		PutData(4,5,dat[0]);
	    for(n=1;n<4;n++)
	    PutData(5+n,5,dat[n]);
	  PutString(0,6,str4);
	  ////数据折算
	    ad=buf[3];
		ad=ad*5000/255;
	    dat[3]=ad%10;
	    dat[2]=ad/10%10;
	    dat[1]=ad/100%10;
	    dat[0]=ad/1000;
		PutData(4,6,dat[0]);
	    for(n=1;n<4;n++)
	    PutData(5+n,6,dat[n]);
 	

}


/************************************************************************
      				    初始化界面
************************************************************************/
void manu_init(uchar k)
{	  
   // uchar k=0x10;
	//for(k=0x11;k<0x121;k+=0x10)
    // {
	 //if(manu1_flag==0)
	// {
 	  showword(wang_1, 0x20+k,0);
	  showword(luo_1, 0x30+k,0);
      showword(hua_1, 0x40+k,0);  
	  showword(shi,0x50+k,0); 
      showword(yan, 0x60+k,0);  
	  showword(jiao_1,0x70+k,0); 
	  showword(xue_1,0x80+k,0); 
 	  showword(xi,0x90+k,0); 
	  showword(tong,0xa0+k,0); 

	 // Delay(200);
	 // LcmClear(0);
	//  }
	//}
}

void manu_select(void)
{	  
      #define k 0x22
 	  showword(qing_1, 0x10+k,0);
	  showword(shu_1, 0x20+k,0);
      showword(ru_1, 0x30+k,0);  
	  showword(shi,0x40+k,0); 
      showword(yan, 0x50+k,0); 
 	  showword(xu_1,0x60+k,0); 
      showword(hao_1, 0x70+k,0); 
	  showword(mao_1, 0x80+k,0);
	  showword(xia_x,0x90+k,0);
	  showword(xia_x,0xa0+k,0);
}

//*****************中断0服务程序**********************
void int0_service()   interrupt 0 
{
   	uchar state,yy;
	uchar xdata *int_poin;      		//SJA1000地址变量指针	
	P1_0=1;//开蜂鸣器
	EA=0;//////////////////////////
	int_poin=IR;                		//IR   0X0003	中断寄存器
	state=*int_poin;					//读中断寄存器清除中断位
	if((state&0x08)==0x08)      		//0000 1000 IR.3=1数据溢出错误中断
	{							
		int_poin=CMR;           		//CMR  0x0001	命令寄存器
		*int_poin=0x0c;					//0000 1100 CMR.3,CMR.2=1 功能:清除数据溢出错误和释放接收缓冲区
	} 
	else if((state&0x04)==0x04)			//0000 0100 IR.2=1 总线出错报警中断
	{
		int_poin=SR;                    //SR 0X0002	状态寄存器
		state=*int_poin;                //读总线错报类型
		if ((state&0x80)==0x80)         //1000 0000 SR.7=1 总线关闭错误
		{
			int_poin=MODE;             
			*int_poin=0x00;				//进入工作模式
			state=0x01;
			while((state&0x01)==0x01)	//确保进入工作模式
			{
				state=*int_poin;
			}
		}
	}
/***********************接收数据中断**********************************/
	else if((state&0x01)==0x01)      	//0000 0001 IR.0=1接收中断
	{			
		int_poin=CANRX;                 //CANRX	0X0010	报文接受缓冲区首址
		state=*int_poin;		
		state=state&0x0f;          		//截取数据长度,低四位为所接数据长度
	 if (state==8)                      //数据长度为8
		{
		 for(state=0;state<4;state++)
			{
				int_poin++;
				ID2[state]=*int_poin;	    //存放在ID2数组中		
			}	
			for(state=0;state<8;state++)
			{
				int_poin++;
				buf[state]=*int_poin;	    //存放在buf数组中		
			}
//---------------------------------------数据处理------------------------------------------------
	/*	 if(ID2[3]==11||ID2[0]==11)           //若为学号
			{
			for(state=0,yy=0;state<6;yy+=2,state++)//只读6个字节的学号
			 {
			  XBYTE[state+0xdc00+ID2[0]]=buf[state];     //将学号存在以0xdc00+ID[0]为首地址的6个单元中
			  PutData2(6+yy,5,buf[state]);   
			 }   			
	        manu_xinxi();//显示 1# 试验台 操作者 学号及 连接成功
			Delay(2000);
			manu2=1;//回到初始化界面
			}
			if(ID2[3]==22||ID2[0]==22)           //若为数据
			{
				for(state=0;state<8;state++)
			 	 XBYTE[state+0xdc00+ID2[0]+add]=buf[state];  //将数据存在以0xdc00+ID[0]+10为首地址的8个单元中
				 add+=10;
			     flag_data=1;  /////接收新数据标志位
			}
            
			P1_0=0;//关蜂鸣器*/
		
	       

//-------------------------------------数据处理---------------------------------------		
		}//if (state==8) 
		//若state=0,则为远程帧,暂不作处理
		int_poin=CMR;			 
		*int_poin=0x04;			//释放当前报文空间
	}
	else                       //发送中断
	{   
		 Delay(200);
		 P1_0=0;//关蜂鸣器       //叫2次表示发送成功
	}
	EA=1;///////////////////////////////
}



⌨️ 快捷键说明

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