【51单片机】LCD1602显示字符串,时间、时间+按键校准、秒表计时的功能代码。

LCD1602显示字符和时间是最基本的实验,在综合前面所学知识并结合c语言程序设计,就可以通过独立按键,来对时间进行校准,计时等功能、或者通过矩阵键盘的按键进行输入,进而让LCD屏上显示的出我们想要的内容和效果。应实验要求,写了4个代码。

本实验采用的是12.000MHz晶振的51开发板.

8bf54d691c4a4ca080c60b810f1a66e8.png

LCD1602电路连线图

 代码1:(在LCD上显示“ Welcome to Baise University”->  (欢迎来到百色学院)  )

#include <REGX52.H>
typedef unsigned char uchar;
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_E=P2^7;
 char count=0,hour=23,minute=59,second=55;

void Delay(unsigned int xms)
{//延时函数
	uchar i, j;
	while(xms--){
		i = 2;
		j = 239;
		do{
			while (--j);
		} while (--i);
	}
}
void LCD_WriteCmd(uchar Command)
{//写命令函数
	LCD_RS=0;
	LCD_RW=0;
	P0=Command;
	LCD_E=1;
	Delay(1);
	LCD_E=0;
	Delay(1);
}
void LCD_WriteData(uchar Data)
{//写数据函数
	LCD_RS=1;
	LCD_RW=0;
	P0=Data;
	LCD_E=1;
	Delay(1);
	LCD_E=0;
	Delay(1);
}

void LCD_Init(void)
{//初始化
	LCD_WriteCmd(0x38);
	LCD_WriteCmd(0x0C);
	LCD_WriteCmd(0x06);
	LCD_WriteCmd(0x01);
}
void LCD_SetCursor(uchar Line,uchar Column)
{//设置显示的行数和列数
	 LCD_WriteCmd(Line==1?0x80+(Column-1):0xC0+(Column-1));
}

void LCD_ShowString(uchar Line,uchar Column,char *String)
{//在指定的行数和列数显示对应的字符串
	uchar i;
	LCD_SetCursor(Line,Column);
	for(i=0;String[i]!='\0';i++)
		LCD_WriteData(String[i]);	
}

void main(){ 
	LCD_Init();

	LCD_ShowString(1,1,"Welcome to Baise");		
    LCD_ShowString(2,1,"University!");		
    while(1);
}

bb0aaa7f46e340d6925107bb42042b9a.jpeg

显示:欢迎来到百色学院

 代码2:(LCD显示时间)

#include <REGX52.H>
typedef unsigned char uchar;
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_E=P2^7;
char hour=23,minute=59,second=55;//时间变量:时、分、秒
uchar T0_flag=0;
void Delay(unsigned int xms)
{//延时函数
	unsigned char i, j;
	while(xms--){
		i = 2;
		j = 239;
		do{
			while (--j);
		} while (--i);
	}
}
void LCD_WriteCmd(uchar Command)
{//写命令函数
	LCD_RS=0;
	LCD_RW=0;
	P0=Command;
	LCD_E=1;
	Delay(1);
	LCD_E=0;
	Delay(1);
}
void LCD_WriteData(uchar Data)
{//写数据函数
	LCD_RS=1;
	LCD_RW=0;
	P0=Data;
	LCD_E=1;
	Delay(1);
	LCD_E=0;
	Delay(1);
}

void LCD_Init(void)
{//初始化LCD1602
	LCD_WriteCmd(0x38);
	LCD_WriteCmd(0x0C);
	LCD_WriteCmd(0x06);
	LCD_WriteCmd(0x01);
}
void LCD_SetCursor(uchar Line,uchar Column)
{//选择显示的行和列:参数一代表行,参数二代表列
	 LCD_WriteCmd(Line==1?0x80+(Column-1):0xC0+(Column-1));
}

void LCD_ShowString(uchar Line,uchar Column,char *String)
{//选择要显示的字字符串,参数一代表行,参数二代表列,参数三要传一个字符串进来,或者字符型的指针
	unsigned char i;
	LCD_SetCursor(Line,Column);
	for(i=0;String[i]!='\0';i++)
		LCD_WriteData(String[i]);
}
void LCD_ShowTime(char h,char m,char s)
{//在lcd1602上面显示时间 ,用定时器1 
        LCD_ShowString(1,7,"Time");
        LCD_SetCursor(2,5);   
		LCD_WriteData(h/10+0x30);
        LCD_WriteData(h%10+0x30);
        LCD_WriteData(0x3a);
        LCD_WriteData(m/10+0x30);
        LCD_WriteData(m%10+0x30);
        LCD_WriteData(0x3a);
        LCD_WriteData(s/10+0x30);
        LCD_WriteData(s%10+0x30);             
}

void Timer0Init()		//50毫秒@12.000MHz
{
	TMOD &= 0xF0;		//设置定时器模式
	TMOD |= 0x01;		//设置定时器模式
	TL0 = 0xB0;		    //设置定时初值
	TH0 = 0x3C;		    //设置定时初值
	TF0 = 0;		    //清除TF0标志
	TR0 = 1;		    //定时器0开始计时
    ET0=1;              //打开小开关
	EA=1;               //打开总开关   
}


void main(){
    Timer0Init();
	LCD_Init();					
    while(1)
        LCD_ShowTime(hour,minute,second);      
}

void interrupt_T0()interrupt 1
{//定时器0中断函数
    TL0 = 0xB0;		
	TH0 = 0x3C;		
    T0_flag++;
    if(T0_flag==20){
        T0_flag=0;     
        second++;
        if(second==60){
            second=0;
            minute++;
            if(minute==60){
                minute=0;
                hour++;
                if(hour==24)
                    hour=0;               
           }
        }
    }
}
1627250ab80f4642a9c1e5ba8fb8cd6f.jpeg

时间显示效果图

 单纯的在LCD1602上面显示可变时间

注:如果觉得时间不准,很可能是晶振不同的问题,这里我的晶振时12MHZ的,如果晶振频率时11.0592MHZ的就要把代码中初始化和中断里面的TL1 = 0xB0;和TH1 = 0x3C;     改成TL1 ==0x00;   TH1 = 0x4C;

代码3:(显示时间+按键扫描)

#include <REGX52.H>
typedef unsigned char uchar;
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_E=P2^7;
 char T0_flag=0,hour=23,minute=59,second=55;

void Delay(unsigned int xms)
{//延时函数
	unsigned char i, j;
	while(xms--){
		i = 2;
		j = 239;
		do{
			while (--j);
		} while (--i);
	}
}
void LCD_WriteCmd(uchar Command)
{//写命令函数
	LCD_RS=0;
	LCD_RW=0;
	P0=Command;
	LCD_E=1;
	Delay(1);
	LCD_E=0;
	Delay(1);
}
void LCD_WriteData(uchar Data)
{//写数据函数
	LCD_RS=1;
	LCD_RW=0;
	P0=Data;
	LCD_E=1;
	Delay(1);
	LCD_E=0;
	Delay(1);
}

void LCD_Init(void)
{//初始化LCD1602
	LCD_WriteCmd(0x38);
	LCD_WriteCmd(0x0C);
	LCD_WriteCmd(0x06);
	LCD_WriteCmd(0x01);
}
void LCD_SetCursor(uchar Line,uchar Column)
{//选择显示的行和列:参数一代表行,参数二代表列
	 LCD_WriteCmd(Line==1?0x80+(Column-1):0xC0+(Column-1));
}

void LCD_ShowString(uchar Line,uchar Column,char *String)
{//选择要显示的字字符串,参数一代表行,参数二代表列,参数三要传一个字符串进来,或者字符型的指针
	unsigned char i;
	LCD_SetCursor(Line,Column);
	for(i=0;String[i]!='\0';i++)
		LCD_WriteData(String[i]);
	
}
void LCD_ShowTime(char h,char m,char s)
{//在lcd1602上面显示时间 ,用定时器1            
        LCD_SetCursor(2,5);   
		LCD_WriteData(h/10+0x30);
        LCD_WriteData(h%10+0x30);
        LCD_WriteData(0x3a);
        LCD_WriteData(m/10+0x30);
        LCD_WriteData(m%10+0x30);
        LCD_WriteData(0x3a);
        LCD_WriteData(s/10+0x30);
        LCD_WriteData(s%10+0x30);            
}

void key_scan(){
   static uchar flag=0;
    if(P3_1==0){
        Delay(20);
        while(P3_1==0);
        Delay(20);
        TR0=0;//关闭中断请求
        flag++;
        
        if(flag==4){
           flag=0;
            TR0=1;
            LCD_WriteCmd(0x01);
            }
    }
        
    if(flag!=0){
           
         LCD_ShowString(1,2,"Change Time");
        switch(flag){
            case 1:if(P3_0==0){ Delay(20);while(P3_0==0);Delay(20);hour++; if(hour>23) hour=0;}break;
            case 2:if(P3_0==0){ Delay(20);while(P3_0==0);Delay(20);minute++; if(minute>59) minute=0;}break;
            case 3:if(P3_0==0){ Delay(20);while(P3_0==0);Delay(20);second++; if(second>59) second=0;}break;
            default:break;
        }
        switch(flag){
            case 1:if(P3_2==0){ Delay(20);while(P3_2==0);Delay(20);hour--; if(hour<0) hour=23;}break;
            case 2:if(P3_2==0){ Delay(20);while(P3_2==0);Delay(20);minute--; if(minute<0) minute=59;}break;
            case 3:if(P3_2==0){ Delay(20);while(P3_2==0);Delay(20);second--; if(second<0) second=59;}break;
            default:break;
        }
    }else{
            
         LCD_ShowString(1,7,"Time");
    }
}
void Timer0Init()		//50毫秒@12.000MHz
{
	TMOD &= 0xF0;		//设置定时器模式
	TMOD |= 0x01;		//设置定时器模式
	TL0 = 0xB0;		    //设置定时初值
	TH0 = 0x3C;		    //设置定时初值
	TF0 = 0;		    //清除TF0标志
	TR0 = 1;		    //定时器0开始计时
    ET0=1;              //打开小开关
	EA=1;               //打开总开关   
}


void main(){
    Timer0Init();
	LCD_Init();					
    while(1){
        key_scan();
        LCD_ShowTime(hour,minute,second);  
    }
}

void interrupt_T0()interrupt 1
{//定时器0中断函数
    TL0 = 0xB0;		
	TH0 = 0x3C;		
    T0_flag++;
    if(T0_flag==20){
        T0_flag=0;     
        second++;
        if(second==60){
            second=0;
            minute++;
            if(minute==60){
                minute=0;
                hour++;
                if(hour==24)
                    hour=0;               
           }
        }
    }
}

67a45bf6f3a5414db6ac5802da99f60b.jpeg

按键更改时间 效果图

功能:通过独立按键进行时间的校准。

k1按一次暂停时钟运行,进入更改时档位,第二次进入更改分档位,第三次进入更改秒档位,第四次启动时钟
k2时/分/秒  数值加一
k3时/分/秒  数值减一

独立按键电路如下:

f5dacf41f5924a8592be6860bbdb4f89.png

独立按键电路连接图

 代码4:(显示时间+按键扫描+秒表计时)

#include <REGX52.H>
typedef unsigned char uchar;
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_E=P2^7;
char hour=23,minute=59,second=55;//时钟变量
char S=0,M=0,H=0;//秒表变量
uchar mode=0,T0_flag=0,T1_flag=0;

void Delay(unsigned int xms)
{//延时函数
	uchar i, j;
	while(xms--){
		i = 2;
		j = 239;
		do{
			while (--j);
		} while (--i);
	}
}
void LCD_WriteCmd(uchar Command)
{//写命令函数
	LCD_RS=0;
	LCD_RW=0;
	P0=Command;
	LCD_E=1;
	Delay(1);
	LCD_E=0;
	Delay(1);
}
void LCD_WriteData(uchar Data)
{//写数据函数
	LCD_RS=1;
	LCD_RW=0;
	P0=Data;
	LCD_E=1;
	Delay(1);
	LCD_E=0;
	Delay(1);
}

void LCD_Init(void)
{//初始化lcd1602
	LCD_WriteCmd(0x38);
	LCD_WriteCmd(0x0C);
	LCD_WriteCmd(0x06);
	LCD_WriteCmd(0x01);
}
void LCD_SetCursor(uchar Line,uchar Column)
{//选择显示的行和列:参数一代表行,参数二代表列
	 LCD_WriteCmd(Line==1?0x80+(Column-1):0xC0+(Column-1));
}

void LCD_ShowString(uchar Line,uchar Column,char *String)
{//选择要显示的字字符串,参数一代表行,参数二代表列,参数三要传一个字符串进来,或者字符型的指针
	unsigned char i;
	LCD_SetCursor(Line,Column);
	for(i=0;String[i]!='\0';i++)
		LCD_WriteData(String[i]);
	
}
void LCD_ShowTime(char h,char m,char s)
{ //在lcd1602上面显示时间 ,用定时器1     
        LCD_SetCursor(2,5);   
		LCD_WriteData(h/10+0x30);
        LCD_WriteData(h%10+0x30);
        LCD_WriteData(0x3a);
        LCD_WriteData(m/10+0x30);
        LCD_WriteData(m%10+0x30);
        LCD_WriteData(0x3a);
        LCD_WriteData(s/10+0x30);
        LCD_WriteData(s%10+0x30);             
}

void LCD_ShowStopwatch()
{//在lcd1602上面显示秒表 ,用定时器2     ,       
        LCD_SetCursor(2,5);   
		LCD_WriteData(H/10+0x30);
        LCD_WriteData(H%10+0x30);
        LCD_WriteData(0x3a);
        LCD_WriteData(M/10+0x30);
        LCD_WriteData(M%10+0x30);
        LCD_WriteData(0x3a);
        LCD_WriteData(S/10+0x30);
        LCD_WriteData(S%10+0x30);           
}

void key_scan()
{//按键扫描,进行模式和档位的更改 
    static uchar flag=0;
    if(P3_1==0){   //档位选择
        Delay(20);
        while(P3_1==0);
        Delay(20);
        TR0=0;//关闭T0中断请求
        flag++;
        if(flag==4){
            flag=0;
            LCD_WriteCmd(0x01);//清屏
            TR0=1;
            }
    }
    if(P3_3==0){//模式切换按键
        Delay(20);
        while(P3_3==0);
        Delay(20);
        LCD_WriteCmd(0x01);
        mode++; 
        if(mode==2)//模式切换成时钟模式 
            mode=0;       
    }
    if(mode==0){    //时钟模式  
        if(flag!=0){
            LCD_ShowString(1,2,"Change Time");
            switch(flag){
                case 1:if(P3_0==0){ Delay(20);while(P3_0==0);Delay(20);hour++; if(hour>23) hour=0;}break;
                case 2:if(P3_0==0){ Delay(20);while(P3_0==0);Delay(20);minute++; if(minute>59) minute=0;}break;
                case 3:if(P3_0==0){ Delay(20);while(P3_0==0);Delay(20);second++; if(second>59) second=0;}break;
                default:break;
            }
            switch(flag){
                case 1:if(P3_2==0){ Delay(20);while(P3_2==0);Delay(20);hour--; if(hour<0) hour=23;}break;
                case 2:if(P3_2==0){ Delay(20);while(P3_2==0);Delay(20);minute--; if(minute<0) minute=59;}break;
                case 3:if(P3_2==0){ Delay (20);while(P3_2==0);Delay(20);second--; if(second<0) second=59;}break;
                default:break;
            }
        }else{
            LCD_ShowString(1,7,"Time");
        }
    }else {//秒表模式
        LCD_ShowString(1,4,"Stopwatch");
        if(P3_2==0){ Delay(20);while(P3_2==0);Delay(20);S=0,H=0,M=0;}/*秒表清零*/
        if(P3_0==0){ Delay(20);while(P3_0==0);Delay(20);TR1=~TR1;}/*秒表 暂停/启动*/
    }
}
void Timer0Init()
{//定时器0初始化函数,定时:50毫秒  晶振为:12.000MHz

	TMOD &= 0xF0;		//设置定时器模式
	TMOD |= 0x01;		//设置定时器模式
	TL0 = 0xB0;		    //设置定时初值
	TH0 = 0x3C;		    //设置定时初值
	TF0 = 0;		    //清除TF0标志
	TR0 = 1;		    //定时器0开始计时
    ET0=1;              //打开定时器T0中断小开关
	EA=1;               //打开总开关   
}

void Timer1Init(void)		
{//定时器1初始化函数,定时:50毫秒  晶振为:12.000MHz

	TMOD &= 0x0F;		//设置定时器模式
	TMOD |= 0x10;		//设置定时器模式	
    TL1 = 0xB0;		//设置定时初值
	TH1 = 0x3C;		//设置定时初值
	TF1 = 0;		//清除TF1标志	
    ET1=1;          //打开定时器T1中断小开关
    EA=1;           //打开总开关     
}
void main()
{
    Timer0Init();
    Timer1Init();
	LCD_Init();					    
    while(1){
        key_scan();
        switch(mode){
           case 0:LCD_ShowTime(hour,minute,second);break; 
           case 1:LCD_ShowStopwatch();break;     
        }  
    }
}

void interrupt_T0()interrupt 1
{//定时器0中断函数
    TL0 = 0xB0;		    //重新设置定时初值
	TH0 = 0x3C;		    //重新设置定时初值
    T0_flag++;
    if(T0_flag==20){
        T0_flag=0;     
        second++;
        if(second==60){
            second=0;
            minute++;
            if(minute==60){
                minute=0;
                hour++;
                if(hour==24)
                    hour=0;               
           }
        }
    }
}

void interrupt_T1() interrupt 3
{//定时器1中断函数 
    TL1 = 0xB0;		//重新设置定时初值
	TH1 = 0x3C;		//重新设置定时初值
    T1_flag++;
    if(T1_flag==20){
        T1_flag=0;     
        S++;
        if(S==60){
            S=0;
           M++;
            if(M==60){
                M=0;
                H++;
                if(H==24)
                    H=0;               
           }
        }
    }
}

da6e6366532b47d1b0f7d1767984a21f.jpeg

秒表计时 效果图

使用说明: 

独立按键
k4模式切换(时钟/秒表)


在时钟模式下:

k1按一次暂停时钟运行,进入更改时档位,第二次进入更改分档位,第三次进入更改秒档位,第四次启动时钟
k2时/分/秒  数值加一
k3时/分/秒  数值减一

在秒表模式下:

k1
k2秒表 暂停/起动
k3秒表清零

心得:要进行给LCD 首先要看明白LCD的数据手册,要显示内容,就得有显示的函数,在这之前还得有写命令和写数据的函数,写命令和写数据要看懂时序图才能码代码。

熬夜肝出来的东西,做一下学习笔记。 

  • 37
    点赞
  • 235
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
要在LCD1602显示字符串和汉字,需要先初始化LCD1602,然后将字符和汉字转换为相应的ASCII码并发送到LCD1602的数据端口。以下是一个简单的例子: ```c #include <reg51.h> //定义LCD1602的I/O端口 sbit RS=P2^0; sbit RW=P2^1; sbit EN=P2^2; //向LCD发送一个指令 void LcdWriteCmd(unsigned char cmd) { RS=0; //选择命令模式 RW=0; //选择写入模式 EN=1; //打开使能 P0=cmd; //发送指令 EN=0; //关闭使能 } //向LCD发送一个字符 void LcdWriteData(unsigned char dat) { RS=1; //选择数据模式 RW=0; //选择写入模式 EN=1; //打开使能 P0=dat; //发送数据 EN=0; //关闭使能 } //初始化LCD1602 void InitLcd() { LcdWriteCmd(0x38); //设置16*2显示,5*7点阵,8位数据接口 LcdWriteCmd(0x0c); //设置显示开,光标关,闪烁关 LcdWriteCmd(0x06); //设置文字在显示器上的移动方向,每次写入后光标加1,整屏不移动 LcdWriteCmd(0x01); //清屏 } //显示字符串 void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str) { unsigned char i; if(y==0) LcdWriteCmd(0x80+x); //在第一行显示 else LcdWriteCmd(0xc0+x); //在第二行显示 for (i=0;str[i]!=0;i++) //逐个发送字符 { LcdWriteData(str[i]); } } //显示汉字 void LcdShowChinese(unsigned char x, unsigned char y, unsigned char *str) { unsigned char i; if(y==0) LcdWriteCmd(0x80+x); //在第一行显示 else LcdWriteCmd(0xc0+x); //在第二行显示 for (i=0;str[i]!=0;i+=2) //逐个发送汉字 { LcdWriteData(str[i]); //发送高字节 LcdWriteData(str[i+1]); //发送低字节 } } void main() { InitLcd(); //初始化LCD1602 LcdShowStr(0, 0, "Hello, world!"); //显示字符串 LcdShowChinese(0, 1, "\xba\xba\xd7\xd6\xce\xf6\xb2\xe5\xd0\xde\xcf\xf1"); //显示汉字 while(1); } ``` 在上面的代码中,`\xba\xba\xd7\xd6\xce\xf6\xb2\xe5\xd0\xde\xcf\xf1` 是“你好世界”的ASCII码,需要先将其转换为相应的汉字再发送到LCD1602上。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值