51单片机LCD1602显示的例程
闲着没事,把自己写过的一些函数好好封装打包一下,以便以后自己使用,懒得又忘记了在哪个文件夹里面保存着。
1、LCD1602显示的原理
原理:https://zhuanlan.zhihu.com/p/166184285
2、LCD1602头文件
#ifndef __LCD1602_H__ #define __LCD1602_H__ #define LCD1602_Order_OFF 0x08 #define LCD1602_Order_CursorClose 0x0C #define LCD1602_Port P0 //LCD输出的8位串行数据口 sbit LCD1602_RS = P2^0; //0命令 1数据 sbit LCD1602_RW = P2^1; //0写 1读 sbit LCD1602_EN = P2^2; //读写使能,0允许 extern void LCD1602_init(); //初始化函数 extern void LCD1602_Write(unsigned char cmd,unsigned char dat); //写开启函数 extern void LCD1602_displaySring(unsigned char hang, unsigned char lie, unsigned char *pstr); //显示字符串函数 extern void LCD1602_CursorSet(unsigned char hang, unsigned char lie); //设置光标函数 #define LCD1602_CursorClose() LCD1602_Write(0,LCD1602_Order_CursorClose) //关闭光标 #define LCD1602_Off() LCD1602_Write(0,LCD1602_Order_OFF) //关显示 /************LCD1602指令集及配置*****************运行时间(在250KHz下)*/ #define LCD1602_Order_Clear 0x01 //清屏 1.64us #define LCD1602_Order_Home 0x02 //光标归位 1.64us #define LCD1602_Order_Mode_ID 0x01 //1=数据读写操作后,AC自动增1; 0=自动减1 #define LCD1602_Order_Mode_S 0x00 //1=数据读写操作 画面平移; 0=画面不动 #define LCD1602_Order_Mode (0x04|\ (LCD1602_Order_Mode_ID<<1)|\ LCD1602_Order_Mode_S) //输入方式设置 40us #define LCD1602_Order_OnOFF_D 0x01 //1=开显示,0=关显示 #define LCD1602_Order_OnOFF_C 0x00 //1=显示光标,0=不显示光标 #define LCD1602_Order_OnOFF_B 0x00 //1=光标闪烁,0=不闪烁 #define LCD1602_Order_OnOFF (0x08|\ (LCD1602_Order_OnOFF_D<<2)|\ (LCD1602_Order_OnOFF_C<<1)|\ LCD1602_Order_OnOFF_B) //显示开关控制 40us #define LCD1602_Order_Shift_SC 0x00 //0=光标平移一个字符位,1=画面平移 #define LCD1602_Order_Shift_RL 0x01 //1=右移,0=左移 #define LCD1602_Order_Shift (0x10|\ (LCD1602_Order_Shift_SC<<3)|\ (LCD1602_Order_Shift_RL<<2)) //光标、画面移动 40us #define LCD1602_Order_Function_DL 0x00 //1=8位数据接口,0=4位 #define LCD1602_Order_Function_N 0x01 //1=两行显示,0=1行 #define LCD1602_Order_Function_F 0x01 //1=5*10点阵,0=5*7 #define LCD1602_Order_Function (0x20|\ (LCD1602_Order_Function_DL<<4)|\ (LCD1602_Order_Function_N<<3)|\ (LCD1602_Order_Function_F<<2)) //工作方式设置 40us #define LCD1602_Order_CGRAM_Address 0 //CGRAM(Character Generator 字符产生器)地址(共6位) #define LCD1602_Order_CGRAM (0x40|LCD1602_Order_CGRAM_Address) //CGRAM地址设置 40us #define LCD1602_Order_DDRAM_Address 0 //一行显示:0~0x4F;两行显示:首行:0~0x27,次行:0x40~0x67 #define LCD1602_Order_DDRAM (0x80|LCD1602_Order_DDRAM_Address) //设置DDRAM地址 40us #endif
3、LCD1602C文件
#include<reg51.h> #include "LCD1602.h" //自带延时函数 void LCD1602_Delay(unsigned int dely) { for(;dely>0;dely--); } //读忙 unsigned char LCD1602_ReadBusy() { unsigned char lcd_status; LCD1602_RS=0; LCD1602_RW=1; LCD1602_EN=1; #if(LCD1602_Order_Function_DL==1) LCD1602_Port=0xFF; #endif #if(LCD1602_Order_Function_DL==0) LCD1602_Port|=0xF0; #endif LCD1602_Delay(10); lcd_status=LCD1602_Port; LCD1602_EN=0; #if(LCD1602_Order_Function_DL==0) LCD1602_EN=1; LCD1602_Delay(10); lcd_status=(lcd_status&0xF0)|((0xF0&LCD1602_Port)>>4); LCD1602_EN=0; #endif return lcd_status; } /*向液晶显示器写命令/数据函数 参数说明:cmd=0为写命令,cmd=1为写数据 */ void LCD1602_Write(unsigned char cmd,unsigned char dat) { while((LCD1602_ReadBusy()&0x80) == 0x80); LCD1602_RS=cmd; LCD1602_RW=0; LCD1602_EN=1; #if(LCD1602_Order_Function_DL==1) LCD1602_Port=dat; #endif #if(LCD1602_Order_Function_DL==0) LCD1602_Port=(LCD1602_Port&0x0F)|(dat&0xF0); LCD1602_Delay(50); LCD1602_EN=0; LCD1602_EN=1; LCD1602_Port=(LCD1602_Port&0x0F)|(dat<<4); #endif LCD1602_Delay(50); LCD1602_EN=0; } /*显示字符串 参数说明:起始行,列,字符串 */ void LCD1602_displaySring(unsigned char hang, unsigned char lie, unsigned char *pstr) { LCD1602_Write(0,0x80+(0x40 * (hang - 1)) + (lie - 1)); while(*pstr) { LCD1602_Write(1,*pstr++); } } /*让指定位置闪烁光标 参数说明:行,列 */ void LCD1602_CursorSet(unsigned char hang, unsigned char lie) { LCD1602_Write(0,0x80+(0x40 * (hang - 1)) + (lie - 1)); LCD1602_Write(0,0x0F); } /*初始化*/ void LCD1602_init() { LCD1602_RS=0; LCD1602_RW=0; LCD1602_EN=1; #if(LCD1602_Order_Function_DL==1) LCD1602_Port=LCD1602_Order_Function; #endif #if(LCD1602_Order_Function_DL==0) LCD1602_Port=(LCD1602_Port&0x0f)|(LCD1602_Order_Function&0xF0); #endif LCD1602_Delay(10); LCD1602_EN=0; LCD1602_Delay(10000); LCD1602_Write(0,LCD1602_Order_Function); //工作方式设置 LCD1602_Write(0,LCD1602_Order_OFF); //关显示 LCD1602_Write(0,LCD1602_Order_Clear); //清屏 LCD1602_Write(0,LCD1602_Order_Mode); //输入方式设置 LCD1602_Write(0,LCD1602_Order_OnOFF); //开显示 }
4、例程的main文件
#include <reg51.h> #include "stdio.h" #include "LCD1602.h" char str_temp[16]; float t = 3.14; //延时n毫秒 void delay_ms(unsigned int n) { unsigned int i=0,j=0; for(i=0;i<n;i++) for(j=0;j<123;j++); } void main() { int i; LCD1602_init(); while(1) { LCD1602_displaySring(1,1,"------test------"); sprintf(str_temp,"%f",t); LCD1602_displaySring(2,13,str_temp); for (i=0;i<10;i++) { LCD1602_displaySring(2,1,"the value:"); sprintf(str_temp,"%d",i); LCD1602_displaySring(2,11,str_temp); delay_ms(500); } } }
5、对于那个stdio.h头文件,作用是调用那个sprintf函数,这是一个非常强大的函数,能将整型数据转换为字符串数据,这样调用显示的时候就不用将数据一位一位地显示了。PS:还能显示负数哦!当想显示浮点数据的时候,就将sprintf函数的第二个参数改一改就好啦!
6、下面是整个例程的仿真图加代码,分享给大家哦。
代码+仿真图:https://wwe.lanzoui.com/inRrBqf340d