stc8a_zhixian_chabu代码

主程序

#include <stc8a8k.h>
#include <stdio.h>
#include <math.h>
#include "oled.h"
#include "key44.h"

unsigned int flag1;
unsigned int count1;
unsigned int count2;
unsigned char KeyValue;
#define xzdir 1  //x正方向,靠近电机
#define xfdir 0  //x反方向,远离电机
#define yzdir 1
#define yfdir 0

#define movex 0
#define movey 1

sbit xdir=P3^4;//x方向引脚
sbit xpu=P6^4;//x脉冲

sbit ydir=P3^5;//y方向引脚
sbit ypu=P6^7;//y脉冲


sbit beep=P5^5;//蜂鸣器引脚

sbit shache=P0^3;//引脚x原点指示灯
sbit xoriginLED=P0^4;//引脚x原点指示灯
sbit yoriginLED=P0^5;//引脚y原点指示灯
sbit xtriginLED=P0^6;//引脚x原点指示灯
sbit ytriginLED=P0^7;//引脚y原点指示灯

// sbit key0=P0^0;//启动按钮;
// sbit key1=P0^1;//选择任务;
// sbit key2=P0^2;//,选择设置的参数:=1,x坐标,=2;y坐标;=3,斜率kb,=4,长度
// sbit key3=P0^3;//选择步长0.01-0.1-1-10-100
// sbit key4=P0^4;//+
// sbit key5=P0^5;//-
// sbit key6=P0^6;//
// sbit key7=P0^7;//选择速度;

unsigned char key1count=0;
unsigned char key2count=0;
unsigned char key3count=0;
unsigned char key4count=0;
unsigned char key5count=0;
unsigned char key6count=0;
unsigned char key7count=0;

int parnum=0;
float stepnum=0.01;
//定时器初值
int freq[10]={1000,2000,3000,4000,5000,6000,7000,8000,9000,10000};
int freqnum=1;
//200*49.38=39.7mm
float pulmm=49.5;//脉冲当量1mm---49.38pulse-   0.5mm--25pulse
int pulnum;
int movesel=0;//movesel=0;选择x轴,=1,选择y轴
//********************************
int xo,yo;//xy的原点坐标
int xstart,ystart;//x,y的起点坐标
int xm,ym;//x,y的动点坐标
int xm1,ym1;
int xend,yend;//终点坐标
int stepsum;//总步长
int ixx;//象限;
int fm;fm1;//偏差;

float kb;
float linelength;

int xoflag=0,yoflag=0;
int jiting=0;
//任务标签
int taskflag=0;
//任务0:0:x回0;1:y回0;2:两个轴回0
void runtask0(int i);

//任务1:原点出发,给定目标坐标,实现第一象限插补
void runtask1(float xeo,float yeo);

//任务2:原点出发,给定斜率,要求是正数,给定线段的长度,进行插补
void runtask2(float kbtemp,float linelengthtemp);

//任务3:原点出发,给定线段起点A的坐标,线段末端的坐标B,判断象限,然后直线插补;
void runtask3(float xa,float ya,float xb,float yb);

//任务4:原点出发,给定圆的圆心,给定半径,逆时针圆弧插i=0
void runtask4(float xra,float yra,float xyradius,unsigned char i);

//直线插补的象限判断,返回1,第一象??---2  3---3   4---4
unsigned char judgexx(float xa,float ya,float xb,float yb);

//插补
void diyi(float xa,float ya,float xb,float yb);
void dier(float xa,float ya,float xb,float yb);
void disan(float xa,float ya,float xb,float yb);
void disi(float xa,float ya,float xb,float yb);
//走一步
void xposstep();//x+
void xnegstep();//x-
void yposstep();//y+
void ynegstep();//y-
//延时ms函数
void delayms(int tt)
{ 
	int i,j;
	for(i=tt;i>0;i--)
		for(j=5000;j>0;j--);
}
void dididi(int tt,int ss)
{
  for(tt;tt>0;tt--)
	{
	  beep=1;
		delayms(ss);
		beep=0;
		delayms(ss);
	}
}
//延时us函数
void delayus(int tt)
{ 
	int i,j;
	for(i=tt;i>0;i--)
		for(j=100;j>0;j--);
}
//端口初始化
void port_init()
{
	P0M0=0x00;P0M1=0x00;
	P1M0=0x00;P1M1=0x00;
	P2M0=0x00;P2M1=0x00;
	P3M0=0x00;P3M1=0x00;
	P4M0=0x00;P4M1=0x00;
	P5M0=0x00;P5M1=0x00;
	P6M0=0x00;P6M1=0x00;
	P7M0=0x00;P7M1=0x00;
}


void main()
{
	unsigned char disbuf[9];
int bb;
	port_init();
	OLED_Init();
	flag1=0;
	kb=0.2;
	linelength=10;
	beep=0;
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0x66;		//设置定时初值
	TH0 = 0xEA;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	
	
	ET0=1;
	
	//限位开关中断打开,下降沿触发
	//x轴中断
	IT0=1;
	EX0=1;
	//y轴中断
	IT1 = 1;                        //set INT1 int type (1:Falling only 0:Low level)
  EX1 = 1;                        //enable INT1 interrupt
	//INT2
	INTCLKO = EX2|EX3|EX4;    //使能INT2中断
	//INTCLKO = EX3;     //使能INT3中断
	
	//总中断触发
	EA=1;	
	OLED_ShowString(0,0,"start ok!");	//72 
	 
	 xm=0;
	 ym=0;
	 xend=100;
	 yend=200;
	 kb=0.01;
	 linelength=100;
	 OLED_ShowString(80,0,"key");	
	 while(1)
	{	
		//KeyValue=
		KeyScan();
		
		OLED_ShowNum(105,0,KeyValue,2,12);
		
			if(KeyValue==1)
			{
   KeyValue=200;	
				switch(key1count)
				{
				 case 0://任务0,原点出发,直线插补
						OLED_ShowString(20,1,"runT0!");
// 				    xend=(int)(22.22*10);//xiaopingtai
// 				    yend=(int)(22.22*30);//100-5mm
				 //x轴脉冲当量和Y轴脉冲当量,因为误差原因,所以两个需要都调节
				    xend=(int)(20*xend);//xiaopingtai---12
				    yend=(int)(19.3*yend);//100-5mm-----38
				   // runtask1(xend,yend);	//100--5   300-17  12  28
           // dididi(5,100);
						break;//两个轴都回0runtask0(1);runtask0(0); 
				 //*************************************************
				 //*******************************************
				 case 1://0
					 OLED_ShowString(20,1,"runT1!");
				 
				  // runtask0(2);
				   break;//原点出发,然后输入的是末端的坐标100,200
				 //******************************************************
				 //******************************************************
				 case 2:
							OLED_ShowString(20,1,"runT2!");
							//runtask2(kb,linelength);
							break;
				 //******************************************************
				 //******************************************************
				 case 3:
							OLED_ShowString(20,1,"runT3!");
						//	runtask3(xm,ym,xend,yend);
							break;
				 case 4:
							OLED_ShowString(20,1,"runT4!");
						//	runtask3(xm,ym,xend,yend);
							break;
				 //**********************************************************
				 //**********************************************************
         default:break;      					
				}
			}
		
		
		else if(KeyValue==2)  //选择任务
		{
			KeyValue=200;	
				  key1count++;
								OLED_ShowString(0,1,"t");
				  OLED_ShowNum(0,10,key1count,2,12);
				//	if(key1count==1)
					 // OLED_ShowString(0,3,"key1c =1!");
					//if(key1count==2)
					//  OLED_ShowString(0,3,"key1c =2!");
				//	if(key1count==3)
					//  OLED_ShowString(0,3,"key1c =3!");
			//		if(key1count==4)
					//  OLED_ShowString(0,3,"key1c =4!");
				 if(key1count==5)
					{
						key1count=0;
						//OLED_ShowString(0,3,"key1c =0!");
					}
        //LCD显示
		
		}
		
		//选择设置的参数:=1,x坐标,=2;y坐标;=3,斜率kb,=4,长度
		else if(KeyValue==3)//选择设置的参数//,		
		{
		KeyValue=200;	
				key2count++;
				if(key2count==7)
					 key2count=1;
				
			  switch(key2count)
				{
					case 1://xm
						parnum=1; OLED_ShowString(50,2,"p=xm!");break;
					case 2://xend
						parnum=2; OLED_ShowString(50,2,"p=xe!");break;
					case 3://ym
						parnum=3; OLED_ShowString(50,2,"p=ym!");break;
					case 4://yend
						parnum=4; OLED_ShowString(50,2,"p=ye!");break;
					case 5://kb
						parnum=5; OLED_ShowString(50,2,"p=kb!");break;
					case 6://linelenth
						parnum=6; OLED_ShowString(50,2,"p=li!");break;
					default:break;		
				}   
				//LCD显示
			
		}
		//*****************************************************key3
			else if(KeyValue==4)//选择设置步长?/,
			//选择设置的参数:0.01----0.1----1----10---100
		{
			
				key3count++;
				if(key3count==6)
					 key3count=1;
				KeyValue=200;	
			  switch(key3count)
				{
					case 1:
						stepnum=0.01;break;
					case 2:
						stepnum=0.1;break;
					case 3:
						stepnum=1;break;
					case 4:
						stepnum=10;break;
					case 5:
						stepnum=100;break;
					default:break;		
				}   
				//LCD显示
				OLED_ShowNum(0,3,stepnum,3,12);
			
		}
			//*****************************************************key4
			else if(KeyValue==5)//+         加参数
			//选择设置的参数:0.01----0.1----1----10---100
		{
						KeyValue=200;	
			  switch(parnum)
				{
					case 1://起点加1毫米
						if(xm>500)
							xm=0;
						else
						xm=xm+stepnum;
						break;
					case 2://终点加1毫米
						if(xend>500)
							xend=0;
						else
						xend=xend+stepnum;
						break;
					case 3://起点加1毫米
							if(ym>500)
							ym=0;
						else
						  ym=ym+stepnum;
						break;
					case 4://终点加1毫米
							if(yend>500)
							yend=0;
						else
				  	yend=yend+stepnum;
						break;
					case 5://斜率加0.01
						if(kb>1)
							kb=0;
						else
						kb=kb+0.01;
						break;
					case 6://长度加1毫米
						if(linelength>500)
							linelength=0;
						else
						linelength=linelength+stepnum;
						break;
					default:break;		
				}  
//LCD显示				
			
		}
		
		//*****************************************************key5
			else if(KeyValue==6)//+
			//选择设置的参数:0.01----0.1----1----10---100
		{
					KeyValue=200;	
			  switch(parnum)
				{
					case 1://起点加1毫米
						if(xm<-500)
							xm=500;
						else
						xm=xm-stepnum;
						break;
					case 2://终点加1毫米,
						if(xend<-500)
							xend=0;
						else
						xend=xend-stepnum;
						break;
					case 3://起点加1毫米
							if(ym<-500)
							ym=0;
						else
						  ym=ym-stepnum;
						break;
					case 4://终点加1毫米
							if(yend<-500)
							yend=0;
						else
				  	yend=yend-stepnum;
						break;
					case 5://斜率加0.01
						if(kb<0)
							kb=1;
						else
						kb=kb-0.01;
						break;
					case 6://长度加1毫米
						if(linelength<-500)
							linelength=500;
						else
						linelength=linelength-stepnum;
						break;
					default:break;		
				} 
//LCD显示				
			
		}
	
			//*****************************************************key7
			else if(KeyValue==7)//选择设置步长?/,
			//选择设置的参数:0.01----0.1----1----10---100
		{
			KeyValue=200;	
				key7count++;
				if(key7count==6)
					 key7count=1;
				
			  switch(key7count)
				{
					case 1:
						freqnum=1;break;
					case 2:
						freqnum=2;break;
					case 3:
						freqnum=3;break;
					case 4:
						freqnum=4;break;
					case 5:
						freqnum=5;break;
					default:break;		
				}  
//LCD显示				
			
		}
			//*****************************************************key7
			else if(KeyValue==12)//S13   x+
			//选择设置的参数:0.01----0.1----1----10---100
		{
				KeyValue=200;		
			OLED_ShowString(60,3,"x+=");		OLED_ShowNum(85,3,jiting,1,12);
			  while(jiting==0)xposstep();
	OLED_ShowNum(85,3,jiting,1,12);
				dididi(3,20);
			jiting=0;
		}  
			
				//*****************************************************key7
			else if(KeyValue==13)//S13   x-
			//选择设置的参数:0.01----0.1----1----10---100
		{KeyValue=200;  
			OLED_ShowString(60,3,"x-=");		OLED_ShowNum(85,3,jiting,1,12);
			 while(jiting==0)xnegstep();//y-
     OLED_ShowNum(85,3,jiting,1,12);
			dididi(3,20);
			jiting=0;
			
			}
			
				//*****************************************************key7
			else if(KeyValue==14)//S13   y+
			//选择设置的参数:0.01----0.1----1----10---100
		{KeyValue=200;
			
				OLED_ShowString(60,3,"y+=");		OLED_ShowNum(85,3,jiting,1,12);
				 while(jiting==0)yposstep();
		OLED_ShowNum(85,3,jiting,1,12);
				dididi(3,20);
			jiting=0;
			}
			
				//*****************************************************key7
			else if(KeyValue==15)//S13   y-
			//选择设置的参数:0.01----0.1----1----10---100
		{KeyValue=200;
			OLED_ShowString(60,3,"y-=");		OLED_ShowNum(85,3,jiting,1,12);
			 while(jiting==0)ynegstep();//y-
			OLED_ShowNum(85,3,jiting,1,12);
				dididi(3,20);
			jiting=0;
			}
			
		KeyValue=100;
		
			
			
			
		OLED_ShowString(0,4,"kb=");	
		sprintf(disbuf,"%.2f",kb);
		OLED_ShowString(24,4,disbuf);
	
		
		OLED_ShowString(60,4,"le=");
		if(linelength>0)
		{
			OLED_ShowChar(90,4,'+');
			OLED_ShowNum(98,4,linelength,3,12);
		}
		else
		{
			OLED_ShowChar(90,4,'-');
			OLED_ShowNum(98,4,abs(linelength),3,12);
		}

		
		OLED_ShowString(0,5,"xm=");
			if(xm>0)
		{
			OLED_ShowChar(24,5, '+');
			OLED_ShowNum(32,5,xm,3,12);
		}
		else
		{
			OLED_ShowChar(24,5,'-');
			OLED_ShowNum(32,5,abs(xm),3,12);
		}

		
		OLED_ShowString(60,5,"ym=");
			if(ym>0)
		{
			OLED_ShowChar(90,5, '+');
			OLED_ShowNum(98,5,ym,3,12);
		}
		else
		{
			OLED_ShowChar(90,5,'-');
			OLED_ShowNum(98,5,abs(ym),3,12);
		}

		
		OLED_ShowString(0,6,"xe=");	
			if(xend>0)
		{
			OLED_ShowChar(24,6, '+');
			OLED_ShowNum(32,6,abs(xend),3,12);
		}
		else
		{
			OLED_ShowChar(24,6,'-');
			OLED_ShowNum(32,6,abs(xend),3,12);
		}

		
		OLED_ShowString(60,6,"ye=");
			if(yend>0)
		{
			OLED_ShowChar(90,6, '+');
			OLED_ShowNum(98,6,yend,3,12);
		}
		else
		{
			OLED_ShowChar(90,6,'-');
			OLED_ShowNum(98,6,abs(yend),3,12);
		}

	}
}
//限位开关x轴P32,低电平触发
//External interrupt0 service routine
void exint0() interrupt 0           //(location at 0003H)
{
 //  beepdidi(3);
	 xoriginLED=1;
	 xoflag=1;
	 TR0=0;
	 xpu=0;
	dididi(5,10);
}
//External interrupt1 service routine
void exint1() interrupt 2           //(location at 0013H)
{
  // beepdidi(3);
	 yoriginLED=1;
	 yoflag=1;
	 TR0=0;
	 ypu=0;
	dididi(5,20);
}

//*********************INT2

void INT2_Isr() interrupt 10 using 1
{
                          //测试端口
	 xoriginLED=1;
	 xoflag=1;
	 TR0=0;
	 xpu=0;
	dididi(3,50);
}
//*********************INT3
void INT3_Isr() interrupt 11 using 1
{
   yoriginLED=1;
	 yoflag=1;
	 TR0=0;
	 ypu=0;  
	dididi(6,80);	//测试端口
}
void INT4_Isr() interrupt 16 using 1
{
  jiting=1;                          //测试端口
	
}
//********************************************************x正方向
void Timer0() interrupt 1
{	

	
	TL0 = 0x66;		//设置定时初值1ms
 	TH0 = 0x7E;		//设置定时初值
	
	count1++;
	if(count1>=10)//pulnum
	{
		count1=0;
		flag1=1;
	}
	else 
	{	
		if(movesel==movex)		
			xpu=!xpu;	       
	  else if(movesel==movey)
			ypu=!ypu;
	}
	
}
//******************************************************
void xposstep()//x+
{
	movesel=movex;
	xdir=xzdir;
	
	TR0=1;
	while(flag1==0);
	flag1=0;
	TR0=0;	
}

void xnegstep()//x-
{
	movesel=movex;
	xdir=xfdir;
	TR0=1;
	while(flag1==0);
	flag1=0;
	TR0=0;	
}

void yposstep()//y+
{
	movesel=movey;
	ydir=yzdir;
	TR0=1;
	while(flag1==0);
	flag1=0;
	TR0=0;	
}

void ynegstep()//y-
{
	movesel=movey;
	ydir=yfdir;
	TR0=1;
	while(flag1==0);
	flag1=0;
	TR0=0;	
}
//********************************************回0
void runtask0(int i)
{
	switch(i)
	{
		case 0: //x轴回0
					while(xoflag==0)//如果不碰到开关,那么一直靠近电机,碰到开关,在中断中让xoflag=1,跳出循环
						xposstep();
					
					delayms(10);
					xoflag=0;
			
			break;
			
			case 1: //y轴回0
					while(yoflag==0)//如果不碰到开关,那么一直靠近电机
						yposstep();
					delayms(100);
					yoflag=0;
					
			break;
			
			case 2: //x,y轴回0
					while(xoflag==0)//如果不碰到开关,那么一直靠近电机
						xposstep();
					delayms(100);
					xoflag=0;//清空标记,给下次使用
					
					while(yoflag==0)//如果不碰到开关,那么一直靠近电机
						yposstep();
					delayms(100);
					yoflag=0;
			break;
					
			default:break;	
	}
}
//
//任务1:原点出发,给定目标坐标,实现第一象限插补
void runtask1(float xeo,float yeo)
{
	//runtask0(2);//回0
	diyi(0,0,xeo,yeo);
}

//任务2:原点出发,给定斜率,要求是正数,给定线段的长度,进行插补
void runtask2(float kbtemp,float linelengthtemp)
{
	float xend2;
	float yend2;
	xend2=linelengthtemp*cos(kbtemp);//弧度
	yend2=linelengthtemp*sin(kbtemp);
	diyi(0,0,xend2,yend2);
}


//任务3:原点出发,给定线段起点A的坐标,线段末端的坐标B,判断象限,然后直线插补;
void runtask3(float xa,float ya,float xb,float yb)
{
	int i;
	//runtask0(2)//先回0
	i=judgexx(xa,ya,xb,yb);//判断第几象限插补
	switch(i)
	{
		case 1:
			diyi(xa,ya,xb,yb);
		  break;
		case 2:
			dier(xa,ya,xb,yb);
		  break;
		case 3:
			disan(xa,ya,xb,yb);
		  break;
		case 4:
			disi(xa,ya,xb,yb);
		  break;
		default:break;
	}
	
}

//**************************************************子程序:
//**************************************************第一象限插补
//******************************************************************
void diyi(float xa,float ya,float xb,float yb)
{
	xstart=xa;
	ystart=ya;//起点坐标
	xend=xb;
	yend=yb;//终点坐标	
	stepsum=(xend-xstart)+(yend-ystart);//计算总的步数 	
	fm=0;//一开始偏差=0,后面判断是在线的上面,还是下面
	
	while(stepsum>=0)
	{
		if(fm<0)
		{
			yposstep();
			fm=fm+xend;
		}
		else 
		{
			xposstep();
			fm=fm-yend;
		}
		stepsum--;
	}
	
	TR0=0;
	
}
//第二象限
void dier(float xa,float ya,float xb,float yb)
{
	xstart=abs(xa);
	ystart=abs(ya);//起点坐标
	xend=abs(xb);
	yend=abs(yb);//终点坐标	
	
	stepsum=abs(xend-xstart)+abs(yend-ystart);//计算总的步数 	
	fm=0;//一开始偏差=0,后面判断是在线的上面,还是下面
	while(stepsum>=0)
	{
		if(fm<0)
		{
			yposstep();
			fm=fm+xend;
		}
		else 
		{
			xnegstep();
			fm=fm-yend;
		}
		stepsum--;
	}
}
void disan(float xa,float ya,float xb,float yb)
{
	xstart=abs(xa);
	ystart=abs(ya);//起点坐标
	xend=abs(xb);
	yend=abs(yb);//终点坐标	
	
	stepsum=abs(xend-xstart)+abs(yend-ystart);//计算总的步数 	
	fm=0;//一开始偏差=0,后面判断是在线的上面,还是下面
	while(stepsum>=0)
	{
		if(fm<0)
		{
			ynegstep();
			fm=fm+xend;
		}
		else 
		{
			xnegstep();
			fm=fm-yend;
		}
		stepsum--;
	}
}
void disi(float xa,float ya,float xb,float yb)
{
	xstart=abs(xa);
	ystart=abs(ya);//起点坐标
	xend=abs(xb);
	yend=abs(yb);//终点坐标	
	
	stepsum=abs(xend-xstart)+abs(yend-ystart);//计算总的步数 	
	fm=0;//一开始偏差=0,后面判断是在线的上面,还是下面
	while(stepsum>=0)
	{
		if(fm<0)
		{
			ynegstep();
			fm=fm+xend;
		}
		else 
		{
			xposstep();
			fm=fm-yend;
		}
		stepsum--;
	}
}
//*************************************************判断象限
unsigned char judgexx(float xa,float ya,float xb,float yb)
{
	float xtemp,ytemp;
	unsigned char resultxx;
	xtemp=xb-xa;
	ytemp=yb-ya;
	
	if(xtemp>0)
	{
		if(ytemp>0)
			resultxx=1;
		else
			resultxx=4;
	}
	else 
	{
		if(ytemp>0)
			resultxx=2;
		else
			resultxx=3;
	}
	return resultxx;//返回判断的象限结果
}


oled.c

// //--------------------------------- 
// //  d0    d1  res  dc  cs
// //  scl  sdin rst  
// //-----------------OLED端口定义----------------  
// sbit OLED_SCLK= P0^0;
// sbit OLED_SDIN= P0^1;
// sbit OLED_RST=P0^2;
// sbit OLED_DC=P0^3;
// sbit OLED_CS=P0^4;
//******************************************************************************/

#include "oled.h"
#include "oledfont.h"  	 

#if OLED_MODE==1
//向SSD1106写入一个字节。
//dat:要写入的数据/命令
//cmd:数据/命令标志 0,表示命令;1,表示数据;
void OLED_WR_Byte(u8 dat,u8 cmd)
{
	DATAOUT(dat);	    
	if(cmd)
	  OLED_DC_Set();
	else 
	  OLED_DC_Clr();		   
	OLED_CS_Clr();
	OLED_WR_Clr();	 
	OLED_WR_Set();
	OLED_CS_Set();	  
	OLED_DC_Set();	 
} 	    	    
#else
//向SSD1106写入一个字节。
//dat:要写入的数据/命令
//cmd:数据/命令标志 0,表示命令;1,表示数据;
void OLED_WR_Byte(u8 dat,u8 cmd)
{	
	u8 i;			  
	if(cmd)
	  OLED_DC_Set();
	else 
	  OLED_DC_Clr();	
delay4us_tOLED(1);	
	OLED_CS_Clr();
	delay4us_tOLED(1);	
	for(i=0;i<8;i++)
	{			  
		OLED_SCLK_Clr();
		delay4us_tOLED(1);	
		if(dat&0x80)
		   OLED_SDIN_Set();
		else 
		   OLED_SDIN_Clr();
		OLED_SCLK_Set();
		dat<<=1;   
	}	
delay4us_tOLED(1);		
	OLED_CS_Set();
	delay4us_tOLED(1);	
	OLED_DC_Set();   	  
} 
#endif
	void OLED_Set_Pos(unsigned char x, unsigned char y) 
{ 
	OLED_WR_Byte(0xb0+y,OLED_CMD);
	OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD);
	OLED_WR_Byte((x&0x0f)|0x01,OLED_CMD); 
}   	  
//开启OLED显示    
void OLED_Display_On(void)
{
	OLED_WR_Byte(0X8D,OLED_CMD);  //SET DCDC命令
	OLED_WR_Byte(0X14,OLED_CMD);  //DCDC ON
	OLED_WR_Byte(0XAF,OLED_CMD);  //DISPLAY ON
}
//关闭OLED显示     
void OLED_Display_Off(void)
{
	OLED_WR_Byte(0X8D,OLED_CMD);  //SET DCDC命令
	OLED_WR_Byte(0X10,OLED_CMD);  //DCDC OFF
	OLED_WR_Byte(0XAE,OLED_CMD);  //DISPLAY OFF
}		   			 
//清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!!	  
void OLED_Clear(void)  
{  
	u8 i,n;		    
	for(i=0;i<8;i++)  
	{  
		OLED_WR_Byte (0xb0+i,OLED_CMD);    //设置页地址(0~7)
		OLED_WR_Byte (0x00,OLED_CMD);      //设置显示位置—列低地址
		OLED_WR_Byte (0x10,OLED_CMD);      //设置显示位置—列高地址   
		for(n=0;n<128;n++)OLED_WR_Byte(0,OLED_DATA); 
	} //更新显示
}


//在指定位置显示一个字符,包括部分字符
//x:0~127
//y:0~63
//mode:0,反白显示;1,正常显示				 
//size:选择字体 16/12 
void OLED_ShowChar(u8 x,u8 y,u8 chr)
{      	
	unsigned char c=0,i=0;	
		c=chr-' ';//得到偏移后的值			
		if(x>Max_Column-1){x=0;y=y+2;}
				OLED_Set_Pos(x,y+1);
				for(i=0;i<6;i++)
				OLED_WR_Byte(F6x8[c][i],OLED_DATA);
}
//m^n函数
u16 oled_pow(u8 m,u8 n)
{
	u16 result=1;	 
	while(n--)result*=m;    
	return result;
}				  
//显示2个数字
//x,y :起点坐标	 
//len :数字的位数
//size:字体大小,这里是12
//mode:模式	0,填充模式;1,叠加模式
//num:数值(0~4294967295);	 		  
void OLED_ShowNum(u8 x,u8 y,u16 num,u8 len,u8 size0)
{         	
	u8 t,temp;
	u8 enshow=0;						   
	for(t=0;t<len;t++)
	{
		temp=(num/oled_pow(10,len-t-1))%10;
		if(enshow==0&&t<(len-1))
		{
			if(temp==0)
			{
				OLED_ShowChar(x+((size0/2)+1)*t,y,' ');//这里我自己修改了一下。不如数据会重叠
				continue;
			}else enshow=1; 
		 	 
		}
	 	OLED_ShowChar(x+((size0/2)+1)*t,y,temp+'0'); //这里我自己修改了一下。不如数据会重叠
	}
} 
//显示一个字符号串
void OLED_ShowString(u8 x,u8 y,u8 *chr)
{
	unsigned char j=0;
	while (chr[j]!='\0')
	{		OLED_ShowChar(x,y,chr[j]);
			x+=8;
		if(x>120){x=0;y+=2;}
			j++;
	}
}

//初始化SSD1306					    
void OLED_Init(void)
{ 	
  //设置端口的IO模式,不同引脚不一样 ====================********%%%    注意修改
// sbit OLED_SCLK= P0^2;
// sbit OLED_SDIN= P0^3;
// sbit OLED_RST=P0^4;
// sbit OLED_DC=P2^0;
// sbit OLED_CS=P0^6;
	//准双向口模式
	// --------------------------
	//     P07 06  05 04   03 02 01 00
	//P0M0  x   0   x  0   0  0  x  x     ===0xa3
	//P0M1  x   0   x  0   0  0  x  x     ===0xa3
	//准双向口模式
	// --------------------------
	//     P27 26  25 24  23 22 21 20
	//P2M0  x   x  x  x  x  x  x    0    ==0xfe
	//P2M1  x   x   x  x   x  x  x  0	   ==0xfe
	
  P4M0 =0;//与操作 清零
	P4M1 =0;
	
	P7M0=0;
	P7M1=0;
	/
	
	delay_tmsOLED(5);
  OLED_RST_Set();
	delay_tmsOLED(5);
	OLED_RST_Clr();
	delay_tmsOLED(5);
	OLED_RST_Set(); 
					  
	OLED_WR_Byte(0xAE,OLED_CMD);//--turn off oled panel
	OLED_WR_Byte(0x00,OLED_CMD);//---set low column address
	OLED_WR_Byte(0x10,OLED_CMD);//---set high column address
	OLED_WR_Byte(0x40,OLED_CMD);//--set start line address  Set Mapping RAM Display Start Line (0x00~0x3F)
	OLED_WR_Byte(0x81,OLED_CMD);//--set contrast control register
	OLED_WR_Byte(0xCF,OLED_CMD); // Set SEG Output Current Brightness
	OLED_WR_Byte(0xA1,OLED_CMD);//--Set SEG/Column Mapping     0xa0左右反置 0xa1正常
	OLED_WR_Byte(0xC8,OLED_CMD);//Set COM/Row Scan Direction   0xc0上下反置 0xc8正常
	OLED_WR_Byte(0xA6,OLED_CMD);//--set normal display
	OLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)
	OLED_WR_Byte(0x3f,OLED_CMD);//--1/64 duty
	OLED_WR_Byte(0xD3,OLED_CMD);//-set display offset	Shift Mapping RAM Counter (0x00~0x3F)
	OLED_WR_Byte(0x00,OLED_CMD);//-not offset
	OLED_WR_Byte(0xd5,OLED_CMD);//--set display clock divide ratio/oscillator frequency
	OLED_WR_Byte(0x80,OLED_CMD);//--set divide ratio, Set Clock as 100 Frames/Sec
	OLED_WR_Byte(0xD9,OLED_CMD);//--set pre-charge period
	OLED_WR_Byte(0xF1,OLED_CMD);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
	OLED_WR_Byte(0xDA,OLED_CMD);//--set com pins hardware configuration
	OLED_WR_Byte(0x12,OLED_CMD);
	OLED_WR_Byte(0xDB,OLED_CMD);//--set vcomh
	OLED_WR_Byte(0x40,OLED_CMD);//Set VCOM Deselect Level
	OLED_WR_Byte(0x20,OLED_CMD);//-Set Page Addressing Mode (0x00/0x01/0x02)
	OLED_WR_Byte(0x02,OLED_CMD);//
	OLED_WR_Byte(0x8D,OLED_CMD);//--set Charge Pump enable/disable
	OLED_WR_Byte(0x14,OLED_CMD);//--set(0x10) disable
	OLED_WR_Byte(0xA4,OLED_CMD);// Disable Entire Display On (0xa4/0xa5)
	OLED_WR_Byte(0xA6,OLED_CMD);// Disable Inverse Display On (0xa6/a7) 
	OLED_WR_Byte(0xAF,OLED_CMD);//--turn on oled panel
	
	OLED_WR_Byte(0xAF,OLED_CMD); /*display ON*/ 
	OLED_Clear();
	OLED_Set_Pos(0,0); 	
}  
//
void OLED_SCLK_Clr()//CLK
{
    OLED_SCLK=0;
}
///
void OLED_SCLK_Set()
{
   OLED_SCLK=1;
}
//
void OLED_SDIN_Clr()//DIN
{
	OLED_SDIN=0;
}

void OLED_SDIN_Set()
{
  OLED_SDIN=1;
}
//
void OLED_RST_Clr()//RES
{
	OLED_RST=0;
}
/
void OLED_RST_Set()
{
	OLED_RST=1;
}
///
void OLED_DC_Clr()//DC
{
  OLED_DC=0;
}
/
void OLED_DC_Set()
{
	OLED_DC=1;
}
///
void OLED_CS_Clr()//CS
{
    OLED_CS=0;
}
///
void OLED_CS_Set()
{
    OLED_CS=1;
}



//
void OLED_ShowFloatii(u8 x,u8 y,float num,u8 ii)
{
	  u8 i,j,mm;
	  float mmd;
	  i=x*8;//横轴每8个像素点,移位一个数字;
	  j=y;//纵轴,每个换到新的行
	  mm=8;//
	  mmd=0.125;//等于1/8=0.125
	 
    switch(ii)
		{
		
			case 43://1234.456
				OLED_ShowNum(i,j,(int)(num/1000)%10,1,12); //
				OLED_ShowNum(i+mm,j,(int)(num/100)%10,1,12);	//i+8
				OLED_ShowNum(i+2*mm,j,(int)(num/10)%10,1,12);//i+16
			 	OLED_ShowNum(i+3*mm,j,(int)(num)%10,1,12);//i+16
			//OLED_ShowString((i+3*mm)*mmd,j,".");//i+24
			  OLED_ShowString(i+4*mm,j,".");//i+24
				OLED_ShowNum(i+5*mm,j,(int)(num*10)%10,1,12);//i+32
				OLED_ShowNum(i+6*mm,j,(int)(num*100)%10,1,12);	
				OLED_ShowNum(i+7*mm,j,(int)(num*1000)%10,1,12);	
				break;
			case 42://1234.45
				OLED_ShowNum(i,j,(int)(num/1000)%10,1,12); //
				OLED_ShowNum(i+mm,j,(int)(num/100)%10,1,12);	//i+8
				OLED_ShowNum(i+2*mm,j,(int)(num/10)%10,1,12);//i+16
			 	OLED_ShowNum(i+3*mm,j,(int)(num)%10,1,12);//i+16
			//OLED_ShowString((i+3*mm)*mmd,j,".");//i+24
			  OLED_ShowString(i+4*mm,j,".");//i+24
				OLED_ShowNum(i+5*mm,j,(int)(num*10)%10,1,12);//i+32
				OLED_ShowNum(i+6*mm,j,(int)(num*100)%10,1,12);	
				break;
			
			case 33://123.456
				OLED_ShowNum(i,j,(int)(num/100)%10,1,12); //
				OLED_ShowNum(i+mm,j,(int)(num/10)%10,1,12);	//i+8
				OLED_ShowNum(i+2*mm,j,(int)(num*1)%10,1,12);//i+16
			//OLED_ShowString((i+3*mm)*mmd,j,".");//i+24
			  OLED_ShowString(i+3*mm,j,".");//i+24
				OLED_ShowNum(i+4*mm,j,(int)(num*100)%10,1,12);//i+32
				OLED_ShowNum(i+5*mm,j,(int)(num*100)%10,1,12);	
				OLED_ShowNum(i+6*mm,j,(int)(num*1000)%10,1,12);	
				break;
			case 32://123.45*100=12345            1,5
				//1---12345/10000  2---12345/1000=12  3---12345/100=123
			//4---12345/10=1234  5---12345%10
				OLED_ShowNum(i,j,(int)(num/100)%10,1,12); //
				OLED_ShowNum(i+mm,j,(int)(num/10)%10,1,12);		//
				OLED_ShowNum(i+2*mm,j,(int)(num*10)%10,1,12);		//
				//OLED_ShowString((i+3*mm)*mmd,j,".");//
		  	OLED_ShowString(i+3*mm,j,".");//
				OLED_ShowNum(i+4*mm,j,(int)(num*10)%10,1,12);	
				OLED_ShowNum(i+5*mm,j,(int)(num*100)%10,1,12);	
				break;
			case 31:
				//123.4====1234
				OLED_ShowNum(i,j,(int)(num/100)%10,1,12); //
				OLED_ShowNum(i+mm,j,(int)(num/10)%10,1,12);		//
				OLED_ShowNum(i+2*mm,j,(int)(num*1)%10,1,12);		//
			//	OLED_ShowString((i+3*mm)*mmd,j,".");//
		   	OLED_ShowString(i+3*mm,j,".");
				OLED_ShowNum(i+4*mm,j,(int)(num*10)%10,1,12);		
				break;
			case 23:
				//12.345===12345
				OLED_ShowNum(i,j,(int)(num/10)%10,1,12); //
				OLED_ShowNum(i+mm,j,(int)(num*1)%10,1,12);		//
			//	OLED_ShowString((i+2*mm)*mmd,j,".");//
				OLED_ShowString(i+2*mm,j,".");
				OLED_ShowNum(i+3*mm,j,(int)(num*10)%10,1,12);//
				OLED_ShowNum(i+4*mm,j,(int)(num*100)%10,1,12);	
				OLED_ShowNum(i+5*mm,j,(int)(num*1000)%10,1,12);
				break;
			case 22:
				//12.34---1234--
				OLED_ShowNum(i,j,(int)(num/10)%10,1,12);		//
				OLED_ShowNum(i+mm,j,(int)(num)%10,1,12);//
   		//	OLED_ShowString((i+2*mm)*mmd,j,".");//
			  OLED_ShowString(i+2*mm,j,".");
				OLED_ShowNum(i+3*mm,j,(int)(num*10)%10,1,12);	
				OLED_ShowNum(i+4*mm,j,(int)(num*100)%10,1,12);
				break;
			case 21:
				//12.3---123--
				OLED_ShowNum(i,j,(int)(num/10)%10,1,12);//
				OLED_ShowNum(i+mm,j,(int)(num)%10,1,12);	
			  //OLED_ShowString((i+2*mm)*mmd,j,".");//	
			  OLED_ShowString(i+2*mm,j,".");
				OLED_ShowNum(i+3*mm,j,(int)(num*10)%10,1,12);
				break;
			case 13:
				//1.234===1234
				OLED_ShowNum(i,j,(int)(num)%10,1,12);		//
   		//	OLED_ShowString((i+mm)*mmd,j,".");//	
			  OLED_ShowString(i+2*mm,j,".");
			  OLED_ShowNum(i+2*mm,j,(int)(num*10)%10,1,12);//
				OLED_ShowNum(i+3*mm,j,(int)(num*100)%10,1,12);	
				OLED_ShowNum(i+4*mm,j,(int)(num*1000)%10,1,12);
				break;
			case 12:
				//1.23===123
			  OLED_ShowNum(i,j,(int)(num)%10,1,12);//
			 // OLED_ShowString((i+mm)*mmd,j,".");//	
			  OLED_ShowString(i+mm,j,".");
				OLED_ShowNum(i+2*mm,j,(int)(num*10)%10,1,12);	
				OLED_ShowNum(i+3*mm,j,(int)(num*100)%10,1,12);
				break;
			case 11:
				//1.2===12
				OLED_ShowNum(i,j,(int)(num*10/10)%10,1,12);
   			//OLED_ShowString((i+mm)*mmd,j,".");//	
			   OLED_ShowString(i+mm,j,".");
				OLED_ShowNum(i+2*mm,j,(int)(num*10)%10,1,12);
				break;
			default :break;
			
		}
}

//
void delay_tmsOLED(unsigned int ms0)		//@11.0592MHz--11-190-766us;11-195--785us;20--x--1000
{                                    //
	unsigned char i, j;
	unsigned int tms;
	for(tms=ms0;tms>0;tms--)
		for(i=20;i>0;i--)
			for(j=136;j>0;j--);
}
/
void delay4us_tOLED(int us)		//@11.0592MHz---4us
{
	int i;
	for(i=us;i>0;i--);
}

key44,c

#include <key44.h>

/*******************************************************************************
* 函 数 名         : KeyScan
* 函数功能		   : 检测有按键按下并读取键值
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/


void KeyScan()
{
	char a = 0;
// 	int KeyValue44=0;
	GPIO_KEY=0x0f;
	P1M1=0x00;
	P1M0=0x00;
	
	if(GPIO_KEY!=0x0f)//读取按键是否按下
	{Delay10ms(1);
		if(GPIO_KEY!=0x0f)//再次检测键盘是否按下
		{
			
			//测试列
				P1M1=0x00;
	      P1M0=0x01;
			GPIO_KEY=0X0F;
			P1M1=0x00;
	      P1M0=0x00;
			switch(GPIO_KEY)
			{
				case(0X07):	KeyValue=0;break;
				case(0X0b):	KeyValue=4;break;
				case(0X0d): KeyValue=8;break;
				case(0X0e):	KeyValue=12;break;
			}
			//测试行
			P1M1=0x00;
	      P1M0=0x01;
			GPIO_KEY=0XF0;
	
			P1M1=0x00;
	      P1M0=0x00;
			switch(GPIO_KEY)
			{
				case(0X70):	KeyValue=KeyValue+3;break;
				case(0Xb0):	KeyValue=KeyValue+2;break;
				case(0Xd0): KeyValue=KeyValue+1;break;
				case(0Xe0):	KeyValue=KeyValue;break;
			}
			while((a<20) && (GPIO_KEY!=0xf0))	 //检测按键松手检测
			{
				Delay10ms(2);
				a++;
			}
		}
	}
// 	return KeyValue44;
}



unsigned char  KeyScan0()
{
 	unsigned char key=0xff;     // 无键按下时,key=0xff;
	unsigned char scancode,recode,tmp;		   // scancode——扫描码,recode——接收码
	P0M0=0x00;
	P0M1=0x00;
	GPIO_KEY=0x0f;								   // 发全0扫描码判断有无任意键按下
	GPIO_KEY=0x0f;								   // 延时
		Delay10ms(1);				
	if(GPIO_KEY!=0x0f)							   // 有键按下
	{										  
		Delay10ms(2);					   // 延时去抖动
		if(GPIO_KEY!=0x0f)					       // 再次判断确认是否键按下
		{
		 	scancode=0xef;					   // 逐列扫描初值
			while((scancode&0xf0)!=0xf0)	   // 扫描码1110 1111最多左移3次就够用了
			{
			 	GPIO_KEY=scancode;				   // 输出扫描码,逐列扫描
				if((GPIO_KEY&0x0f)!=0x0f)			   // 本列有键按下
				{								  
				 	recode=GPIO_KEY|0xf0;	           // 高4位无效,保留低4位
		            while((GPIO_KEY&0x0f)!=0x0f);    // 等待按键松开     
					tmp=(~scancode)+(~recode); // 按位取反目的是让按键码从小到大规律变化
					break;					   // 返回键码 = 扫描码(高4位) + 接收码(低4位)
				}
				else
				scancode=(scancode<<1)|0x01;   // 行扫描码左移1位
			}
		}
	}
	switch (tmp)		        
	{
		case 0x18:key=0;break;	 // 第1列
		case 0x14:key=4;break;
		case 0x12:key=8;break;
		case 0x11:key=12;break;

		case 0x28:key=1;break;	 // 第2列
		case 0x24:key=5;break;
		case 0x22:key=9;break;
		case 0x21:key=13;break;

		case 0x48:key=2;break;	 // 第3列
		case 0x44:key=6;break;
		case 0x42:key=10;break;
		case 0x41:key=14;break;

		case 0x88:key=3;break;	 // 第4列
		case 0x84:key=7;break;
		case 0x82:key=11;break;
		case 0x81:key=15;break;
	}
	return(key);
}  
/*******************************************************************************
* 函 数 名         : Delay10ms
* 函数功能		   : 延时函数,延时10ms
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/

void Delay10ms(unsigned int c)   //误差 0us
{
    unsigned char a, b;

	//--c已经在传递过来的时候已经赋值了,所以在for语句第一句就不用赋值了--//
    for (;c>0;c--)
	{
		for (b=144;b>0;b--)
		{
			for (a=157;a>0;a--);
		}          
	}       
}

key44.h

#include <stc8a8k.h>
//--定义使用的IO口--//	
#define GPIO_KEY P1
extern unsigned char KeyValue;
//--声明全局函数--//

void  KeyScan();
void Delay10ms(unsigned int c);   //误差 0us

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值