51单片机 LCD12864 矩阵键盘

软件部分

#include"reg51.h"
/********************************************************************************************************************************* 实验名称:普中单片机12864的使用 实验效果:倒计时100显示 *****************************************************************************************************************************/

/********************************************************************************************************** 端口定义 ************************************************************************************************************/

sbit RS=P2^6; //命令/数据选择 
sbit RW=P2^5;  //读写口 
sbit  E=P2^7;	  //锁存控制 
sbit RES = P2^0; 
sbit PSB = P2^2;

/********************************************************************************************************** 函数声明 ************************************************************************************************************/

void InitLCD(void);	

void Display_Char(unsigned char x,unsigned char y,unsigned char  Char);
void Display_String(unsigned char x,unsigned char y,unsigned char  *s);
void Display_UnsignedInt(unsigned char x,
                          unsigned char y,
                          unsigned int Number,
						  unsigned  char Count); 
void Display_SignedInt(unsigned char x,
                       unsigned char y,
                       signed int Number,
                       unsigned char Count)	;
void Display_Float(unsigned char x,
                    unsigned char y,
                    float Number,
                    unsigned char Count1,
                    unsigned char Count2);
					
void DELAY_nUS(unsigned int Time);
void DELAY_nMS(unsigned int time);
void delay(unsigned int time);
 
#define GPIO_KEY P1

unsigned char KeyValue;
//用来存放读取到的键值
unsigned char KeyState;
//用来存放按键状态
unsigned char PuZh[]=" MCU Science ";
unsigned char dat[]="0123456789ABCDEF"; 
/********************************************************************** 函数主体部分 ***************************************************************************/
void DELAY_nUS(unsigned int Time)
{
	while(--Time);
}
void DELAY_nMS(unsigned int time)
{
  unsigned int  i,j;             
  for(i=0;i<time;i++)    
     for(j=0;j<939;j++); 
}

void delay(unsigned int time)              //int型数据为16位,所以最大值为65535 
 {										   //0.1ms
   unsigned int  i,j;                  //定义变量i,j,用于循环语句 
   for(i=0;i<time;i++)         //for循环,循环50*time次
     for(j=0;j<50;j++);       //for循环,循环50次
 }

 /******************************************************************************* * 函 数 名 : Delay10ms * 函数功能 : 延时函数,延时10ms * 输 入 : 无 * 输 出 : 无 *******************************************************************************/
void Delay10ms(void)   //误差 0us
{
    unsigned char a,b,c;
    for(c=1;c>0;c--)
        for(b=38;b>0;b--)
            for(a=130;a>0;a--);
}


/******************************************************************************* * 函 数 名 : checkbusy() * 函数功能 : 查忙 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/
void checkbusy(void)           
{
   RS=0;                   
   RW=1;                  
   E=1;                    
   while((P0&0x80)==0x80); 
   E=0;                   
}
/******************************************************************************* * 函 数 名 : LcdWriteCom * 函数功能 : 向LCD写入一个字节的数据 * 输 入 : dat * 输 出 : 无 *******************************************************************************/	
void LcdWriteCom(unsigned char cmdcode) //写入命令
{
   checkbusy();           
   RS=0;                   
   RW=0;                   
   E=1;                  
   P0=cmdcode;            
   delay(10);               
   E=0;                    
}
/******************************************************************************* * 函 数 名 : LcdWriteData * 函数功能 : 向LCD写入一个字节的数据 * 输 入 : dat * 输 出 : 无 *******************************************************************************/	
void LcdWriteData(unsigned char dispdata)
{
   checkbusy();           
   RS=1;                  
   RW=0;                  
   E=1;                   
   P0=dispdata;           
   delay(10);              
   E=0;                    
}
/******************************************************************************* * 函 数 名 : InitLCD() * 函数功能 : 初始化LCD屏 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/	
void InitLCD(void)
   {
   PSB=1;            
   RES=0;
   delay(10);         
   RES=1;             
   LcdWriteCom(0x30);       
   LcdWriteCom(0x0c);       
   LcdWriteCom(0x01);       
   LcdWriteCom(0x06);       	
}  
/******************************************************************************* * 函 数 名 : Display_Char() * 函数功能 : 显示字符 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/
void Display_Char(unsigned char x,unsigned char y,unsigned char  Char)   
{                                    
  switch(y)                              
     { 
	  case 0: LcdWriteCom(0x80+x);break;  
	  case 1: LcdWriteCom(0x90+x);break;   
	  case 2: LcdWriteCom(0x88+x);break;    
	  case 3: LcdWriteCom(0x98+x);break;  
      default:break;
	 }
	 LcdWriteData(Char);


}
/******************************************************************************* * 函 数 名 : Display_String() * 函数功能 : 显示字符串 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/
void Display_String(unsigned char x,unsigned char y,unsigned char  *s)   
{                                    
 switch(y)                                     
     { 
	  case 0: LcdWriteCom(0x80+x);break;   
	  case 1: LcdWriteCom(0x90+x);break;    
	  case 2: LcdWriteCom(0x88+x);break;   
	  case 3: LcdWriteCom(0x98+x);break;    
      default:break;
	 }
   while(*s>0)                        
     {  
      LcdWriteData(*s);                     
      delay(10);                     
      s++;                         
     }
}
/******************************************************************************* * 函 数 名 : Display_Unsignedint() * 函数功能 : 显示无符号整形 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/
void Display_UnsignedInt(unsigned char x,unsigned char y,unsigned int Number,unsigned char Count)
{
	unsigned char NumbArray[6]={0};    
   
    NumbArray[0]=(Number/10000)%10+0x30; 
    NumbArray[1]=(Number/1000) %10+0x30;
    NumbArray[2]=(Number/100)  %10+0x30;
    NumbArray[3]=(Number/10)   %10+0x30;
    NumbArray[4]=(Number/1)    %10+0x30; 
    NumbArray[5]= 0;
 
    Display_String(x,y,&NumbArray[5-Count]);
}

/******************************************************************************* * 函 数 名 : Display_Signedint() * 函数功能 : 显示有符号整形 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/
void Display_SignedInt(unsigned char x,
                       unsigned char y,
                       signed int Number,
                       unsigned char Count)
{
    unsigned char NumberArray[7]={0};    
    signed int Number_Temp;
    
    Number_Temp = Number;
    if(Number_Temp<0)
    {
        Number_Temp = 0 - Number_Temp;
    }

    NumberArray[0]='+'; 
    NumberArray[1]=(Number_Temp/10000)%10+0x30; 
    NumberArray[2]=(Number_Temp/1000) %10+0x30;
    NumberArray[3]=(Number_Temp/100)  %10+0x30;
    NumberArray[4]=(Number_Temp/10)   %10+0x30;
    NumberArray[5]=(Number_Temp/1)    %10+0x30;
    NumberArray[6]=0;
    
    if(Number>0)
    {
        NumberArray[5-Count] = '+';
    }
    else
    {
        NumberArray[5-Count] = '-';
    }
    
    Display_String(x, y, &NumberArray[5-Count]);
}


/******************************************************************************* * 函 数 名 : Display_Float() * 函数功能 : 显示浮点数 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/
void Display_Float(unsigned char x,
                    unsigned char y,
                    float Number,
                    unsigned char Count1,
                    unsigned char Count2)
{
    unsigned char NumberArray[11]={0};         

    unsigned int  Number_Integer = 0;      
    unsigned int  Number_Decimal = 0;       

    float Number_Temp;
    
    Number_Temp = Number;
    
    if(Number_Temp < 0)
    {
        Number_Temp= 0 - Number_Temp;
    }

  
    Number_Integer = (unsigned int)(Number_Temp);                                        
    Number_Decimal = (unsigned short)((Number_Temp - Number_Integer + 0.0005) * 1e3);     


    NumberArray[ 0] = '+';
    NumberArray[ 1] = Number_Integer/10000 % 10 + 0x30;
    NumberArray[ 2] = Number_Integer/ 1000 % 10 + 0x30;
    NumberArray[ 3] = Number_Integer/  100 % 10 + 0x30;
    NumberArray[ 4] = Number_Integer/   10 % 10 + 0x30;
    NumberArray[ 5] = Number_Integer/    1 % 10 + 0x30;
	NumberArray[ 6] ='.';
    NumberArray[ 7] = Number_Decimal/  100 % 10 + 0x30;
    NumberArray[ 8] = Number_Decimal/   10 % 10 + 0x30;
    NumberArray[ 9] = Number_Decimal/    1 % 10 + 0x30;
    NumberArray[10] = 0;
    
    if(Number>0)
    {
        NumberArray[5-Count1] = '+';
    }
    else
    {
        NumberArray[5-Count1] = '-';
    }
    
    NumberArray[7+Count2] = 0; 
    Display_String(x, y, &NumberArray[5-Count1]);

}

/******************************************************************************* * 函 数 名 : KeyDown * 函数功能 : 检测有按键按下并读取键值 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/
void KeyDown(void)
{
	char a;
	GPIO_KEY=0x0f;
	if(GPIO_KEY!=0x0f)
	{
		Delay10ms();
		if(GPIO_KEY!=0x0f)
		{
			KeyState=1;
			//测试列
			GPIO_KEY=0X0F;
      		Delay10ms();
			switch(GPIO_KEY)
			{
				case(0X07):	KeyValue=0;break;
				case(0X0b):	KeyValue=1;break;
				case(0X0d): KeyValue=2;break;
				case(0X0e):	KeyValue=3;break;
				default:	KeyValue=17;	//检测出错回复17意思是把数码管全灭掉。
			}
			//测试行
			GPIO_KEY=0XF0;
			Delay10ms();
			switch(GPIO_KEY)
			{
				case(0X70):	KeyValue=KeyValue;break;
				case(0Xb0):	KeyValue=KeyValue+4;break;
				case(0Xd0): KeyValue=KeyValue+8;break;
				case(0Xe0):	KeyValue=KeyValue+12;break;
 			default:	KeyValue=17;
			}
			while((a<50)&&(GPIO_KEY!=0xf0))	 //检测按键松手检测
			{
				Delay10ms();
				a++;
			}
			a=0;
		}
	}
}


void main()
{

	unsigned char i;
	unsigned char temp;
	InitLCD();
	KeyState=0;
	for(i=0;i<16;i++)
	{
	// wcode(0x80);
		LcdWriteData(PuZh[i]);	
	}
	while(1)
	{
	  KeyDown();
		if(KeyState)
		{
			KeyState=0;
			LcdWriteCom(0x80+0x40);
		    LcdWriteData(dat[KeyValue]);
		}
	}				
}

参考资料

  1. STM32 固件库 矩阵键盘 https://blog.csdn.net/weixin_43599390/article/details/105181107
  2. 51单片机 LCD液晶显示模块使用
    https://blog.csdn.net/weixin_43599390/article/details/105058048
  3. 博客链接https://lemonhubs.github.io/