单片机LCD1602液晶显示的汇编程序
也没去理解AC,只知道第一行第1点的地址是80H,第二行第1 点是C0H。下面就是你要的程序,仅供参考RS BIT P1.2 ;这3位是液晶屏的控制信号,连接方式由具体硬件而定RW BIT P1.1E BIT P1.0ORG 00HAJMP MAINORG 30HMAIN: mov R0,#24ACALL INITIALACALL DISPLAY;调用液晶显示子程序AJMP MAIN;-------液晶显示---------------------------------------DISPLAY: MOV A,#80H ;第一行第1 个点ACALL WR_CMDMOV DPTR, #LINE1ACALL PR_STRACALL WR_DATADISP1:MOV A,#1CH ;字符左移命令(注:实物中左移命令字为18H)ACALL WR_CMDACALL D05SDJNZ R0,DISP1RET;---液晶屏初始化-------------------------------------------------INITIAL: MOV A, #01HACALL WR_CMDMOV A, #38HACALL WR_CMDMOV A, #0CHACALL WR_CMDMOV A, #06HACALL WR_CMDRET;----写液晶指令的子程序------------------------------------------WR_CMD: MOV P3, ACLR RS ;写入控制命令CLR RWCLR EACALL DELAYSETB ERET;----写液晶数据---------------------------------------------WR_DATA: MOV P3, ASETB RS ;写入数据CLR RWCLR EACALL DELAY ;判断液晶模块是否忙?SETB ERET;-----写行字符---------------------------------------------------------------PR_STR:CLR AMOVC A, @A+DPTRJZ END_PRACALL WR_DATAINC DPTRAJMP PR_STREND_PR: RET;----查看液晶忙碌信号---------------------------------------------------------DELAY: MOV P3,#0FFH ;判断液晶显示器是否忙的子程序CLR RSSETB RWCLR ENOPSETB EJB P3.7,DELAY ;如果P3.7为高电平表示忙就循环等待RET ;----0.5S延时(按12MHZ算)-----------------------------------------------------------------D05S: MOV R6,#25MOV R5,#100MOV R4,#100DJNZ R4,$DJNZ R5,$-4DJNZ R6,$-8RET;--------------------------------------------------------------------------------------LINE1:DB ' ZHU NI YI SHENG PING AN',00HEND
为什么LCD要初始化,应该是IC初始化吧?
是对LCD控制IC初始化。
_____________________________________________
如果是单片机控制LCD显示时,单片机电路一般都会上电复位或硬复位,这样就可以完成单片机系统电路的初始化操作。
但单片机的初始化对LCD没有影响。LCD本身也有控制器,即要对IC也要进行初始化操作。
例如:假设当我们开机时LCD显示“你好”。系统运行过程中突然复位,这个时候假如LCD显示“北京”。
单片机复位后应该显示“你好”才对,但可能LCD还显示“北京”。这个时候就要对LCD进行复位,就可以显示正常了。
写出编程LCD1602液晶的初始化程序
#include
#define uchar unsigned char
#define uint unsigned int
#define lcd_ports P1
sbit lcdrs=P3^5;
sbit lcdrw=P3^3;
sbit lcde=P3^4;
void delay(uint z)//延迟子程序
{
uchar i,j;
for(i=z;i>0;i--)
for(j=256;j>0;j--);
}
void write_com(uchar com) //1602写指令
{
lcdrs=0;
P1=com;
delay(5);
lcde=1;
delay(5);
lcde=0;
}
void write_data(uchar date) //1602写数据,写的是你要显示数据的ASCLL码值
{
lcdrs=1;
P1=date;
delay(5);
lcde=1;
delay(5);
lcde=0;
}
void init() //初始化
{
lcdrw=0;
lcde=0;
write_com(0x38); //使液晶显示点阵
write_com(0x0e); //初始设置
write_com(0x06); //初始设置
write_com(0x01); //清零
write_com(0x80+0x00); //使指针指向第一行第一列
}
void main()
{
init();
while(1){
write_com(0x80);//从第一行第一列开始写数据。
write_data(0x73); //显示s字符
write_data(0x69);//第一行第二列显示字符i
write_data(0x6e);//第一行第三列显示字符n
write_data(0x65);//第一行第四列显示字符e;}
}
LCD1602用C语言编程如何显示字符?
void delay(uint z);//延时,1微妙时间有点短
你看看下面我做的程序,在2051+12M晶振通过你可以套用这个程序,不行的话就改长延时
/******************AT89S51使用12M晶振*******************/
//LCD脚接法,根据实际接法定义
#define LCM_D4_RS P3_2//第4脚数据/命令
#define LCM_D5_RW P3_5//第5脚读/写
#define LCM_D6_E P3_7//第6脚使能
#define LCM_D16_BLK P3_0//背光负极
#define LCM_D7_Data P1//第7-14脚数据
//LCD脚接法,根据实际接法定义
#define Busy 0x80 //用于检测LCM状态字中的Busy标识
#define _LCD_BIT_IS 4 //CPU与LCD1602间使用DB7-DB4这4根数据线进行传输
#include //头文件
#include //strlen()函数头文件
void LCMInit(void); //LCM初始化化
void WriteDataLCM(unsigned char WDLCM);//写数据
void WriteCommandLCM(unsigned char WCLCM,int BuysC); //写指令
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData); //按指定位置显示一个字符
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData);//按指定位置显示一串字符
void Delay5Ms(void); //5ms延时
unsigned char ReadStatusLCM(void); //读状态
unsigned char code Greetings_Line1[] = {"Welcome Control"};
unsigned char code Greetings_Line2[] = {" ChuLong Make "};
data unsigned char cou = 0; // 定义软计数器,放在程序最前面的寄存器定义部分
void main(void)
{
LCMInit(); //LCM初始化
LCM_D16_BLK= 0;//开背光灯
TMOD = 0x11; // 定时/计数器0,1工作于方式1 16位定时
TH0 = 0x3c; // 预置产生50ms时基信号
TL0 = 0xb0;
EA = 1; // 开总中断
ET0 = 1; // 定时/计数器0允许中断
TR0 = 1; // 开定时/计数器0
DisplayListChar(0, 0, Greetings_Line1);
DisplayListChar(0, 1, Greetings_Line2);
//while(1);
}
//
void LCMInit(void) //LCM初始化
{
WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号
Delay5Ms();
WriteCommandLCM(0x38,0);
Delay5Ms();
WriteCommandLCM(0x38,0);
#if(_LCD_BIT_IS == 8) //CPU与LCD1602间使用DB0-DB8这8根数据线进行传输
WriteCommandLCM(0x38,1); //显示8位模式设置,开始要求每次检测忙信号
#else //CPU与LCD1602间使用DB0-DB4这4根数据线进行传输
WriteCommandLCM(0x28,1); //显示4位模式设置,开始要求每次检测忙信号
#endif
WriteCommandLCM(0x08,1); //关闭显示
WriteCommandLCM(0x01,1); //显示清屏
WriteCommandLCM(0x06,1); // 显示光标移动设置
WriteCommandLCM(0x0C,1); // 显示开及光标设置
}
//写数据
void WriteDataLCM(unsigned char WDLCM)
{
ReadStatusLCM(); //检测忙
LCM_D4_RS = 1;
LCM_D5_RW = 0;
#if(_LCD_BIT_IS == 8) //CPU与LCD1602间使用DB0-DB8这8根数据线进行传输
{
LCM_D7_Data = WDLCM;
}
#else //CPU与LCD1602间使用DB0-DB4这4根数据线进行传输
{
LCM_D7_Data &= 0x0f; //清高四位
LCM_D7_Data |= WDLCM & 0xf0; //写高四位
LCM_D6_E = 0;
LCM_D6_E = 1;
WDLCM = WDLCM << 4; //低四位移到高四位
LCM_D7_Data &= 0x0f; //清高四位
LCM_D7_Data |= WDLCM & 0xf0; //写低四位
}
#endif
LCM_D6_E = 0;
LCM_D6_E = 1;
}
//写指令
void WriteCommandLCM(unsigned char WCLCM,int BuysC) //BuysC为0时忽略忙检测
{
if(BuysC)
ReadStatusLCM(); //根据需要检测忙
LCM_D4_RS = 0;
LCM_D5_RW = 0;
#if(_LCD_BIT_IS == 8) //CPU与LCD1602间使用DB7-DB4这4根数据线进行传输
{
LCM_D7_Data = WCLCM;
}
#else
{
LCM_D7_Data &= 0x0f; //清高四位
LCM_D7_Data |= WCLCM & 0xf0; //写高四位
LCM_D6_E = 0;
LCM_D6_E = 1;
WCLCM = WCLCM << 4; //低四位移到高四位
LCM_D7_Data &= 0x0f; //清高四位
LCM_D7_Data |= WCLCM & 0xf0; //写低四位
}
#endif
LCM_D6_E = 0;
LCM_D6_E = 1;
}
//读状态
unsigned char ReadStatusLCM(void)
{
LCM_D7_Data = 0xff;
LCM_D4_RS = 0;
LCM_D5_RW = 1;
LCM_D6_E = 1;
while (LCM_D7_Data & Busy); //检测忙信号
return(LCM_D7_Data);
}
//按指定位置显示一个字符
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
{
Y &= 0x1;
X &= 0xF; //限制X不能大于15,Y不能大于1
if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;
X |= 0x80; //算出指令码
WriteCommandLCM(X, 0); //这里不检测忙信号,发送地址码
WriteDataLCM(DData);
}
//按指定位置显示一串字符
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)
{
int ListLength;
Y &= 0x1;
X &= 0xF; //限制X不能大于15,Y不能大于1
for(ListLength = 0;ListLength < strlen(DData);ListLength++) //若到达字串尾则退出
{
if (X <= 0xF) //X坐标应小于0xF
{
DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符
X++;
}
}
}
//5ms延时
void Delay5Ms(void)
{
unsigned int TempCyc = 5552;
while(TempCyc--);
}
//10s延时
void tiem0(void) interrupt 1
{ // T/C0中断服务程序(产生50ms时基信号)
if(cou < 60)
{ // 计数值到1000(1s) (****时间为倒计时****)
cou = 0; // 软计数器清零
}
cou++; // 软计数器加1
TH0 = 0x3c; // 重置定时常数
TL0 = 0xb0;
}
LCD1602初始化问题
给个例子你看啊,延时是根据时序图来进行的啊,如果不延时,可能时序就不对,写的地址肯定也就被误解了啊
void write_com(uchar com)
{
P0=com;
RS=0;
RW=0;
E=0;
delay(5); // 你可能是这里没延时
E=1;
delay(5);
}
void write_date(uchar date)
{
P0=date;
RS=1;
RW=0;
E=0;
delay(5);
E=1;
delay(5);
}
void init()
{
write_com(0x38);
write_com(0x0f);
write_com(0x06);
write_com(0x80);
write_com(0x01);
}
1602液晶屏,读忙标志的原理
1,lcd1602工作原理是什么?线段的显示点阵图形式液晶由M×N个显示单元组成,假设LCD显示屏有64行,每行有128列,每8列对应1字节的8位,即每行由16字节,共16×8=128个点组成,屏上64×16个显示单元与显示RAM区1024字节相对应,每一字节的内容和显示屏上相应位置的亮暗对应。例如屏的第一行的亮暗由RAM区的000H——00FH的16字节的内容决定,当(000H)=FFH时,则屏幕的左上角显示一条短亮线,长度为8个点;当(3FFH)=FFH时,则屏幕的右下角显示一条短亮线;当(000H)=FFH,(001H)=00H,(002H)=00H,……(00EH)=00H,(00FH)=00H时,则在屏幕的顶部显示一条由8段亮线和8条暗线组成的虚线。这就是LCD显示的基本原理。字符的显示用LCD显示一个字符时比较复杂,因为一个字符由6×8或8×8点阵组成,既要找到和显示屏幕上某几个位置对应的显示RAM区的8字节,还要使每字节的不同位为“1”,其它的为“0”,为“1”的点亮,为“0”的不亮。这样一来就组成某个字符。但由于内带字符发生器的控制器来说,显示字符就比较简单了,可以让控制器工作在文本方式,根据在LCD上开始显示的行列号及每行的列数找出显示RAM对应的地址,设立光标,在此送上该字符对应的代码即可。汉字的显示汉字的显示一般采用图形的方式,事先从微机中提取要显示的汉字的点阵码(一般用字模提取软件),每个汉字占32B,分左右两半,各占16B,左边为1、3、5……右边为2、4、6……根据在LCD上开始显示的行列号及每行的列数可找出显示RAM对应的地址,设立光标,送上要显示的汉字的第一字节,光标位置加1,送第二个字节,换行按列对齐,送第三个字节……直到32B显示完就可以LCD上得到一个完整汉字。2,lcd1602工作原理-lcd1602的基本参数显示容量:16×2个字符芯片工作电压:4.5—5.5V工作电流:2.0mA(5.0V)模块最佳工作电压:5.0V字符尺寸:2.95×4.35(W×H)mm3,lcd1602工作原理-lcd1602与单片机连接电路图lcd1602液晶显示模块可以只用D4-D7作为四位数据分两次传送。这样的话,可以节省MCU的I/O口资源。lcd1602可以显示2行16个字符,有8为数据总线D0-D7,和RS、R/W、EN三个控制端口,工作电压为5V,并且带有字符对比度调节和背光。lcd1602液晶显示模块可以和单片机AT89C51直接接口,电路连接简单,如图1所示:lcd1602和51单片机的连接图lcd1602和51单片机的连接图其中图中的JPBG直接接电源,第3引脚的可调电位器的两端一定要连接电源和地。P2.0,P2.1,P2.2分别是RS,R/W和E三个控制位,P0.0-P0.7是8位数据线。三个控制位详见说明,RS=0表示写或读指令,RS=1表示写数据。R/W是读写指令,R/W=1是读,R/W=0是写。E是使能端,要根据时序图去写对应的程序。lcd1602和AT89S52单片机的连接图此电路中,上拉电阻用4.7K的,液晶的3脚用一个10K可调电阻接地,调节液晶亮度。4,lcd1602工作原理-lcd1602引脚图与引脚定义lcd1602共16个管脚,但是编程用到的主要管脚不过三个,分别为:RS(数据命令选择端),R/W(读写选择端),E(使能信号);以后编程便主要围绕这三个管脚展开进行初始化,写命令,写数据。1602采用标准的16脚接口,第1脚:VSS为电源地第2脚:VCC接5V电源正极第3脚:V0为液晶显示器对比度调整端,接正电源时对比度最弱,接地电源时对比度最高(对比度过高时会 产生“鬼影”,使用时可以通过一个10K的电位器调整对比度)。第4脚:RS为寄存器选择,高电平1时选择数据寄存器、低电平0时选择指令寄存器。第5脚:RW为读写信号线,高电平(1)时进行读操作,低电平(0)时进行写操作。第6脚:E(或EN)端为使能(enable)端,高电平(1)时读取信息,负跳变时执行指令。第7~14脚:D0~D7为8位双向数据端。第15~16脚:空脚或背灯电源。15脚背光正极,16脚背光负极。 5,lcd1602工作原理-读写操作指令编程表 各种液晶厂家均有提供几乎都是同样规格的lcd1602 模块或兼容模块,尽管各厂家的对其各自的产品命名不尽相同;但其最初采用的LCD 控制器采用的是HD44780,在各厂家生产的1602 模块当中,基本上也都采用了与之兼容的控制IC,所以从特性上基本上是一样的;当然,很多厂商提供了不同的字符颜色、背光色之类的显示模块。但是它们的读写操作是一样的。 lcd1602液晶模块内部的控制器共有11条控制指令,如下表所示。 lcd1602液晶模块的读写操作,屏幕和光标的操作都是通过指令编程来实现的。(说明1为高电平,0为低电平)指令1:清显示,指令码01H,光标复位到地址00H位置指令2:光标复位,光标返回到地址00H 指令3:光标和显示位置设置I/D,光标移动方向,高电平右移,低电平左移,S:屏幕上所有文字是否左移或右移,高电平表示有效,低电平表示无效。 指令4:显示开关控制。D:控制整体的显示开与关,高电平表示开显示,低电平表示关显示。C:控制光标的开与关,高电平表示有光标,低电平表示无光标 B:控制光标是否闪烁,高电平闪烁,低电平不闪烁。 指令5:光标或显示移位 S/C :高电平时显示移动的文字,低电平时移动光标 指令6:功能设置命令 DL:高电平时为4位总线,低电平时为8位总线 N:低电平时为单行显示,高电平时为双行显示,F:低电平时显示5X7的点阵字符,高电平时显示5X10的显示字符。指令7:字符发生器RAM地址设置。指令8:DDRAM地址设置。 指令9:读忙信号和光标地址 BF:忙标志位,高电平表示忙,此时模块不能接收命令或数据,如果为低电平表示不忙。 小编推荐阅读: lcd1602液晶显示屏介绍_lcd1602引脚功能 lcd1602在proteus中怎么找_lcd1602proteus仿真 lcd1602只亮不显示_lcd1602简单显示程序 lcd1602地址设置_LCD1602内部的控制器指令 lcd1602的封装_lcd1602的初始化程序 lcd1602的a和k是什么引脚_lcd1602与单片机的连接方法阅读原文