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

📄 wangzheng.c

📁 数控电源 用AD0809和DAO832实现 可用键盘任意预置电压值 可实现步进 用四位LED显示
💻 C
字号:
																																			   /*付启兵 龚华 王宏刚
   2008--4--1 
   April Fools' Day 
   GOOD LUCK ,YOUNG MEN !!!*/
#include<reg51.h>
//#include<stdio.h>
#include<absacc.h>
#include<math.h>

#define uchar unsigned char
#define uint unsigned int

#define DAC0832 XBYTE[0xffff] /*DAC地址*/
#define AD XBYTE[0X7FF8]

//#define P3_2 P3^2
//#define P3_3 P3^3
//#define N 10
sbit P2_0=P2^0;
sbit P2_1=P2^1;
sbit P2_2=P2^2;
sbit P2_3=P2^3;
sbit P2_4=P2^4;
sbit P2_5=P2^5;
sbit P2_6=P2^6;
sbit P3_7=P3^7;

//#define pro  displayled1[0]*10+displayled1[1]+99;
uchar pro=99;
uchar dis,keyH,keyL,keyM;
 
uchar displayled1[2],displayled,countflag;

uchar code tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
bit negativeflag,pointflag ,jhjflag,startflag=1,tri_transflag,squ_transflag;
bit upflag=1;
xdata tri_digital=1,squ_digital=0;
sbit cs=P3^5;
sbit AD_cs=P3^4;


//sbit led4=P2^3;
sbit ad_busy=P3^2;
uchar ad_data;
int ad_data1;


/*******延时*********
 void delay( )
{   uchar i ,j;
	for(i=0;i<20;i++)
	for(j=0;j<20;j++);
} */ 

void delay(unsigned int i)
{	
	while(i)i--;
}

 display(ad_data1)
{	EX0=0;

    cs=1;
    keyH=ad_data1/100;
	keyM=ad_data1%100/10;
//	keyMl=ad_data1%100/10;
	keyL=ad_data1%100%10;

   //P1=tab[keyH]|0x80;
	P0=tab[keyH]|0x80;
	P2_6=0;		
	delay(200);
	P2_6=1;

	P2_5=0; 
	//P1=tab[keyM];
	P0=tab[keyM];
	delay(200);	//延时不够(如为20)时无法正确显示
	P2_5=1; 
    P2_4=0; 
	//P1=tab[keyL];
	P0=tab[keyL];
	delay(200);
	P2_4=1;
    EX0=1;
	//P3_7=1;
    cs=0;

 	
  }





//#define pro 128 //预置值



/*x.x的显示	*/
 display1(key1)
{	
    keyH=key1/10;
    keyL=key1%10;

   	P0=tab[keyH]|0x80;
	P2_1=0;		
	delay(200);
	P2_1=1;

	P2_2=0; 
	P0=tab[keyL];
	delay(200);
	P2_2=1; 

	P2_3=0;
	P0=0x3e;
	delay(200);
	P2_3=1; 
   
}

/*-x.x的显示*/
display2(key2) 
{		
    keyH=key2/10;
    keyL=key2%10;

   	P0=tab[keyH]|0x80;
	P2_1=0;		
	delay(200);
	P2_1=1;

	P2_2=0; 
	P0=tab[keyL];
	delay(200);
	P2_2=1; 

    P2_0=0; 
	P0=0x40;
	delay(200);
	P2_0=1; 

	P2_3=0;
	P0=0x3e;
	delay(200);
	P2_3=1;

   
} 
/*x的显示*/
display3(key3)
{
    keyL=key3%10;

	P2_2=0; 
	P0=tab[keyL];
	delay(200);
	P2_2=1; 

	P2_3=0;
	P0=0x3e;
	delay(200);
	P2_3=1;
   
}

/*-x的显示*/
display4(key4)
{
	keyL=key4%10;
   	P0=0x40;
	P2_1=0;		
	delay(200);
	P2_1=1;

	P2_2=0; 
	P0=tab[keyL];
	delay(200);
	P2_2=1; 

	P2_3=0;
	P0=0x3e;
	delay(200);
	P2_3=1;
   
}

/*-的显示*/
display5( )
{
    P0=0x40;
	P2_2=0;		
	delay(200);
	P2_2=1;  

	P2_3=0;
	P0=0x3e;
	delay(200);
	P2_3=1;
}

/*三角波产生	 //不能在服务子程序中加while否则在主程序中无法响应中断
triangle_wave()
{ //while(1)
   DAC0832=tri_digital;
   if((tri_digital==255)||(tri_digital==0))
   upflag=~upflag;
   if(upflag==1) tri_digital++;
   else   tri_digital--;
   //delay();
   	
} */

/*方波产生
square_wave()
{ 
   DAC0832=squ_digital;
   if(squ_digital==0)
   squ_digital=255;
   else   squ_digital=0;
   delay(100);
    
} */
/*小数点的显示
display6()
{
	
    P0=0x80;
	P2_1=0;		
	delay(N);
	P2_1=1;

	P2_3=0;
	P0=0x3e;
	delay(N);
	P2_3=1;
	//displayled1[0] 

}	*	/


/*display7()	//清屏/* 
{ 
   	P0=0x00;
	P2_2=0;		
	delay(N);
	P2_2=1;

	 P0=0x00;
	 P2_3=0;
	 delay(N);
	 P2_3=1;
	 
    P0=0x00;
    P2_1=0; 
	delay(N);
	P2_1=1; 
}  */


/******加***********/
displayadd( )
{	//addflag=0;
	pro=pro+1;
	if(pro>198)pro=198;
	//	dis=pro; 
    //DAC0832=pro; 
	return;
	
		
}

/*******减*********/
displaysub( )
{  // subflag=0;
	pro=pro-1;
	if(pro==255)pro=0;	
	return;

}	  

/**void add1(void )  interrupt 0   // 中断服务自程序必须是void类型,如要返回一变量值可用定义全局变量的方式操作
{ 
    pro=pro+1;
	if(pro>198) pro=198;

}  */


/* void sub1(void) interrupt 2 //若加using2 则会出现错误	 若中断服务程序中用到using,而又调用其它函数,
                        // 则被调函数必须与中断服务程序使用相同的寄存器组
{  //delay(N); 
   //if(P3_3==1)
   //sub();
   //else return;														
   	pro=pro-1;
	if(pro==255)pro=0;	//本打算时判断当pro<0时将pro赋0的,但用if(pro<0)pro=0;来写会发生错误,
	                   //原因是pro为无符号型,故0-1=255,即在下次操作时pro已 变为255不能用pro<0来判断

   
} 	
 controlwords()
 {
   pro=displayled1[0]*10+displayled1[1] ;
   return(pro);
  }*/	

void ad0808(void) interrupt 0 //中断
{
    ad_data=AD;
}

 void keyinterrupt () interrupt 2
{   int t;
	uchar recode;
	uchar scancode;
	uchar flag=0xff;
	t=1000;
	while(t--);
	if(INT1==1)
	return;
	EX1=0;
    EX0=0;
	startflag=0;//一旦有键按下就表明不再是开机时的状态,故将其清零
//	tri_transflag=0	;
//	squ_transflag=0;
	//display7();
	//addflag=0;
	//subflag=0;
	jhjflag=0; //每次进入中断之前保证加减标志位清零
	 countflag++;
	if(countflag==3)  //是否按下了两个数,或只显示一位数
	{countflag=1;
	 negativeflag=0;
	 pointflag=0;
	//countflag1=0;
	//displayled1[0]=0;
	//displayled1[1]=0;
	}
	
	if((P1&0xf0)!=0xf0)//继续判断是否有按键按下
	     { 
	          scancode=0xfe;  //进行逐行判断
	          while((scancode&0x10)!=0)
	         { 
			      P1=scancode;
	        	  if((P1&0xf0)!=0xf0)//即如果P1口的高四位有0出现则继续执行下面程序(从低四位逐一赋0,而此语句将低四位屏蔽,判断高四位)
	              {
			 		  recode=(P1&0xf0|0x0f);
					  if(countflag==1) 
					  {
					 switch((~scancode)+(~recode))
				      {   // 下面是键盘的编码识别
				          case 0x81:     displayled1[0]=0;displayled1[1]=0;  break;//返回对应的键值0~15
				          case 0x82:     displayled1[0]=4; displayled1[1]=0; break;
				          case 0x84:     displayled1[0]=8;displayled1[1]=0;	break;
				          case 0x88:     tri_transflag=1;   break; //12	
				          case 0x41:     displayled1[0]=1;displayled1[1]=0;  break;
				          case 0x42:     displayled1[0]=5;displayled1[1]=0;  break;
				          case 0x44:     displayled1[0]=9;displayled1[1]=0;  break;
				          case 0x48:     pro=99; jhjflag=1;countflag--; break;			  //清屏功能键
				          case 0x21:     displayled1[0]=2;displayled1[1]=0;  break;
				          case 0x22:     displayled1[0]=6;displayled1[1]=0;  break;
				          case 0x24:     negativeflag=1; countflag--;displayled1[1]=0;displayled1[0]=0;  break;  //10	 负号选择键
				          //case 0x28:     pointflag=1;countflag--;break;
				          case 0x11:     displayled1[0]=3;displayled1[1]=0;  break;
				          case 0x12:     displayled1[0]=7;displayled1[1]=0;  break;
				          case 0x14:     displayadd();jhjflag=1;countflag--;break;//步进加功能键 11
				          case 0x18:     displaysub();jhjflag=1;countflag--;break;	//步进减功能键 12
						  default:break;
					  }
					        }
						     if(countflag==2)
							//else
								  {	  
							 		  switch((~scancode)+(~recode))
				      {   // 下面是键盘的编码识别
				          case 0x81:    displayled1[1]=0;     break;//返回对应的键值0~15
				          case 0x82:    displayled1[1]=4;  	  break;
				          case 0x84:    displayled1[1]=8;    break;
				          case 0x88:    squ_transflag=1;   break; //12
				          case 0x41:    displayled1[1]=1;     break;
				          case 0x42:    displayled1[1]=5;     break;

				          case 0x44:    displayled1[1]=9;    break;
				         // case 0x48:    negativeflag=1;countflag--;   break;  //14
				          case 0x21:    displayled1[1]=2;     break;
				          case 0x22:    displayled1[1]=6;     break;
				          //case 0x24:    negativeflag=1;countflag--;   break;
				          case 0x28:     pointflag=1;countflag--;displayled1[1]=0;break;
				          case 0x11:    displayled1[1]=3;     break;
				          case 0x12:    displayled1[1]=7;     break;
				          case 0x14:     displayadd();jhjflag=1;countflag--;break;//步进加功能键 11
					      case 0x18:     displaysub();jhjflag=1;countflag--;break;	//步进减功能键 15	  default:break;
					  }

			}
			}
	        else 
	            scancode = (scancode<<1)|0x01;//sccode左移一位继续扫描
	      }
		 }
		 
    P1=0xf0;
	while(1)
	{if(INT1==1)
		flag=~flag;
		if(flag==0) break;
		t=10000;
		while(t--);
	}
	EX1=1;
	EX0=1;
	return;
}

/*******主函数**********/
 main()
{
	//uchar displayled=0;//预置值 当此处忘记加分号时会产生 "too many actual parameters"的错误
    //displayled1[0]=displayled;
	//uchar pro1;
	
  
	P1=0xf0;
	//IT0 =1;
	IT1 =1;
	//EX0 = 1;
	//EX1 = 1;
	//EA = 1;	
	//countflag1=0;

	ad_data=0;
	ad_busy=0;

	while(1)
	{	 //display3(displayled1[0]);
		 //dis=pro;	 //一定要是先在外面赋初始值
         //display1(0);
		//pro=(displayled1[0]*10+displayled1[1])+99;
	    //DAC0832=pro; //由于开始时displayled1[0]*10+displayled1[1]的值是不确定的,故不可将其赋给DAC0832
		//DAC0832=pro1;
       //由于堆栈的作用,必须把pro赋给dis
	  // pro=(displayled1[0]*10+displayled1[1])+99;
	  	
	    AD_cs=0;
		EA=1;
		EX1=0;
	    EX0=1;
	    IT0=0;
    	AD=0;
		//P2=1;
		 // 去掉此语句后无法正确显示
		 
		ad_data1=ad_data+ad_data;
		 EX0=0;
	    //delay(100 );
		display(ad_data1); 
		delay(50);


	
		
	  EA=1;
	  EX0=0;
	  EX1=1;
	  cs=0;
if(startflag==1)		 //开机显示
  {	   
       display1(0);
	   DAC0832=99;
	   cs=1;
	   //delay(200);	  
  }

	  else

	{
		   if(jhjflag==1)	
		   {  
		   if(pro>=99)
			 {  
			 dis=pro-99;
			 display1(dis);	   //步进加
			 DAC0832=pro;
			 }
			 else
			 {
			  dis=99-pro;	   //步进减
			  display2(dis);
			  DAC0832=pro;
			 } 
		   } 
	  
	       else{
			     //pro=(displayled1[0]*10+displayled1[1])+99;
			    // DAC0832=pro;
					if (tri_transflag==1&&countflag==1)
				   {triangle_wave();
				    }
				    if (squ_transflag==1&&countflag==2)
					{square_wave();
					} 
		
				    if(negativeflag==1&&!countflag)//负号显示
					{
					display5( );
					}
			
				    if(countflag==1&&negativeflag==0&&pointflag==0)//一位数的显示
					{
					display3(displayled1[0]);
					DAC0832=(displayled1[0]*10+displayled1[1])+99;
					pro=99+(displayled1[0]*10+displayled1[1]);
					}
					
					//if(pointflag==1) //小数点的显示
					//{display6()&&countflag==1;
					//}
				    if(negativeflag==0&&pointflag==1)//两位数的显示
					{
					display1(displayled1[0]*10+displayled1[1]);
					DAC0832=displayled1[0]*10+displayled1[1]+99;
				    pro=99+(displayled1[0]*10+displayled1[1]);
					 //display1(pro);
					}
					
				    if(negativeflag==1&&pointflag==1) //负的两位数的显示
					{
					display2(displayled1[0]*10+displayled1[1]);
					DAC0832=99-(displayled1[0]*10+displayled1[1]);
					pro=99-(displayled1[0]*10+displayled1[1]);
					}
			
				    if(countflag==1&&negativeflag==1&&pointflag==0) //负的一位数的显示
					{
					display4(displayled1[0]);
					DAC0832=99-(displayled1[0]*10+displayled1[1]);
					pro=99+(displayled1[0]*10+displayled1[1]);
					}
					 //display1(pro-99);
					 delay(200);

				}
	}	 cs=1;
	     ///DAC0832=pro;  
		 //countflag1++  ;
	   
}

}	 
	   /*若为128则为-0.1的电压,若为0则为-5v,若为255则为4.95v
      产生中断前先入栈了,故返回后仍是原先显示的值,除非改变中
	  	   断时入栈的值,才能改变显示的值*/

⌨️ 快捷键说明

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