LCD1602液晶显示原理:点击此处
为方便使用,我的范例代码是只提供 .h .c ,使用这种方式也方便进行代码替换,使你得主代码区域不会太过于复杂。我只会简单在最后写一个使用的范例,我不会将整个功能的代码放上来,因为你的作品功能只有自己知道,我如果整个实现都写出来,只会误导到你。
所有我发布上来的代码,都是我在实际项目中使用过,并确保没有问题的。
注意:我所使用的LCD1602液晶显示代码,必须将RS/RW/EN都接在单片机上,因为严谨性,代码中有检测LCD是否在忙的状态,如果三根线不接在对应的单片机接口上,会导致代码卡死!
这份LCD1602液晶显示代码是我最喜欢用的一个,相较于其他范例代码,这份更加人性化。
=========================delay.h =========================
#ifndef __DELAY_H__ #define __DELAY_H__ /*------------------------------------------------ us延时函数,含有输入参数 unsigned char t,无返回值 unsigned char 是定义无符号字符变量,其值的范围是 0~255 延时函数会有误差,但是也可以使用,如需精准 计时还请使用定时器 ------------------------------------------------*/ void DelayUs2x(unsigned char t); /*------------------------------------------------ ms延时函数,含有输入参数 unsigned char t,无返回值 unsigned char 是定义无符号字符变量,其值的范围是 0~255 延时函数会有误差,但是也可以使用,如需精准 计时还请使用定时器 ------------------------------------------------*/ void DelayMs(unsigned char t); #endif
=========================delay.c =========================
#include "delay.h" /*------------------------------------------------ us延时函数,含有输入参数 unsigned char t,无返回值 unsigned char 是定义无符号字符变量,其值的范围是 0~255 延时函数会有误差,但是也可以使用,如需精准 计时还请使用定时器 ------------------------------------------------*/ void DelayUs2x(unsigned char t) { while(--t); } /*------------------------------------------------ ms延时函数,含有输入参数 unsigned char t,无返回值 unsigned char 是定义无符号字符变量,其值的范围是 0~255 延时函数会有误差,但是也可以使用,如需精准 计时还请使用定时器 ------------------------------------------------*/ void DelayMs(unsigned char t) { while(t--) { //大致延时1mS DelayUs2x(245); DelayUs2x(245); } }
=========================lcd1602.c =========================
#include "lcd1602.h" #include "delay.h" #include <intrins.h> #define uchar unsigned char #define uint unsigned int #define _NOP() _nop_() sbit RS = P2^6; //定义端口 sbit RW = P2^5; sbit EN = P2^7; #define DataPort P0 #define DataPIN P0 #define CLR_RS (RS=0) #define SET_RS (RS=1) #define CLR_RW (RW=0) #define SET_RW (RW=1) #define CLR_EN (EN=0) #define SET_EN (EN=1) /* LcdReset(); //LCD1602初始化 DelayMs(10); sprintf(temp,"1111111111111111");//更新显示 DispStr(0,0,(unsigned char *)temp);//打印显示 sprintf(temp,"1111111111111111");//¸更新显示 DispStr(0,1,(unsigned char *)temp);//打印显示 */ /*********************************************** 函数名称:DispStr 功 能:让液晶从某个位置起连续显示一个字符串 参 数:x--位置的列坐标 y--位置的行坐标 ptr--指向字符串存放位置的指针 返回值 :无 ***********************************************/ void DispStr(uchar x,uchar y,uchar *ptr) { uchar *temp; uchar i,n = 0; temp = ptr; while(*ptr++ != '\0') n++; //计算字符串有效字符的个数 for (i=0;i<n;i++) { Disp1Char(x++,y,temp[i]); if (x == 0x10) { break; } } } /******************************************* 函数名称:DispNChar 功 能:让液晶从某个位置起连续显示N个字符 参 数:x--位置的列坐标 y--位置的行坐标 n--字符个数 ptr--指向字符串存放位置的指针 返回值 :无 注意:这个函数是屏蔽起来的,因为不是经常使用 如果你想使用,那么可以打开屏蔽 ******************************************* /*void DispNChar(uchar x,uchar y, uchar n,uchar *ptr) { uchar i; for (i=0;i<n;i++) { Disp1Char(x++,y,ptr[i]); if (x == 0x10) { x = 0; y ^= 1; } } } */ /******************************************* 函数名称:LocateXY 功 能:让液晶从某个位置起连续显示N个字符 参 数:x--位置的列坐标 y--位置的行坐标 返回值 :无 ********************************************/ void LocateXY(uchar x,uchar y) { uchar temp; temp = x&0x0f; y &= 0x01; if(y) temp |= 0x40; //如果在第2行 temp |= 0x80; LcdWriteCommand(temp,1); } /******************************************* 函数名称:Disp1Char 功 能:在某个位置显示一个字符 参 数:x--位置的列坐标 y--位置的行坐标 data1--显示的字符数据 返回值 :无 ********************************************/ void Disp1Char(uchar x,uchar y,uchar data1) { LocateXY( x, y ); LcdWriteData( data1 ); } /******************************************* 函数名称:LcdReset 功 能:对1602液晶模块进行复位操作 参 数:无 返回值 :无 ********************************************/ void LcdReset(void) { // DataDir = 0xFF; //数据端口设为输出状态 LcdWriteCommand(0x38, 0); //规定的复位操作 DelayMs(5); LcdWriteCommand(0x38, 0); DelayMs(5); LcdWriteCommand(0x38, 0); DelayMs(5); LcdWriteCommand(0x38, 1); //显示模式设置 LcdWriteCommand(0x08, 1); //显示关闭 LcdWriteCommand(0x01, 1); //显示清屏 LcdWriteCommand(0x06, 1); //写字符时整体不移动 LcdWriteCommand(0x0c, 1); //显示开,不开游标,不闪烁 } /*------------------------------------------------ 清屏函数 ------------------------------------------------*/ void LcdClear(void) { LcdWriteCommand(0x01,1); DelayMs(5); } /******************************************* 函数名称:LcdWriteCommand 功 能:向液晶模块写入命令 参 数:cmd--命令 cnk--是否判断忙的标志,1:判忙 0:不判 返回值 :无 ********************************************/ void LcdWriteCommand(uchar cmd,uchar chk) { if (chk) WaitForEnable(); //检测忙信号 CLR_RS; CLR_RW; _NOP(); DataPort = cmd; //将命令字写入数据端口 _NOP(); SET_EN; //产生使能脉冲信号 _NOP(); _NOP(); CLR_EN; } /******************************************* 函数名称:LcdWriteData 功 能:向液晶显示的当前地址写入显示数据 参 数:data1--显示字符数据 返回值 :无 ********************************************/ void LcdWriteData( uchar data1 ) { WaitForEnable(); //等待液晶不忙 SET_RS; CLR_RW; SET_EN; _NOP(); DataPort = data1; //将显示数据写入数据端口 _NOP(); //产生使能脉冲信号 _NOP(); _NOP(); CLR_EN; } /******************************************* 函数名称:WaitForEnable 功 能:等待1602液晶完成内部操作 参 数:无 返回值 :无 ********************************************/ void WaitForEnable(void) { unsigned int later=0; DataPort=0xff; CLR_RS; SET_RW; _NOP(); SET_EN; _NOP(); _NOP(); // while((DataPIN&Busy)!=0); while(((DataPIN&0x80)!=0)&&(later<1000)) //检测忙标志 { DelayUs2x(2); later++; } CLR_EN; // DataDir|=0xFF; }
=========================lcd1602.h =========================
/*----------------------------------------------- 名称:LCD1602.h 引脚定义如下:1-VSS 2-VDD 3-V0 4-RS 5-R/W 6-E 7-14 DB0-DB7 15-BLA 16-BLK ------------------------------------------------*/ #include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义 #include<intrins.h> #ifndef __LCD1602_H__ #define __LCD1602_H__ void DispStr(unsigned char x,unsigned char y,unsigned char *ptr); void DispNChar(unsigned char x,unsigned char y, unsigned char n,unsigned char *ptr); void LocateXY(unsigned char x,unsigned char y); void Disp1Char(unsigned char x,unsigned char y,unsigned char data1); void LcdReset(void); void LcdWriteCommand(unsigned char cmd,unsigned char chk); void LcdWriteData( unsigned char data1 ); void WaitForEnable(void); void LcdClear(void); #define LCD_Init LcdReset #define LCD_Write_Char Disp1Char #define LCD_Write_String DispStr #define LCD_Clear LcdClear #endif
=========================main.c =========================
#include "reg52.h" #include "lcd1602.h" //因为lcd1602.h中已经包含了delay.h所以这里可以不用包含 /******************************************* 在lcd1602.h中有这样一段定义 #define LCD_Init LcdReset #define LCD_Write_Char Disp1Char #define LCD_Write_String DispStr #define LCD_Clear LcdClear 所以,LCD_Init 可以代表 LcdReset ********************************************/ void main() { int dat = 123;//data在这种语言中属于专有名词,所以最好不要用这个命名 LCD_Init(); while(1) { LCD_Write_String(0,0,"hello world!! "); LCD_Write_Char(0,1,'D'); LCD_Write_Char(1,1,'a'); LCD_Write_Char(2,1,'t'); LCD_Write_Char(3,1,':'); LCD_Write_Char(4,1,(dat/100%10)+0x30);//这里+0x30是因为需要将数字转换成 //ASCII码,数字1在ASCII码中对应0x30(十进制的48) LCD_Write_Char(5,1,(dat/10%10)+48); LCD_Write_Char(6,1,(dat%10)+0x30);//个人爱好,比较喜欢写0x30 //一行LCD1602显示屏有16个格子来显示,尽量补满所有未写入的格子都写入空格 LCD_Write_String(7,1," ") } } /* 以上代码运行后会显示 hello_world!! Data:123 */
从keil4中复制出来,结果中文全是乱码,我一个一个手打改回来了,当你们在复制这些代码到keil时,也可能出现乱码,你们可以去设置编码格式,或者像我一样一个一个打出来,当然肯定会累很多,后面我回去找一找格式转换的工具,要不然以后代码我就得累死了