基于51单片机控制LCD1602液晶屏显示
1602
LCD1602一共有16个接口,其中RS,RW,EN,D0,D1,D2,D3,D4,D5,D6,D7用于读写数据
也就是说是并行通信。
判断液晶忙:
判断STA7是否为1,所以将P0口总线的数据和0x80(1000 0000)进行与运算。
每次对1602写指令都需要判断是否忙。
void Read_busy()
{
uchar busy;
P0 = 0xff;
RS = 0;
RW = 1;
do{
EN = 1;
busy = P0;
EN = 0;
}
while(busy & 0x80);
}
写字节和写数据都是按照1602的数据手册来写的。
写LCD1602命令一个字节:
void Write_Cmd(uchar cmd)
{
Read_busy();
RS = 0;
RW = 0;
P0 = cmd;
EN = 1;
EN = 0;
}
写一个字节数据:
void Write_Dat(uchar dat)
{
Read_busy();
RS = 1;
RW = 0;
P0 = dat;
EN = 1;
EN = 0;
}
由上面的函数,就可以初始化LCD1602。
1602初始化函数:
void Init_LCD1602()
{
LCD1602_Write_Cmd(0x38); //设置16*2显示,5*7点阵,8位数据接口
LCD1602_Write_Cmd(0x0c); //开显示,不显示光标(0xf开显示,显示光标,光标闪烁)
LCD1602_Write_Cmd(0x01); //清除显示
LCD1602_Write_Cmd(0x06); //读写一字节后地址指针加1
Write_Cmd(0x80 | 0x00); //设置显示地址(显示在第一行第一个)设置显示地址以及设置读写地址指针方向一定要在清除显示之后要不然仍会显示在第一个格
)
在显示数字的时候要用 Write_Dat(3 + \’0\’);
显示字母使用ASCLL码(例如:显示H:Write_Dat(0x48);)
在指定位置显示一个字符:
要显示的横坐标取值0-40
要显示的行坐标取值0-1(0为第一行,1为第二行)
dat:需要显示的数据以ASCLL形式显示
void LCD1602_Dis_OneChar(uchar x, uchar y,uchar dat)
{
if(y) x |= 0x40;
x |= 0x80;
LCD1602_Write_Cmd(x);
LCD1602_Write_Dat(dat);
}
显示字符串的时候就需要用到指针:
在指定位置显示字符串:
要显示的横坐标取值0-40
要显示的行坐标取值0-1(0为第一行,1为第二行)
*str:需要显示的字符串
void LCD1602_Dis_Str(uchar x, uchar y, uchar *str)
{
if(y) x |= 0x40;
x |= 0x80;
LCD1602_Write_Cmd(x);
while(*str != \’\0\’)
{
LCD1602_Write_Dat(*str++);
}
}
调用方式:
uchar TestStr[] = {“Welcome!”};
LCD1602_Dis_Str(0, 0, &TestStr[0]);
显示简单的数字:
#include <reg52.h> #define uchar unsigned char #define uint unsigned int sbit RS = P3^5; sbit RW = P3^6; sbit EN = P3^4; void Read_busy() //判断液晶忙 { uchar busy; P0 = 0xff; RS = 0; RW = 1; do{ EN = 1; busy = P0; EN = 0; } while(busy & 0x80); } void Write_Cmd(uchar cmd) //写LCD1602命令一个字节 { Read_busy(); RS = 0; RW = 0; P0 = cmd; EN = 1; EN = 0; } void Write_Dat(uchar dat) //写一个字节数据 { Read_busy(); RS = 1; RW = 0; P0 = dat; EN = 1; EN = 0; } void main() { Write_Cmd(0x38);//设置16*2显示 Write_Cmd(0x0f);//开显示 显示光标,光标闪烁 Write_Cmd(0x01);//清屏 Write_Cmd(0x06);//地址指针移位命令 Write_Cmd(0x80 | 0x00);//显示地址 Write_Dat(1 + \'0\'); Write_Dat(2 + \'0\'); Write_Dat(3 + \'0\'); Write_Dat(4 + \'0\'); Write_Dat(5 + \'0\'); while(1); }
显示字符串:
#include <reg52.h>
typedef unsigned char uchar; typedef unsigned int uint; #define LCD1602_DB P0 //LCD1602数据总线 sbit LCD1602_RS = P3^5; //RS端 sbit LCD1602_RW = P3^6; //RW端 sbit LCD1602_EN = P3^4; //EN端 sbit DU = P2^6;// sbit WE = P2^7;//数码管位选段选用于关闭数码管显示 /*================================================= *函数名称:Read_Busy *函数功能:判断1602液晶忙,并等待 =================================================*/ void Read_Busy() { uchar busy; LCD1602_DB = 0xff;//复位数据总线 LCD1602_RS = 0; //拉低RS LCD1602_RW = 1; //拉高RW读 do { LCD1602_EN = 1;//使能EN busy = LCD1602_DB;//读回数据 LCD1602_EN = 0; //拉低使能以便于下一次产生上升沿 }while(busy & 0x80); //判断状态字BIT7位是否为1,为1则表示忙,程序等待 } /*================================================= *函数名称:LCD1602_Write_Cmd *函数功能:写LCD1602命令 *调用:Read_Busy(); *输入:cmd:要写的命令 =================================================*/ void LCD1602_Write_Cmd(uchar cmd) { Read_Busy(); //判断忙,忙则等待 LCD1602_RS = 0; LCD1602_RW = 0; //拉低RS、RW操作时序情况1602课件下中文使用说明基本操作时序章节 LCD1602_DB = cmd;//写入命令 LCD1602_EN = 1; //拉高使能端 数据被传输到LCD1602内 LCD1602_EN = 0; //拉低使能以便于下一次产生上升沿 } /*================================================= *函数名称:LCD1602_Write_Dat *函数功能:写LCD1602数据 *调用:Read_Busy(); *输入:dat:需要写入的数据 =================================================*/ void LCD1602_Write_Dat(uchar dat) { Read_Busy(); LCD1602_RS = 1; LCD1602_RW = 0; LCD1602_DB = dat; LCD1602_EN = 1; LCD1602_EN = 0; } /*================================================= *函数名称:LCD1602_Dis_OneChar *函数功能:在指定位置显示一个字符 *调用:LCD1602_Write_Cmd(); LCD1602_Write_Dat(); *输入:x:要显示的横坐标取值0-40,y:要显示的行坐标取值0-1(0为第一行,1为第二行) dat:需要显示的数据以ASCLL形式显示 =================================================*/ void LCD1602_Dis_OneChar(uchar x, uchar y,uchar dat) { if(y) x |= 0x40; x |= 0x80; LCD1602_Write_Cmd(x); LCD1602_Write_Dat(dat); } /*================================================= *函数名称:LCD1602_Dis_Str *函数功能:在指定位置显示字符串 *调用:LCD1602_Write_Cmd(); LCD1602_Write_Dat(); *输入:x:要显示的横坐标取值0-40,y:要显示的行坐标取值0-1(0为第一行,1为第二行) *str:需要显示的字符串 =================================================*/ void LCD1602_Dis_Str(uchar x, uchar y, uchar *str) { if(y) x |= 0x40; x |= 0x80; LCD1602_Write_Cmd(x); while(*str != \'\0\') { LCD1602_Write_Dat(*str++); } } /*================================================= *函数名称:Init_LCD1602 *函数功能:1602初始化 *调用: LCD1602_Write_Cmd(); =================================================*/ void Init_LCD1602() { LCD1602_Write_Cmd(0x38); // 设置16*2显示,5*7点阵,8位数据接口 LCD1602_Write_Cmd(0x0c); //开显示 LCD1602_Write_Cmd(0x06); //读写一字节后地址指针加1 LCD1602_Write_Cmd(0x01); //清除显示 } void main() { uchar TestStr[] = {"Welcome!"}; DU = 0; WE = 0;//关闭数码管显示 Init_LCD1602();//1602初始化 LCD1602_Dis_Str(0, 0, &TestStr[0]); //显示字符串 LCD1602_Dis_OneChar(10, 1, 0xff); //显示一个黑方格 while(1); }