如何基于51单片机利用LCD12864编写数字频率计并连接外部设备显示波形

如何基于51单片机利用LCD12864编写数字频率计并连接外部设备显示波形

  • 建议你看下这篇博客👉 :关于单片机控制用字库显示LCD12864汉字
  • 除此之外, 这篇博客: 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]);
    		}
    	}				
    }
    
  • 您还可以看一下 朱有鹏老师的巫妖王51单片机开发板配套视频课程课程中的 LCD12864工业液晶屏小节, 巩固相关知识点