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

📄 5d_keys.c

📁 基于C8051F020的五维方向键
💻 C
字号:


#include <c8051f020.h>                    // 特殊功能寄存器(包含位)声明
#include <stdio.h>

//------------------------------------------------------------------------------------
// 定义16位SFR
//------------------------------------------------------------------------------------
sfr16 DP       = 0x82;                    // data pointer
sfr16 TMR3RL   = 0x92;                    // Timer3 reload value
sfr16 TMR3     = 0x94;                    // Timer3 counter
sfr16 ADC0     = 0xbe;                    // ADC0 数据
sfr16 ADC0GT   = 0xc4;                    // ADC0 greater than window
sfr16 ADC0LT   = 0xc6;                    // ADC0 less than window
sfr16 RCAP2    = 0xca;                    // Timer2 capture/reload
sfr16 T2       = 0xcc;                    // Timer2
sfr16 RCAP4    = 0xe4;                    // Timer4 capture/reload
sfr16 T4       = 0xf4;                    // Timer4
sfr16 DAC0     = 0xd2;                    // DAC0  数据
sfr16 DAC1     = 0xd5;                    // DAC1  数据
//char display[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
char disp_lcd[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46};
//------------------------------------------------------------------------------------
// 定义全局常量和变量
//------------------------------------------------------------------------------------

#define SYSCLK 22118400                     // 定义系统时钟(Hz)
#define uint8   unsigned char 
#define uint16   unsigned int
#define    KEY   P6
sfr Lcd_port =0x85;     //LCd数据端口  P5                        
sfr Lcd_ctr =0x84;      //LCd控制端口  P4
/*开漏 LCD_RS=P4.5    开漏 LCD_RW=P4.6     开漏 LCD_E=P4.7*/

uint8 code  Welcome0[64]  ={ "01234567        "
                             "                "
                             "                "
							 "                "};
uint8 Ac;
uint8 RamData;
//------------------------------------------------------------------------------------
// 自定义函数
//------------------------------------------------------------------------------------
		    //延时子程序
				//读ADC
//void System_Init(void);             //系统初始化
//uint8 keyscan0();                     //键盘扫描
//--------gmyul768op7 8op----------------------------------------------------------------------------

void delay ()
  {
   uint8 k;
   for(k=0;k<200;k++);
}

void Delay(uint16 time)	   //延时程序   ========不分通道========
{
  	uint16 i,t;
	for(i=0;i<time;i++){for(t=0;t<300;t++) ;}
} 

////////////////////////////////////////////////////////////////////////////////LCD程序
void Wait(uint8 dly)
{for(;dly>0;dly--);}  

uint8 Lcd_Busy( void )
{
    uint8 Lcd1;
  	Lcd_ctr=0x40;		   //RS=0,RW=1 
	Wait(50);
        Lcd_ctr=0xc0;
	Wait(50);
	Lcd_port=0xff;
	Lcd1=Lcd_port;                              //从LCD读状态
	Lcd_ctr=0x40;	                                //读数据,操作允许脉冲信号
	if(( Lcd1 & 0x80 )==0) return 0 ;           //LCD不忙,返回0
	return 1;			                       //LCD忙,返回1
}

void LcdWriteCommand( uint8 comm)
{
   while(Lcd_Busy()==1);                   //等LCD空闲
	Lcd_ctr=0x00; 			    				//Lcd_RS=0,Lcd_RW=0
	Wait(50);
	Lcd_ctr=0x80;
	Wait(50);
	Lcd_port=comm;   		   				 // 送控制字到LCD
	Wait(50);
	Lcd_ctr=0x00;	       	            		// 下降沿打入数据,操作允许脉冲信号
	Wait(50);
}

void Lcd_Ram_Write(uint8 Lcd_d)
{
	while (Lcd_Busy()==1);			        // 检测LCD忙信号,等LCD不忙
	Lcd_ctr=0xa0; 		                        //RS=1,RW=0  数据写入LCD
	Wait(50);
	Lcd_port=Lcd_d;                         //向LCD写数据
	Lcd_ctr=0x20;
	Wait(50);                             // 下降沿打入数据
}

void Lcd_reset()
{
	LcdWriteCommand(0x30);                    //写命令字0x38,8位数据宽度
	delay();
	LcdWriteCommand(0x01);                    //写命令字0x01,清显示
	delay();
	LcdWriteCommand(0x06);                    //输入方式设定  AC自动加1 
	delay();
	LcdWriteCommand(0x0c);                    //开显示,关 光标+闪动  D2,D1(0=无光标),D0(1=闪动)
	delay();
}

void disp_flash(uint8 t)
{
		uint8 j,m;	
		LcdWriteCommand(0x02);                  //***************************
		Delay(1500);
		LcdWriteCommand(0x0f);                  //闪烁
		Delay(1500);
              if(t == 0 )
			    {
			      for(j=0;j<4;j++){
	             	 for(m=0;m<15;m++)  Lcd_Ram_Write(Welcome0[j*16+m]);}
				     //for(m=0;m<16;m++) Lcd_Ram_Write(0x03);}
			    }	
}

uint8 Ac_Read()
{
  	Lcd_ctr=0x40;		   //RS=0,RW=1 
	Wait(50);
    Lcd_ctr=0xc0;
	Wait(50);
	Lcd_port=0xff;
	Ac=Lcd_port;                              //从LCD读状态
	Lcd_ctr=0x40;	                                //读数据,操作允许脉冲信号
	Ac=Ac&0x7f;
	Ac=Ac+0x80;
    return Ac;
}

void Cursor_Move(uint8 n)
{   uint8 flag;
    flag=0;
    Ac_Read();
    if(n==10)              //上移
	  {
	       if(Ac >=0x80&Ac <= 0x87)
		      {
		          Ac = Ac+0x18;
                  LcdWriteCommand(Ac);                    
          	      delay();
			   }
		   else if(Ac >=0x90&Ac <= 0x97)
		      {
		          Ac = Ac-0x10;
                  LcdWriteCommand(Ac);                    
          	      delay();
			   }
		   else if(Ac >=0x88&Ac <= 0x8f)
		      {
		          Ac = Ac+0x08;
                  LcdWriteCommand(Ac);                    
          	      delay();
			   }
           else 
		      {
		          Ac = Ac-0x10;
                  LcdWriteCommand(Ac);                    
          	      delay();
			   }
   	  }

	if(n==4)                //左移
	  { 
	       if(Ac ==0x80)
		       {
			       Ac =Ac+0x1f;
                   LcdWriteCommand(Ac);                    
          	       delay();
				   flag=1;
			   }  
		    if(Ac ==0x90)
		       {
			       Ac =Ac-0x09;
                   LcdWriteCommand(Ac);                    
          	       delay();
				   flag=1;
			   }
  		    if(Ac ==0x88)
		       {
			       Ac =Ac+0x0f;
                   LcdWriteCommand(Ac);                    
          	       delay();
				   flag=1;
			   }  
			if(Ac ==0x98)
		       {
			       Ac =Ac-0x09;
                   LcdWriteCommand(Ac);                    
          	       delay();
				   flag=1;
			   }  
            if(flag==0)
		       {
			       LcdWriteCommand(0x10);                    
                   delay();
				}
	  }
	if(n==14)                 //下移
	  {
	       if(Ac >=0x80&Ac <= 0x87)
		      {
		          Ac = Ac+0x10;
                  LcdWriteCommand(Ac);                    
          	      delay();
			   }
		   else if(Ac >=0x90&Ac <= 0x97)
		      {
		          Ac = Ac-0x08;
                  LcdWriteCommand(Ac);                    
          	      delay();
			   }
		   else if(Ac >=0x88&Ac <= 0x8f)
		      {
		          Ac = Ac+0x10;
                  LcdWriteCommand(Ac);                    
          	      delay();
			   }
           else 
		      {
		          Ac = Ac-0x18;
                  LcdWriteCommand(Ac);                    
          	      delay();
			   }
	  }
	if(n==15)               //右移
	  { 
	       if(Ac==0x87)
		      {
			      Ac = Ac+0x09;
                  LcdWriteCommand(Ac);     
                  delay();
				  flag=1;
			  }
		   if(Ac==0x97)
		      {
			      Ac = Ac-0x0f;
                  LcdWriteCommand(Ac);                    
          	      delay();
				  flag=1;
			  }
		   if(Ac==0x8f)
		      {
			      Ac = Ac+0x09;
                  LcdWriteCommand(Ac);                    
          	      delay();
				  flag=1;
			  }
		   if(Ac==0x9f)
		      {
			      Ac = Ac-0x1f;
                  LcdWriteCommand(Ac);                    
          	      delay();
				  flag=1;
			  }
		  if(flag==0)
	 	      {
	  	          LcdWriteCommand(0x14);                    
                  delay();
		      }
	  }

	if(n==12)                             //确认    
	  {
  	    Ac=Ac+0x01;
        LcdWriteCommand(Ac);                    
        delay();
       }


	   
    if(n!=10&n!=11&n!=12&n!=13&n!=14&n!=15&n!=16)                       //写数据
       {
         //if()
          //{ }
          Lcd_Ram_Write(disp_lcd[n]);
		  delay();
	   }
}


uint8 Lcd_ReadRam(void)
{
     //uint8  Ac1;
     //Ac1 = Ac_Read();
    // =Lcd_ctr;
     Lcd_ctr=0xe0;
     Wait(50);
    // if()
       // {
             RamData=Lcd_port;
             Wait(50);
        // }
     RamData=Lcd_port;
     Lcd_ctr=0x60;
     //Wait(50);
	 return RamData;

}

//////////////////////////////////////////////////////////////////////////////

/**************************************************************************
4*4矩阵键盘扫描,返回值为按键对应的数值(0~F),若无键则返回0x10,输入时无反相器
**************************************************************************/
unsigned char keyscan0()             //4*4矩阵键盘扫描返回按键对应的数值
{
  unsigned char i,k,out,in=1,j;
     KEY=0xff;
     KEY=0x0f;
	 i=KEY;
	 j=i=i&0x0f;
    if(i!=0x0f)
  {	 delay();
     if(i==j)
   {  out=0xef;
     for(i=0;i<4;i++)
	 { KEY=0xff;
	   KEY=out;
	   k=KEY;
	   k=k&0x0f;
	  do{ j=KEY;
	      j=j&0x0f;
	   } while(i==k);
     if(i==0){
        switch(k)
	{ case 0x0e :  return 3;break;
      case 0x0d :  return 7;break;
      case 0x0b :  return 11;break;
      case 0x07 :  return 15;break;
	 }  }
    else if(i==1){
	   switch(k)
	{ case 0x0e :  return 0;break;
      case 0x0d :  return 4;break;
      case 0x0b :  return 8;break;
      case 0x07 :  return 12;break;
	 }}
	 else if(i==2){
	   switch(k)
	{ case 0x0e :  return 2;break;
      case 0x0d :  return 6;break;
      case 0x0b :  return 10;break;
      case 0x07 :  return 14;break;
	 }  }
	else if(i==3){
	   switch(k)
	{ case 0x0e :  return 1;break;
      case 0x0d :  return 5;break;
      case 0x0b :  return 9;break;
      case 0x07 :  return 13;break;
	 }}
      out=out<<1;
	  out=out+0x01;
	 }
   
  }
 }
   else return 16;	 
}


/////////////////////////////////////////////////////////////////////////////
void System_Init(void)	  

{
 uint8  y;

	OSCXCN=0xe7;		//使能外晶体 >11.0592MHz
	Delay(200);
	y=0x00;
	while(y!=0x80)	    //等外晶体稳定
	  {
	  	y=OSCXCN;
	   	y=y&0x80;
	  }

	OSCICN=0x8c;       //切换到外晶体 */               //  

    P0MDOUT = 0xff;             //配置P0口 	  推拉输出
   	P1MDOUT = 0x00;         	//配置P1口 	  推拉输出
   	P2MDOUT = 0xff;         	//配置P2口 	  推拉输出
   	P3MDOUT = 0xff;        	    //配置P3口 	  推拉输出
   	P74OUT  = 0x00;
	XBR0 = 0x00;                 // XBAR0 串口连接到端口 P0.0=TXD  P0.1=RXD
	XBR1 = 0x00;	            // XBAR1
	XBR2 = 0x40;	           // 交叉开关使能(D6=1)


	EA=0;
  	WDTCN = 0xde;              //配置WT--看门狗定时器
  	WDTCN = 0xad;   

	P1=0x7f;
    Delay(1000);
    P1=0xff;

    Lcd_port = 0xff; 
    while(Lcd_Busy()==1);       // 检测LCD忙信号,等LCD不忙
	Lcd_reset();
    
}	     

/////////////////////////////////////////////////////////////////////////////////////////////////////////
void main (void)
{   
    uint8 m;
	//uint8 Data;
	System_Init();
	disp_flash(0);
    LcdWriteCommand(0x02);                    
    delay();
 	while(1)
  	 { 
       m=keyscan0();
       Cursor_Move(m);
       Delay(1000);
     }
	
}

⌨️ 快捷键说明

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