51单片机的1602液晶显示程序

合集下载

51单片机驱动LCD1602程序设计(C语言)

51单片机驱动LCD1602程序设计(C语言)
51 单片机驱动 LCD1602 程序设计(C 语言)
字符液晶绝大多数是基于 HD44780 液晶芯片的,控制原理是完全相同的,因此 HD44780 写 的控制程序可以很方便地应用于市面上大部分的字符型液晶。字符型 LCD 通常有 14 条引脚线或 16 条引脚线的 LCD,多出来的 2 条线是背光电源线 VCC(15 脚)和地线 GND(16 脚),其控制原理 与 14 脚的 LCD 完全一样,定义如下表所示:
for(i=0;i<count;i++) {
if (0 == y) x |= 0x80; //当要显示第一行时地址码+0x80; else x |= 0xC0; //在第二行显示是地址码+0xC0; Write_com(x); //发送地址码 Write_dat(*p); //发送要显示的字符编码 x++; p++; }
01110
○■■■○
10001
■○○○■
10001
■○○○■
10001
■○○○■
11111
■■■■■
10001
■○○○■
10001
■○○○■
上图左边的数据就是字模数据,右边就是将左边数据用“○”代表 0,用“■”代表 1。看出是个“A”
字了吗?在文本文件中“A”字的代码是 41H,PC 收到 41H 的代码后就去字模文件中将代表 A 字的
字符型 LCD 的引脚定义
HD44780 内置了 DDRAM、CGROM 和 CGRAM。DDRAM 就是显示数据 RAM,用来寄存 待显示的字符代码。共 80 个字节,其地址和屏幕的对应关系如下表:
也就是说想要在 LCD1602 屏幕的第一行第一列显示一个"A"字,就要向 DDRAM 的 00H 地址写 入“A”字的代码就行了。但具体的写入是要按 LCD 模块的指令格式来进行的。在 1602 中我们用前 16 个就行了。第二行也一样用前 16 个地址。对应如下:

51单片机实现电子时钟功能-1602液晶显示

51单片机实现电子时钟功能-1602液晶显示

第一章设计要求及系统组成一、基本操作时序:读状态:输入:RS=L,RW=H,E=H 输出:D0~D7=状态字写指令:输入:RS=L,RW=L,D0~D7=指令码,E=高脉冲输出:无读数据:输入:RS=H,RW=H,E= 高脉冲输出:D0~D7数据写数据:输入:RS=H,RW=L。

D0~D7=数据,E=高脉冲输出:无二、、、状态字说明:STA7 D7\ STA6 D6\ STA5 D5 \ STA4 D4 \STA3 D3 \ STA2 D2\\ STA1 D1STA0-6:当前数据地址指针的数值STA7:读写操作使能 1表示禁止,0表示允许对控制器每次进行读写操作之前,都必须进行读写检测,确保STA7为0;但是我们可以进行延时进行实现。

RAM地址映射: LCD 16字*2行00 01 02 03 04 05 06 07 08 08 09 0A 0B 0C 0D 0E 0F (27)40 41 42 4F 50 (67)指令说明:1.初始化设置 1.显示模式设置指令码:00111000(0x38)功能:设置16*2显示,5*7点阵,8位数据接口必须开显示 2.显示开、关及光标设置指令码:00001DCB,功能:D=1 开显示;D=0 关显示;C=1显示光标;B=1 光标闪烁;B=0 光标不显示 000001NS:功能:N=1当读或写一个字符后地址指针加1,且光标加1;N=0相应的减1;S=1当写一个字符,整屏显示左移(N=1)或右移(N=0),以得到光标不移动而屏幕移动的效果。

S=0 当写一个字符,正屏显示不移动。

数据控制:控制器内部设有一个数据地址指针,用户可通过它们来访问内部的全部80字节RAM4.2.1 数据指针设置:指令码:80H+地址码(0-27H,第二行开始:40H-67H) 4..2.2 读数据,写数据其它设置:01H:显示清屏:1.数据指令清零 2 所有显示清零 02H:显示回车:1.数据清零如何进行连接:实际操作中,液晶接到,第一管脚是D,第二管脚是VCC,15和16是背光,D0-D7是数据口,接到单片机的P0口,P0口接了两个锁存器,液晶,D/A,具有高阻状态的都可以随便接,没有影响,,第六管脚是LCDEN相当于 E,使能信号,它接P3^4,R/W接地,表示低电平,因为我们只进行写操作,RS接2实验板上的P3^5;只需这两端口便足以控制液晶,2和3是偏压信号,一端接地,接口信号说明:编号:1 VSS(符号表示)电源地(引脚说明)2VDD 电源正极3VL液晶显示偏压信号4RS数据/命令选择端(H/L)5R/W 读写选择端(H/L)6E使能信号7D0 Data 1/0 8D1 Data 1/0 9 D2 Data 1/0 10 D3 Data 1/0 11D4 Data 1/0 12D5 Data 1/0 13D6 Data 1/0 14D7 Data 1/0 15BLK背光源正极16 BLK背光源负极实际操作:::先写光标程序;写两个子程序,一个写数据,一个写指令:先进性两个宏定义,再位申明LCDEN与RS;为了电量充足。

基于51单片机的红外遥控+液晶LCD1602显示程序源代码

基于51单片机的红外遥控+液晶LCD1602显示程序源代码

基于51单片机的红外遥控+液晶LCD1602显示程序源代码/*******************红外遥控+液晶LCD1602测试程序源代码******************** 单片机型号:STC15W4K56S4,内部晶振:22.1184M。

功能:红外遥控+液晶LCD1602显示功能测试。

操作说明:按下红外遥控器上的“CH-”键,液晶LCD1602上显示“CH-”。

按下红外遥控器上的“CH”键,液晶LCD1602上显示“CH”。

按下红外遥控器上的“CH+”键,液晶LCD1602上显示“CH+”。

按下红外遥控器上的“|<<”键,液晶LCD1602上显示“|<<”。

按下红外遥控器上的“>>|”键,液晶LCD1602上显示“>>|”。

按下红外遥控器上的“>||”键,液晶LCD1602上显示“>||”。

按下红外遥控器上的“-”键,液晶LCD1602上显示“-”。

按下红外遥控器上的“+”键,液晶LCD1602上显示“+”。

按下红外遥控器上的“EQ”键,液晶LCD1602上显示“EQ”。

按下红外遥控器上的“0”键,液晶LCD1602上显示“0”。

按下红外遥控器上的“100+”键,液晶LCD1602上显示“100+”。

按下红外遥控器上的“200+”键,液晶LCD1602上显示“200+”。

按下红外遥控器上的“1”键,液晶LCD1602上显示“1”。

按下红外遥控器上的“2”键,液晶LCD1602上显示“2”。

按下红外遥控器上的“3”键,液晶LCD1602上显示“3”。

按下红外遥控器上的“4”键,液晶LCD1602上显示“4”。

按下红外遥控器上的“5”键,液晶LCD1602上显示“5”。

按下红外遥控器上的“6”键,液晶LCD1602上显示“6”。

按下红外遥控器上的“7”键,液晶LCD1602上显示“7”。

按下红外遥控器上的“8”键,液晶LCD1602上显示“8”。

基于51单片机的1602液晶屏的时钟显示完整程序

基于51单片机的1602液晶屏的时钟显示完整程序

//基于51单片机的1602液晶屏的时钟显示完整程序#include <reg52.h>#define uchar unsigned char#define uint unsigned intsbit en=P2^6;sbit rs=P2^4;sbit rw=P2^5;uchar count,shi,fen,miao;void delay(unsigned int);void init();void write_com(unsigned char);void write_date(unsigned char);void write_sfm(uchar,uchar);uchar code table[]="2013-2-15";uchar code table1[]="23:59:55";void main(){init();while(1){if(count==20){count=0;miao++;if(miao==60){miao=0;fen++;if(fen==60){fen=0;shi++;if(shi==24){shi=0;}write_sfm(1,shi);}write_sfm(3,fen);}write_sfm(6,miao);}}// while(1);}void delay(unsigned int z) // 延时函数{unsigned int x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void init(){unsigned char num;en=0;rw=0;write_com(0x38); //设置点阵write_com(0x0c); //设置光标不闪烁write_com(0x06); //设置光标地址后移write_com(0x01); //清屏write_com(0x80); // 表示从第一行开始显示for(num=0;num<9;num++){write_date(table[num]);delay(20);}write_com(0x80+0x40);for(num=0;num<8;num++){write_date(table1[num]);delay(20);}TMOD=0x01;TH0=(65536-50000)/256;TL0=(65535-50000)%256;EA=1;ET0=1;TR0=1;}void write_com(unsigned char com) //送指令{rs=0;rw=0;en=0;P0=com;delay(5);en=1;delay(5);en=0;}void write_date(unsigned char date) //送数据{rs=1;en=0;rw=0;P0=date;delay(5);en=1;delay(5);en=0;}void time0() interrupt 1{TH0=(65536-50000)/256;TL0=(65535-50000)%256;count++;}void write_sfm(uchar add,uchar date) //将数据分离{unsigned char shi,ge;shi=date/10;ge=date%10;write_com(0x80+0x40+add);write_date(0x30+shi); //将数值转化为十六进制0是30。

51单片机控制1602LCD显示程序

51单片机控制1602LCD显示程序

LCD显示电路#include<reg51.h>sbit RS=P3^7; //寄存器选择位,将RS位定义为P2.0引脚sbit RW=P3^6; //读写选择位,将RW位定义为P2.1引脚sbit E=P2^7; //使能信号位,将E位定义为P2.2引脚sbit BF=P0^7; //忙碌标志位,将BF位定义为P0.7引脚#define Lcd_Data P0#include <string.h>#include<intrins.h> //包含_nop_()函数定义的头文件unsigned char code string1[ ]={0x77,0x75,0x20,0x79,0x61,0x6E,0x67,0x20,0x79,0x61,0x6E,0x67,0x20,0x20,0x20,0x20}; //第一行显示的字符void Lcd_delay1ms() // 函数功能:延时1ms//注:不同单片机不同晶振需要对此函数进行修改{ unsigned char i,j;for(i=0;i<90;i++)for(j=0;j<33;j++);}void Lcd_delay(unsigned int n) // 函数功能:延时若干毫秒,入口参数:n{ unsigned int i;for(i=0;i<n;i++)Lcd_delay1ms();}/*****************************************************函数功能:判断液晶模块的忙碌状态返回值:result。

result=1,忙碌;result=0,不忙***************************************************/bit Lcd_BusyTest(void)bit result;RS=0; //根据规定,RS为低电平,RW为高电平时,可以读状态RW=1;E=1; //E=1,才允许读写_nop_(); //空操作_nop_();_nop_();_nop_(); //空操作四个机器周期,给硬件反应时间result=BF; //将忙碌标志电平赋给resultE=0;return result;}/*****************************************************函数功能:将模式设置指令或显示地址写入液晶模块入口参数:dictate***************************************************/void Lcd_WriteCom (unsigned char dictate){ while(Lcd_BusyTest()==1); //如果忙就等待RS=0; //根据规定,RS和R/W同时为低电平时,可以写入指令RW=0;E=0; //E置低电平(写指令时就是让E从0到1发生正跳变,所以应先置ぜ? _nop_();_nop_(); //空操作两个机器周期,给硬件反应时间Lcd_Data=dictate; //将数据送入P0口,即写入指令或地址_nop_();_nop_();_nop_();_nop_(); //空操作四个机器周期,给硬件反应时间E=1; //E置高电平_nop_();_nop_();_nop_();_nop_(); //空操作四个机器周期,给硬件反应时间E=0; //当E由高电平跳变成低电平时,液晶模块开始执行命令}/*****************************************************函数功能:指定字符显示的实际地址x入口参数:注:此函数已经加上了0x80,故只需写上实际地址就行***************************************************/void Lcd_WriteAddress(unsigned char x){ Lcd_WriteCom(x|0x80); //显示位置的确定方法规定为80H+地址码x/*****************************************************函数功能:将数据(字符的标准ASCII码)写入液晶模块入口参数:y(为字符常量)***************************************************/void Lcd_WriteData(unsigned char y){while(Lcd_BusyTest()==1);RS=1; //RS为高电平,RW为低电平时,可以写入数据RW=0;E=0; //E置低电平(写指令时就是让E从0到1发生正跳变所以应先置ぜ?Lcd_Data=y; //将数据送入P0口,即将数据写入液晶模块_nop_();_nop_();_nop_();_nop_(); //空操作四个机器周期,给硬件反应时间E=1; //E置高电平_nop_();_nop_();_nop_();_nop_(); //空操作四个机器周期,给硬件反应时间E=0; //当E由高电平跳变成低电平时,液晶模块开始执行命令}/*****************************************************函数功能:对LCD的显示模式进行初始化设置***************************************************/void Lcd_Int(void){Lcd_delay(15); //延时15ms,首次写指令时应给LCD一段较长的反应时间Lcd_WriteCom(0x38); //显示模式设置:16×2显示,5×7点阵,8位数据接口Lcd_delay(5); //延时5msLcd_WriteCom(0x38); //9次写设置模式Lcd_delay(5);Lcd_WriteCom(0x38); //9次写设置模式Lcd_delay(5);Lcd_WriteCom(0x38); //9次写设置模式Lcd_delay(5);Lcd_WriteCom(0x38); //9次写设置模式Lcd_delay(5);设置模式次写9// Lcd_WriteCom(0x38);Lcd_delay(5);Lcd_WriteCom(0x38); //9次写设置模式Lcd_delay(5);Lcd_WriteCom(0x38); //9次写设置模式Lcd_delay(5);Lcd_WriteCom(0x38); //9次写设置模式Lcd_delay(5);Lcd_WriteCom(0x38); //9次写设置模式Lcd_delay(5);Lcd_WriteCom(0x38); //9次写设置模式Lcd_delay(5);Lcd_WriteCom(0x38); //9次写设置模式Lcd_delay(5);Lcd_WriteCom(0x0C); //显示模式设置:显示开,有光标,光标闪烁Lcd_delay(5);Lcd_WriteCom(0x06); //显示模式设置:光标右移,字符不移Lcd_delay(5);Lcd_WriteCom(0x01); //清屏幕指令,将以前的显示内容清零Lcd_delay(5); }void hanying_show(void){unsigned char Lcd_i;Lcd_WriteCom(0x01);//清显示:清屏幕指令Lcd_delay(2);Lcd_WriteAddress(0x00); // 设置显示位置为最左侧Lcd_delay(2);Lcd_i=0;while(string1[Lcd_i]!='\0') //'\0'是数组结束标志需先将字符存入{Lcd_WriteData(string1[Lcd_i]); // 显示字符Lcd_i++;Lcd_delay(4);}}void main(){Lcd_Int(); //1602初始化while(1){hanying_show();}}。

51单片机计算器1602显示程序

51单片机计算器1602显示程序
{
delay_jsq(5);
if(P2!=0xfb)
{
if(P2!=0xfb)
{
temp=P2&0xf0;
switch(temp)
{
case 0xe0:num=8;
break;
case 0xd0:num=9;
break;
case 0xb0:num=10;
break;
case 0x70:num=11;
case 0x70:num=7;
break;
}
}
while(P2!=0xfd);
if(j!=0)
{
write_lcd1602(0x01,0);
delay(1);
j=0;
}
if(num==4||num==5||num==6&&num!=7)//如果按下的是'4','5'或'6'
{
if(flag1==0)//没有按过符号键
break;
}
}
}
}
void main()
{
ini_lcd1602();
while(1)
{
keyscan_4_4();
}
}
write_lcd1602(0x06,0);
delay(1);
write_lcd1602(0x01,0);
delay(1);
num_1=0;
i=0;
j=0;
a=0; //第一个参与运算的数
b=0; //第二个参与运算的数
c=0;
flag1=0; //flag1表示是否有符号键按下,
fuhao=0; // fuhao表征按下的是哪个符号

基于51单片机的1602LCD显示

基于51单片机的1602LCD显示

标签:单片机LCD基于51单片机的1602LCD显示基于51单片机的1602LCD显示LCD(liquid crystal display)为液晶显示器,它一般不会单独使用,而是将LCD面板、驱动与控制电路组合成LCD模块(1iquid crystal display moulde,简称为LCM)来使用。

LCM是一种很省电的显示设备,常被应用在数字或微处理器控制的系统,做为简易的人机接口,但人们一般还是习惯称之为LCD显示器。

1 硬件设计采用51单片机控制1602LCD显示器的电路如下所示。

在桌面上双击图标,打开ISIS 7 Professional窗口(本人使用的是v7.4 SP3中文版)。

单击菜单命令“文件”→“新建设计”,选择DEFAULT 模板,保存文件名为“LCD.DSN”。

在器件选择按钮中单击“P”按钮,或执行菜单命令“库”→“拾取元件/符号”,添加如下表51单片机AT89C51 一片晶体CRYSTAL 12MHz 一只瓷片电容CAP 22pF 二只电解电容CAP-ELEC 10uF 一只电阻RES 10K 一只排阻 RESPAC-8 10K 一只1602液晶显示器 LM016L 一只若用Proteus软件进行仿真,则上图中的晶振和复位电路以及U1的31脚,都可以不画,它们都是默认的。

在ISIS原理图编辑窗口中放置元件,再单击工具箱中元件终端图标,在对象选择器中单击POWER和GROUND放置电源和地。

放置好元件后,布好线。

左键双击各元件,设置相应元件参数,完成电路图的设计。

2 软件设计用1602LCD显示两行字符的流程图如下所示。

用1602LCD显示“Welcom to China”和“Hi!Good morning!”的详细C51程序如下。

//用LCD循环显示"Welcome to China"和"Hi!Good morning!"#include<reg51.h> //包含单片机的头文件#include<intrins.h> //包含_nop_()函数定义的头文件sbit RS="P2"^0; //寄存器选择位,将RS位定义为P2.0引脚sbit RW="P2"^1; //读写选择位,将RW位定义为P2.1引脚sbit E="P2"^2; //使能信号位,将E位定义为P2.2引脚sbit BF="P0"^7; //忙碌标志位,,将BF位定义为P0.7引脚unsigned char code string[ ]={"Welcome to China"};unsigned char code string1[ ]={"Hi!Good morning!"};/*************************************************函数功能:延时1ms(3j+2)*i=(3×33+2)×10=1010(微秒),可以认为是1毫秒*************************************************/void delay1ms(){unsigned char i,j;for(i=0;i<10;i++)for(j=0;j<33;j++);}/*****************************函数功能:延时若干毫秒入口参数:n******************************/void delay(unsigned char n){unsigned char i;for(i=0;i<n;i++)delay1ms();}/*******************************************函数功能:判断液晶模块的忙碌状态返回值:result。

51单片机控制基于1602液晶显示 电子时钟【带闹铃和整点报时】

51单片机控制基于1602液晶显示 电子时钟【带闹铃和整点报时】
{
write_date(week6[num]);
delay1();
}
};
break;
}
}
void display() //显示时间子程序
{
write_week(week);
write_ymd(3,year);
write_ymd(6,months);
write_ymd(9,day);
write_sfm(0,shi);
write_sfm(3,fen);
write_sfm(6,miao);
}
void display_1() //显示闹钟子程序
{
write_week(week_1);
write_ymd(3,year1);
write_ymd(6,months1);
write_ymd(9,day1);
write_sfm(0,shi1);
write_com(0x80+add);
write_date(0x30+sh);
write_date(0x30+ge);
}
void write_week(uchar add) //周几显示
{
switch(add)
{
case 0:{
write_com(0x80+12);//设置数据起始地址
for(num=0;num<3;num++)
{
write_date(week3[num]);
delay1();
}
};
break;
case 4:{
write_com(0x80+12);//设置数据起始地址
for(num=0;num<3;num++)

基于51单片机控制的1602液晶电子时钟显示程序

基于51单片机控制的1602液晶电子时钟显示程序

基于51单片机控制的1602液晶电子时钟显示程序[ 2007-05-31 13:31:45 | By: kevin ]刚写好的基于51单片机控制的1602液晶电子时钟显示程序,整理了一下,并尽量加上的注释,放出来大家共享及交流。

有兴趣的可以参考一下,各管脚定义都比较明显,有一定基础的可稍作修改即可进行实验。

//基于51单片机控制的1602液晶电子时钟显示程序#i nclude <intrins.h>#i nclude <at89x51.h>#define uchar unsigned char#define LCM_RS P2_2 //定义引脚#define LCM_RW P2_1#define LCM_E P2_0#define LCM_Data P0#define Busy 0x80 //用于检测LCM状态字中的Busy标识uchar i, j, k, second, tcount, minute, hour;void WriteDataLCM(unsigned char WDLCM);void WriteCommandLCM(unsigned char WCLCM,BuysC);unsigned char ReadDataLCM(void);unsigned char ReadStatusLCM(void);void LCMInit(void);void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData);void DisplayqListChar(unsigned char X, unsigned char Y, unsigned char code *DData);void Delay5Ms(void);void Delay400Ms(void);unsigned char code table[]={'0','1','2','3','4','5','6','7','8','9'};//数码管数字编码unsigned char code MyNo[] = {"NAME:Who_am_I?"};/*************************************************************************** ***************** 函数名称:delay()** 功能描述:延时子程序,大约延时n MS** 输入:** 输出:** 全局变量:** 调用模块:** 作者:kevin** 日期:2007年5月31日**************************************************************************** ****************/delay(uchar n){uchar i,j,k;for(i=2;i>0;i--)for(j=n;j>0;j--)for(k=125;k>0;k--);}/*************************************************************************** ***************** 函数名称:lcd()** 功能描述:液晶初始化,然后在液晶屏第二行显示提示信息** 输入:** 输出:** 全局变量:** 调用模块:Delay400Ms(),LCMInit(),DisplayListChar()** 作者:kevin** 日期:2007年5月31日**************************************************************************** ****************/void lcd(void){Delay400Ms(); //启动等待,等LCM讲入工作状态LCMInit(); //LCM初始化Delay5Ms(); //延时片刻(可不要)DisplayListChar(0, 1, MyNo);}/*************************************************************************** ***************** 函数名称:WriteDataLCM()** 功能描述:写数据** 输入:WDLCM** 输出:** 全局变量:** 调用模块:** 作者:kevin** 日期:2007年5月31日**************************************************************************** ****************/void WriteDataLCM(unsigned char WDLCM){ReadStatusLCM(); //检测忙LCM_Data = WDLCM;LCM_RS = 1;LCM_RW = 0;LCM_E = 0; //若晶振速度太高可以在这后加小的延时LCM_E = 0; //延时LCM_E = 1;}/*************************************************************************** ***************** 函数名称:WriteCommandLCM()** 功能描述:写指令** 输入:** 输出:** 全局变量:** 调用模块:** 作者:kevin** 日期:2007年5月31日**************************************************************************** ****************/void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC为0时忽略忙检测{if (BuysC) ReadStatusLCM(); //根据需要检测忙LCM_Data = WCLCM;LCM_RS = 0;LCM_RW = 0;LCM_E = 0;LCM_E = 0;LCM_E = 1;}/*************************************************************************** ***************** 函数名称:ReadDataLCM()** 功能描述:读数据** 输入:** 输出:** 全局变量:** 调用模块:** 作者:kevin** 日期:2007年5月31日**************************************************************************** ****************/unsigned char ReadDataLCM(void){LCM_RS = 1;LCM_E = 0;LCM_E = 0;LCM_E = 1;return(LCM_Data);}/*************************************************************************** ***************** 函数名称:ReadStatusLCM()** 功能描述:读状态** 输入:** 输出:** 全局变量:** 调用模块:** 作者:kevin** 日期:2007年5月31日**************************************************************************** ****************/unsigned char ReadStatusLCM(void){LCM_Data = 0xFF;LCM_RS = 0;LCM_E = 0;LCM_E = 0;LCM_E = 1;while (LCM_Data & Busy); //检测忙信号return(LCM_Data);}/*************************************************************************** ***************** 函数名称:LCMInit()** 功能描述:LCM初始化** 输入:** 输出:** 全局变量:** 调用模块:** 作者:kevin** 日期:2007年5月31日**************************************************************************** ****************/void LCMInit(void){LCM_Data = 0;WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号Delay5Ms();WriteCommandLCM(0x38,0);Delay5Ms();WriteCommandLCM(0x38,0);Delay5Ms();WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号WriteCommandLCM(0x08,1); //关闭显示WriteCommandLCM(0x01,1); //显示清屏WriteCommandLCM(0x06,1); // 显示光标移动设置WriteCommandLCM(0x0C,1); // 显示开及光标设置}/*************************************************************************** ***************** 函数名称:DisplayOneChar()** 功能描述:按指定位置显示一个字符** 输入:** 输出:** 全局变量:** 调用模块:** 作者:kevin** 日期:2007年5月31日**************************************************************************** ****************/void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData){Y &= 0x1;X &= 0xF; //限制X不能大于15,Y不能大于1if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;X |= 0x80; // 算出指令码WriteCommandLCM(X, 0); //这里不检测忙信号,发送地址码WriteDataLCM(DData);}/*************************************************************************** ***************** 函数名称:DisplayListChar()** 功能描述:按指定位置显示一串字符** 输入:** 输出:** 全局变量:** 调用模块:** 作者:kevin** 日期:2007年5月31日**************************************************************************** ****************/void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData){unsigned char ListLength;ListLength = 0;Y &= 0x1;X &= 0xF; //限制X不能大于15,Y不能大于1while (DData[ListLength]>0x20) //若到达字串尾则退出{if (X <= 0xF) //X坐标应小于0xF{DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符ListLength++;X++;}}}/*************************************************************************** ***************** 函数名称:Delay5Ms()** 功能描述:5ms延时** 输入:** 输出:** 全局变量:** 调用模块:** 作者:kevin** 日期:2007年5月31日**************************************************************************** ****************/void Delay5Ms(void){unsigned int TempCyc = 5552;while(TempCyc--);}/*************************************************************************** ***************** 函数名称:Delay400Ms()** 功能描述:400ms延时** 输入:** 全局变量:** 调用模块:** 作者:kevin** 日期:2007年5月31日**************************************************************************** ****************/void Delay400Ms(void){unsigned char TempCycA = 5;unsigned int TempCycB;while(TempCycA--){TempCycB=7269;while(TempCycB--);};}/*************************************************************************** ***************** 函数名称:timer0()** 功能描述:中断子程序,1秒重写一次液晶,以此实现60秒计数** 输入:** 全局变量:** 调用模块:** 作者:kevin** 日期:2007年5月31日**************************************************************************** ****************/void timer0() interrupt 1 using 0{int i;TH0=(65536-50000)/256*3; //中断设置初始化TL0=(65536-50000)%256*3;tcount++;if(tcount==60) //满1秒{ i=0;DisplayOneChar(i++, 0, 'T'); //在第1行第1个坐标显示DisplayOneChar(i++, 0, 'I'); //在第1行第2个坐标显示DisplayOneChar(i++, 0, 'M'); //在第1行第3个坐标显示DisplayOneChar(i++, 0, 'E'); //在第1行第4个坐标显示DisplayOneChar(i++, 0, ':'); //在第1行第5个坐标显示DisplayOneChar(i++, 0, table[hour/10]); //在第1行第6个坐标显示DisplayOneChar(i++, 0, table[hour%10]); //在第1行第7个坐标显示DisplayOneChar(i++, 0, ':'); //在第1行第1个坐标显示DisplayOneChar(i++, 0, table[minute/10]); //在第1行第8个坐标显示DisplayOneChar(i++, 0, table[minute%10]); //在第1行第9个坐标显示DisplayOneChar(i++, 0, ':'); //在第1行第10个坐标显示DisplayOneChar(i++, 0, table[second/10]); //在第1行第11个坐标显示DisplayOneChar(i++, 0, table[second%10]); //在第1行第12个坐标显示tcount=0;second++;if(second==60) //满1分{second=0;minute++; //分数加1,秒数归零if(minute==60) //满1小时{minute=0;hour++; //小时数加1,分数归零if(hour==24){hour=0;}}}}}/*************************************************************************** ***************** 函数名称:main()** 功能描述:主程序,设置初始时间,中断设置初始化,液晶显示,等待中断** 输入:** 输出:** 全局变量:** 调用模块:** 作者:kevin** 日期:2007年5月31日**************************************************************************** ****************/void main(){uchar i;second=0;minute=0;hour=0; //设置初始时间TH0=(65536-50000)/256; //中断设置初始化TL0=(65536-50000)%256;EA=1;ET0=1;TMOD=0x21;TR0=1;lcd();i=0;DisplayOneChar(i++, 0, 'T'); //在第1行第1个坐标显示DisplayOneChar(i++, 0, 'I'); //在第1行第2个坐标显示DisplayOneChar(i++, 0, 'M'); //在第1行第3个坐标显示DisplayOneChar(i++, 0, 'E'); //在第1行第4个坐标显示DisplayOneChar(i++, 0, ':'); //在第1行第5个坐标显示DisplayOneChar(i++, 0, table[hour/10]); //在第1行第6个坐标显示DisplayOneChar(i++, 0, table[hour%10]); //在第1行第7个坐标显示DisplayOneChar(i++, 0, ':'); //在第1行第1个坐标显示DisplayOneChar(i++, 0, table[minute/10]); //在第1行第8个坐标显示DisplayOneChar(i++, 0, table[minute%10]); //在第1行第9个坐标显示DisplayOneChar(i++, 0, ':'); //在第1行第10个坐标显示DisplayOneChar(i++, 0, table[second/10]); //在第1行第11个坐标显示DisplayOneChar(i++, 0, table[second%10]); //在第1行第12个坐标显示while(1); //等待中断}。

超强的51+LCD1602控制(四位,八位控制),1602函数全集+写入字库

超强的51+LCD1602控制(四位,八位控制),1602函数全集+写入字库

风骚的51+LCD1602控制(四位,八位控制),1602函数全集+写入字库LCD1602写字库在文档后面。

LCD1602演示程序(很多函数哦)控制芯片为HD44780函数都是经过测试的,实物显示都通过了,呵呵,请大家放心使用^_^呵呵,支持四线数据接口模式,可以任意切换编程,只须改模式选择Port_Type_Select就可以咯!很方便的。

并且我说一下我的个人体会,希望大家在写程序的时候,最好考虑一下程序的可移植性,而且要方便更改参数和硬件资源的选择,最好使用条件编译,任意切换硬件资源,可以方便以后更改参数,就会省去以后不少的不必要的麻烦和错误以及宝贵的时间里面有标准测试,如果您觉得好的话,请您帮忙顶一下,,写出更好的功能函数。

先简单介绍一下功能函数吧:/*--------------------------------------------------------------*/ //模式选择(条件编译)#define Port_Type_Select 1 //=1, 选择八位数据模式//=0, 选择四位数据模式, LCD高四位接MCU端口高四位/*--------------------------------------------------------------*/ //函数声明void LCD_busy (void); //检测LCD是否忙void LCD_init (void); //LCD初始化void LCD_cmd (unsigned char cmd); //写入指令void LCD_dat (unsigned char dat); //写入数据void LCD_pos (unsigned char x, unsigned char y); //显示定位void LCD_printc(unsigned char x, unsigned char y, unsigned char c); //定位输出字符void LCD_prints(unsigned char x, unsigned char y, unsigned char *s); //定位输出字符串void LCD_printn(unsigned char x, unsigned char y, unsigned int num); //定位输出16位二进制数字unsigned char LCD_current_addr(void); //读出AC当前地址(DB6~DB0)或忙标志位DB7unsigned char LCD_current_addr_dat(void); //读出AC当前地址的数据unsigned char LCD_addr_dat(unsigned char x, unsigned char y); //读出AC指定地址的数据void LCD_pos_CG(unsigned char x, unsigned char *CGRAM_dat); //指定地址(x: 0-7)写入8bytes数据CGRAM/*-------------------------------------------------------------*///光标、画面移动,不影响DDRAM#define LCD_LEFT_MOVE LCD_cmd(0x18); //LCD显示左移一位#define LCD_RIGHT_MOVE LCD_cmd(0x1c); //LCD显示右移一位#define LCD_CURSOR_LEFT_MOVE LCD_cmd(0x10); //光标左移一位#define LCD_CURSOR_RIGHT_MOVE LCD_cmd(0x14); //光标右移一位/*--------------------------------------------------------------*///设置显示、光标及闪烁开、关#define LCD_DISPLAY_ON LCD_cmd(0x0c); //LCD开显示#define LCD_DISPLAY_OFF LCD_cmd(0x08); //LCD关显示#define LCD_CURSOR_ON LCD_cmd(0x0e); //光标显示#define LCD_CURSOR_OFF LCD_cmd(0x0c); //光标不显示#define LCD_CURSOR_BLINK_ON LCD_cmd(0x0f); //光标闪烁#define LCD_CURSOR_BLINK_OFF LCD_cmd(0x0e); //光标不闪烁#define LCD_GO_HOME LCD_cmd(0x02); //AC=0,光标、画面回HOME位, DDRAM内容不变#define LCD_CLR LCD_cmd(0x01); //LCD清屏, 清除DDRAM, 清除屏幕, 置AC为0, 光标回位?/*--------------------------------------------------------------*///工作方式设置#define LCD_DISPLAY8_DOUBLE_LINE LCD_cmd(0x38); //两行显示8-bits#define LCD_DISPLAY8_SINGLE_LINE LCD_cmd(0x30); //单行显示8-bits#define LCD_DISPLAY4_DOUBLE_LINE LCD_cmd(0x28); //两行显示4-bits#define LCD_DISPLAY4_SINGLE_LINE LCD_cmd(0x20); //单行显示4-bits/*--------------------------------------------------------------*///输入方式设置#define LCD_AC_AUTO_INCREMENT LCD_cmd(0x06); //数据读、写操作后,AC 自动加 1#define LCD_AC_AUTO_DECREASE LCD_cmd(0x04); //数据读、写操作后,AC自动减 1#define LCD_MOVE_ENABLE LCD_cmd(0x07); //数据读、写操作,画面平移#define LCD_MOVE_DISENABLE LCD_cmd(0x06); //数据读、写操作,画面不动以下是液晶驱动头文件:/*--------------------------------------------------------------*/ //File: LCD1602_8A.H//Time: 20:10//Modi: 09-5-17/*--------------------------------------------------------------*/ //防止被重复定义#ifndef __LCD1602_8A_H__#define __LCD1602_8A_H__/*--------------------------------------------------------------*/ //模式选择(条件编译)#define Port_Type_Select 1 //=1, 选择八位数据模式//=0, 选择四位数据模式, LCD高四位接MCU端口高四位#define Int_Transfer 1 //=1, 允许中断服务函数调用//=0, 不允许中断服务函数调用/*--------------------------------------------------------------*/ //LCD1602与单片机接口定义sfr LCD_IO = 0x80; //P0-0x80,P1-0x90,P2-0xA0,P3-0xB0;sbit LCD_RS = P2^0; //LCD数据/命令选择端(H/L)sbit LCD_RW = P2^1; //LCD 读/写选择端(H/L)sbit LCD_EN = P2^2; //LCD使能控制端/*--------------------------------------------------------------*/ //工作方式设置#define LCD_DISPLAY8_DOUBLE_LINE LCD_cmd(0x38); //两行显示8-bits #define LCD_DISPLAY8_SINGLE_LINE LCD_cmd(0x30); //单行显示8-bits #define LCD_DISPLAY4_DOUBLE_LINE LCD_cmd(0x28); //两行显示4-bits #define LCD_DISPLAY4_SINGLE_LINE LCD_cmd(0x20); //单行显示4-bits/*--------------------------------------------------------------*/ //输入方式设置#define LCD_AC_AUTO_INCREMENT LCD_cmd(0x06); //数据读、写操作后,AC 自动加 1#define LCD_AC_AUTO_DECREASE LCD_cmd(0x04); //数据读、写操作后,AC自动减 1#define LCD_MOVE_ENABLE LCD_cmd(0x07); //数据读、写操作,画面平移#define LCD_MOVE_DISENABLE LCD_cmd(0x06); //数据读、写操作,画面不动/*--------------------------------------------------------------*///设置显示、光标及闪烁开、关#define LCD_DISPLAY_ON LCD_cmd(0x0c); //LCD开显示#define LCD_DISPLAY_OFF LCD_cmd(0x08); //LCD关显示#define LCD_CURSOR_ON LCD_cmd(0x0e); //光标显示#define LCD_CURSOR_OFF LCD_cmd(0x0c); //光标不显示#define LCD_CURSOR_BLINK_ON LCD_cmd(0x0f); //光标闪烁#define LCD_CURSOR_BLINK_OFF LCD_cmd(0x0e); //光标不闪烁#define LCD_GO_HOME LCD_cmd(0x02); //AC=0,光标、画面回HOME位, DDRAM内容不变#define LCD_CLR LCD_cmd(0x01); //LCD清屏, 清除DDRAM, 清除屏幕, 置AC为0, 光标回位?/*--------------------------------------------------------------*///光标、画面移动,不影响DDRAM#define LCD_LEFT_MOVE LCD_cmd(0x18); //LCD显示左移一位#define LCD_RIGHT_MOVE LCD_cmd(0x1c); //LCD显示右移一位#define LCD_CURSOR_LEFT_MOVE LCD_cmd(0x10); //光标左移一位#define LCD_CURSOR_RIGHT_MOVE LCD_cmd(0x14); //光标右移一位/*--------------------------------------------------------------*///LCD1602地址相关/*#define LINE1_HEAD 0x80 //第一行DDRAM起始地址#define LINE2_HEAD 0xc0 //第二行DDRAM起始地址#define LINE1 0 //第一行#define LINE2 1 //第二行#define LINE_LENGTH 16 //每行的最大字符长度(40-DDRAM)/*--------------------------------------------------------------*/ //函数声明void LCD_busy (void); //检测LCD是否忙void LCD_init (void); //LCD初始化void LCD_cmd (unsigned char cmd); //写入指令void LCD_dat (unsigned char dat); //写入数据void LCD_pos (unsigned char x, unsigned char y); //显示定位void LCD_printc(unsigned char x, unsigned char y, unsigned char c); //定位输出字符void LCD_prints(unsigned char x, unsigned char y, unsigned char *s); //定位输出字符串void LCD_printn(unsigned char x, unsigned char y, unsigned int num); //定位输出16位二进制数字unsigned char LCD_current_addr(void); //读出AC当前地址(DB6~DB0)或忙标志位DB7unsigned char LCD_current_addr_dat(void); //读出AC当前地址的数据unsigned char LCD_addr_dat(unsigned char x, unsigned char y); //读出AC指定地址的数据void LCD_pos_CG(unsigned char x, unsigned char *CGRAM_dat); //指定地址(x: 0-7)写入8bytes数据CGRAM/*--------------------------------------------------------------*/ //读出AC当前地址(DB6~DB0)或忙标志位DB7#if Port_Type_Select //选择八位数据模式unsigned char LCD_current_addr(void){unsigned char ac_addr;LCD_EN = 0;LCD_RS = 0; //指令LCD_RW = 1; //读出LCD_IO = 0xff; //端口置为输入方式(P0)LCD_EN = 1;ac_addr = LCD_IO;LCD_EN = 0;return (ac_addr);}#else //选择四位数据模式unsigned char LCD_current_addr(void){unsigned char ac_addr;LCD_EN = 0;LCD_RS = 0; //指令LCD_RW = 1; //读出LCD_IO |= 0xf0; //端口置为输入方式(P0)LCD_EN = 1;ac_addr = LCD_IO & 0xf0; //高四位LCD_EN = 0;LCD_EN = 1;ac_addr |= LCD_IO >> 4; //低四位LCD_EN = 0;return (ac_addr);}#endif/*--------------------------------------------------------------*/ //检测LCD忙状态#if Int_Transfer //允许中断服务函数调用void LCD_busy(void){unsigned char ac_dat;unsigned char busy_flag;do{ac_dat = LCD_current_addr();busy_flag = ac_dat & 0x80;}while(busy_flag); //=1表示忙, =0表示空闲}#else //不允许中断服务函数调用void LCD_busy(void){unsigned char ac_dat;bit busy_flag;do{ac_dat = LCD_current_addr();busy_flag = (bit)(ac_dat & 0x80);}while(busy_flag); //=1表示忙, =0表示空闲}#endif/*--------------------------------------------------------------*/ //读出AC当前地址的数据#if Port_Type_Select //选择八位数据模式unsigned char LCD_current_addr_dat(void){unsigned char addr_dat;// unsigned char i;LCD_busy(); //或者检查忙最可靠// for(i = 0; i < 3; i++) //要连续读出三次才会有效{LCD_EN = 0;LCD_RS = 1; //数据LCD_RW = 1; //读出LCD_IO = 0xff; //端口置为输入方式(P0)LCD_EN = 1;addr_dat = LCD_IO;LCD_EN = 0;}return (addr_dat);}#else //选择四位数据模式unsigned char LCD_current_addr_dat(void){unsigned char addr_dat;// unsigned char i;LCD_busy(); //或者检查忙最可靠// for(i = 0; i < 3; i++) //要连续读出三次才会有效{LCD_EN = 0;LCD_RS = 1; //数据LCD_RW = 1; //读出LCD_IO |= 0xf0; //端口置为输入方式(P0)LCD_EN = 1;addr_dat = LCD_IO & 0xf0; //高四位LCD_EN = 0;LCD_EN = 1;addr_dat |= LCD_IO >> 4; //低四位LCD_EN = 0;}return (addr_dat);}#endif/*--------------------------------------------------------------*/ //写入指令#if Port_Type_Select //选择八位数据模式void LCD_cmd(unsigned char cmd){LCD_busy(); //检测忙LCD_RS = 0; //指令LCD_RW = 0; //写入LCD_EN = 1;LCD_IO = cmd; //传指令LCD_EN = 0; //下降沿有效}#else //选择四位数据模式void LCD_cmd(unsigned char cmd){LCD_busy(); //检测忙LCD_IO &= 0x0f; //清高四位LCD_RS = 0; //指令LCD_RW = 0; //写入LCD_EN = 1;LCD_IO |= cmd & 0xf0; //写高四位LCD_EN = 0; //下降沿有效cmd <<= 4; //低四位移到高四位LCD_IO &= 0x0f; //清高四位LCD_EN = 1;LCD_IO |= cmd & 0xf0; //写高四位LCD_EN = 0; //下降沿有效}#endif/*--------------------------------------------------------------*/ //写入数据#if Port_Type_Select //选择八位数据模式void LCD_dat(unsigned char dat){LCD_busy(); //检测忙LCD_RS = 1; //数据LCD_RW = 0; //写入LCD_EN = 1;LCD_IO = dat; //传数据LCD_EN = 0; //下降沿有效}#else //选择四位数据模式void LCD_dat(unsigned char dat){LCD_busy(); //检测忙LCD_IO &= 0x0f; //清高四位LCD_RS = 1; //数据LCD_RW = 0; //写入LCD_EN = 1;LCD_IO |= dat & 0xf0; //写高四位LCD_EN = 0; //下降沿有效dat <<= 4; //低四位移到高四位LCD_IO &= 0x0f; //清高四位LCD_EN = 1;LCD_IO |= dat & 0xf0; //写高四位LCD_EN = 0; //下降沿有效}#endif/*--------------------------------------------------------------*/ //显示定位DDRAMvoid LCD_pos(unsigned char x, unsigned char y){if(y) LCD_cmd(x|0xc0);//y=1第二行显示,y=0第一行显示0<=x<16(40-DDRAM)else LCD_cmd(x|0x80);//数据指针=80+地址码(00H~27H,40H~67H)}/*--------------------------------------------------------------*/ //指定地址(x: 0-7)写入8bytes数据CGRAMvoid LCD_pos_CG(unsigned char x, unsigned char *CGRAM_dat){unsigned char i;x <<= 3; //转化为6位数据的高三位x |= 0x40;LCD_cmd(x); //写入地址for(i = 0; i < 8; i++)LCD_dat(CGRAM_dat[i]); //写入数据}/*--------------------------------------------------------------*/ //读出AC指定地址的数据unsigned char LCD_addr_dat(unsigned char x, unsigned char y){unsigned char addr_dat;LCD_pos(x, y); //定位addr_dat = LCD_current_addr_dat(); //读出数据return (addr_dat);}/*--------------------------------------------------------------*/ //定位输出字符void LCD_printc(unsigned char x, unsigned char y, unsigned char c) {LCD_pos(x, y);LCD_dat(c);}/*--------------------------------------------------------------*/ //定位输出字符串void LCD_prints(unsigned char x, unsigned char y, unsigned char *s) {LCD_pos(x, y);while(*s){LCD_dat(*s);s++;}}/*--------------------------------------------------------------*/ //定位输出16位二进制数字// 0<= num <65536void LCD_printn(unsigned char x, unsigned char y, unsigned int num) {char i;unsigned char ii;unsigned char dat[6];for(i = 0; i < 6; i++) dat[i] = 0; i = 0; //初始化数据while(num / 10) //拆位{dat[i] = num % 10; //最低位num /= 10; i++;}dat[i] = num; //最高位ii = i; //保存dat的位数for(; i >= 0; i--) dat[i] += 48; //转化成ASCIILCD_prints(x, y, " "); //清显示区域LCD_pos(x, y);for(i = ii; i >= 0; i--) LCD_dat(dat[i]); //输出数字字符}/*--------------------------------------------------------------*/ //LCD初始化void LCD_init(void){#if Port_Type_Select //选择八位数据模式LCD_DISPLAY8_DOUBLE_LINE //设置LCD为16X2显示,5X7点阵,八位数据接口#elseLCD_DISPLAY4_DOUBLE_LINE //设置LCD为16X2显示,5X7点阵,四位数据接口#endifLCD_AC_AUTO_INCREMENT //LCD显示光标移动设置(光标地址指针加1,整屏显示不移动)LCD_DISPLAY_ON //LCD开显示及光标设置(光标不闪烁,不显示"_") LCD_CLR //清屏}/*--------------------------------------------------------------*/ [原创] 液晶1602 显示汉字研究液晶, 汉字, 研究1602是一款最常用也是最便宜的液晶显示屏。

51单片机控制基于1602液晶显示 电子时钟【带闹铃和整点报时】

51单片机控制基于1602液晶显示 电子时钟【带闹铃和整点报时】
void buzz_pro(uchar be)//蜂鸣器发声函数
{
switch(be)
{//uint i;
/*用于整点响铃*/case 0:{
buzz=~buzz;
//delay1();
}break;
/*用于闹铃报时*/case 1:{
buzz=~buzz;
//delay(10);
}break;
}
}
void write_com(uchar com)//命令写入函数
{
rs=0;
delay(3);
P0=com;
delay(3);
lcden=1;
delay(3);
lcden=0;
}
void write_date(uchar date)//数据写入函数
{
rs=1;
delay(3);
P0=date;
delay(3);
write_date(0x30+ge);
}
void write_ymd(uchar add,uchar date)//年月日写入子程序
{
uchar sh,ge;
sh=date/10;
ge=date%10;
write_com(0x80+add);
write_date(0x30+sh);
write_date(0x30+ge);
sbit buzz=P1^5; //蜂鸣器控制端
uchar code week0[]="Sun";
uchar code week1[]="Mon";
uchar code week2[]="Tue";

基于51单片机的1602LCD显示

基于51单片机的1602LCD显示

标签:单片机LCD基于51单片机的1602LCD显示基于51单片机的1602LCD显示LCD(liquid crystal display)为液晶显示器,它一般不会单独使用,而是将LCD面板、驱动与控制电路组合成LCD模块(1iquid crystal display moulde,简称为LCM)来使用。

LCM是一种很省电的显示设备,常被应用在数字或微处理器控制的系统,做为简易的人机接口,但人们一般还是习惯称之为LCD显示器。

1 硬件设计采用51单片机控制1602LCD显示器的电路如下所示。

在桌面上双击图标,打开ISIS 7 Professional窗口(本人使用的是v7.4 SP3中文版)。

单击菜单命令“文件”→“新建设计”,选择DEFAULT 模板,保存文件名为“LCD.DSN”。

在器件选择按钮中单击“P”按钮,或执行菜单命令“库”→“拾取元件/符号”,添加如下表所示的元件。

51单片机AT89C51 一片晶体CRYSTAL 12MHz 一只瓷片电容CAP 22pF 二只电解电容CAP-ELEC 10uF 一只电阻RES 10K 一只排阻RESPAC-8 10K 一只1602液晶显示器LM016L 一只若用Proteus软件进行仿真,则上图中的晶振和复位电路以及U1的31脚,都可以不画,它们都是默认的。

在ISIS原理图编辑窗口中放置元件,再单击工具箱中元件终端图标,在对象选择器中单击POWER和GROUND放置电源和地。

放置好元件后,布好线。

左键双击各元件,设置相应元件参数,完成电路图的设计。

2 软件设计用1602LCD显示两行字符的流程图如下所示。

用1602LCD显示“Welcom to China”和“Hi!Good morning!”的详细C51程序如下。

//用LCD循环显示"Welcome to China"和"Hi!Good morning!"#include<reg51.h> //包含单片机的头文件#include<intrins.h> //包含_nop_()函数定义的头文件sbit RS="P2"^0; //寄存器选择位,将RS位定义为P2.0引脚sbit RW="P2"^1; //读写选择位,将RW位定义为P2.1引脚sbit E="P2"^2; //使能信号位,将E位定义为P2.2引脚sbit BF="P0"^7; //忙碌标志位,,将BF位定义为P0.7引脚unsigned char code string[ ]={"Welcome to China"};unsigned char code string1[ ]={"Hi!Good morning!"};/*************************************************函数功能:延时1ms(3j+2)*i=(3×33+2)×10=1010(微秒),可以认为是1毫秒*************************************************/void delay1ms(){unsigned char i,j;for(i=0;i<10;i++)for(j=0;j<33;j++);}/*****************************函数功能:延时若干毫秒入口参数:n******************************/void delay(unsigned char n){unsigned char i;for(i=0;i<n;i++)delay1ms();}/*******************************************函数功能:判断液晶模块的忙碌状态返回值:result。

基于51单片机定时器的1602液晶显示器时钟显示(带年月日)

基于51单片机定时器的1602液晶显示器时钟显示(带年月日)

基于51单⽚机定时器的1602液晶显⽰器时钟显⽰(带年⽉⽇)#include#define uchar unsigned char#define uint unsigned intuchar a,count,S1num,xqnum;char yue,ri,shi,fen,miao;int nian;sbit lcdrs=P2^5;sbit lcdrw=P2^4;sbit lcden=P2^3;sbit S1=P3^0; //定义键——进⼊设置sbit S2=P3^1; //定义键——增⼤sbit S3=P3^2; //定义键——减⼩sbit S4=P3^3; //定义键——退出设置uchar code table0[]="2014-08-13 WED";uchar code table1[]="00:00:00";uchar code xingqi[][3]={"MON","TUE","WED","THU","FRI","SAT","SUN"};void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}/**************************************************1602液晶显⽰器模块sbit lcdrs=P2^5;sbit lcdrw=P2^4;sbit lcden=P2^3;*************************************************/void write_com(uchar com) //液晶写指令{lcdrw=0;P0=com;delay(5);lcden=1;delay(5);lcden=0;}void write_data(uchar dat) //液晶写数据{lcdrw=0;lcdrs=1;P0=dat;delay(5);lcden=1;delay(5);lcden=0;}/********************************************年⽉⽇写⼊1602函数********************************************/void write_sfm(uchar add,uchar dat) //写时分秒函数{ uchar shi,ge;shi=dat/10;ge=dat%10;write_com(0x80+0x40+add);write_data(0x30+shi);write_data(0x30+ge);}void write_yr(uchar add,uchar dat) //写⽉⽇函数{uchar shi,ge;shi=dat/10;ge=dat%10;write_com(0x80+add);write_data(0x30+shi);}void write_nian(uchar add,uint dat) //写年函数{uint qian,bai,shi,ge;qian=dat/1000;bai=dat%1000/100;shi=dat%100/10;ge=dat%10;write_com(0x80+add);write_data(0x30+qian);write_data(0x30+bai);write_data(0x30+shi);write_data(0x30+ge);/***************************************************初始化***************************************************/void init_lcd() //液晶初始化{lcden=0;nian=2014;yue=8;ri=13;shi=0; //初始shi、fen、miaofen=0;miao=0;write_com(0x38); //设置16x2显⽰,5x7点阵,8位数据⼝write_com(0x0c); //设置开显⽰,不显⽰光标write_com(0x06); //写⼀个字符后地址指针加1write_com(0x01); //显⽰清0,数据指针清0}void init() //初始化函数{init_lcd(); //液晶初始化write_com(0x80); //设置显⽰初始坐标for(a=0;a<14;a++) //显⽰年⽉⽇初始值write_data(table0[a]);delay(5);}write_com(0x80+0x40); //设置显⽰初始坐标for(a=0;a<8;a++) //显⽰时分秒初始值{write_data(table1[a]);delay(5);}write_nian(0,nian);write_sfm(6,miao); //分别将shi、fen、miao送去液晶显⽰write_sfm(3,fen);write_sfm(0,shi);count=0;xqnum=0;S1num=0; //初始化全局变量countTMOD=0x01; //设置定时器0⼯作模式1 TH0=(65535-50000)/256; //定时器装初始值TL0=(65535-50000)%256;EA=1; //开总中断ET0=1; //开定时器0中断TR0=1; //启动定时器0}/**************************************************独⽴键盘sbit S1=P3^0; //定义键——进⼊设置sbit S2=P3^1; //定义键——增⼤sbit S3=P3^2; //定义键——减⼩sbit S4=P3^3; //定义键——退出设置独⽴键盘已接地*************************************************/void keyscan(){if(S1==0){delay(5); //确认定义键被按下{S1num++; //定义键S1按下次数记录while(!S1); //释放按键确认if(S1num==1) //S1按下⼀次时{TR0=0; //关闭定时器write_com(0xc0+7); //光标定位到秒位置write_com(0x0f); //光标闪烁}if(S1num==2) //S1按下两次时{write_com(0xc0+4); //光标定位到分位置}if(S1num==3) //S1按下三次时{write_com(0xc0+1); //光标定位到时位置}if(S1num==4) //S1按下四次时{write_com(0x80+13); //光标定位到星期位置}if(S1num==5) //S1按下五次时{write_com(0x80+9); //光标定位到⽇位置}if(S1num==6) //S1按下六次时{write_com(0x80+6); //光标定位到⽉位置}if(S1num==7) //S1按下七次时{write_com(0x80+3); //光标定位到年位置}if(S1num==8) //S1按下⼋次时S1num=0; //S1记录按键次数清零TR0=1; //开启定时器write_com(0x0c); //取消光标闪烁}}}if(S1num!=0) //只有定义键按下后S2、S3、S4才有效{ if(S2==0){delay(5); //防抖if(S2==0) //确认按键被按下{while(!S2); //释放按键确认if(S1num==1) //S1按下⼀次时{miao++; //调整秒加1if(miao==60) //满60清零miao=0;write_sfm(6,miao); //每调节⼀次送液晶显⽰⼀次write_com(0x80+0x40+6); //显⽰位置重新回到调节处} if(S1num==2) //S1按下两次时{fen++; //调整分加1if(fen==60)fen=0;write_sfm(3,fen);write_com(0x80+0x40+3);}if(S1num==3) //S1按下三次时{shi++; //调整时加1if(shi==24)shi=0;write_com(0x80+0x40);}if(S1num==4) //星期加调整{ xqnum++;if(xqnum==7)xqnum=0;write_com(0x80+0x0b);for(a=0;a<3;a++){write_data(xingqi[xqnum][a]); delay(5);}}if(S1num==5) //⽇加调整{ri++;if(yue==2){if(nian%400==0){if(ri==30){ri=1;}}if(nian%400!=0){if(ri==29){ri=1;}}}else if(yue<=7){if(yue%2==0&yue!=2){ri=1;}}else if(yue%2!=0&yue!=2) {if(ri==32){ri=1;}}}else if(yue>=8){if(yue%2==0){if(ri==32){ri=1;}}else if(yue%2!=0){if(ri==31){ri=1;}}}write_yr(8,ri);}if(S1num==6) //⽉加调整{ yue++;write_yr(5,yue);}if(S1num==7) //年加调整{nian++;if(nian==2019)nian=2014;write_nian(0,nian);}}}if(S3==0){delay(5);if(S3==0) //确认按键被按下{while(!S3);if(S1num==1){miao--; //调整秒减1if(miao==-1) //减到00后再减重新设置为59 miao=59;write_sfm(6,miao);write_com(0x80+0x40+6);}if(S1num==2){fen--; //调整分减1if(fen==-1)fen=59;write_sfm(3,fen);write_com(0x80+0x40+3);}if(S1num==3)shi--; //调整时减1if(shi==-1)shi=23;write_sfm(0,shi);write_com(0x80+0x40);}if(S1num==4){xqnum--; //调整星期减⼀if(xqnum==-1)xqnum=6;write_com(0x80+0x0b);for(a=0;a<3;a++){write_data(xingqi[xqnum][a]); delay(5);}}if(S1num==5) //调整⽇{ri--;if(yue==2){if(nian%400==0){if(ri==0){ri=29;}}if(nian%400!=0){if(ri==0){ri=28;}else if(yue<=7){if(yue%2==0&yue!=2){if(ri==0){ri=30;}}else if(yue%2!=0&yue!=2) {if(ri==0){ri=31;}}}else if(yue>=8){if(yue%2==0){if(ri==0){ri=31;}}else if(yue%2!=0){if(ri==0){ri=30;}}write_yr(8,ri);}if(S1num==6) //调整⽉{yue--;if(yue==0)yue=12;write_yr(5,yue);}if(S1num==7) //调整年{nian--;if(nian==2013)nian=2018;write_nian(0,nian);}}}if(S4==0) //退出设置、开启中断{delay(5);if(S4==0){S1num=0;TR0=1;write_com(0x0c);}}}}/**************************************************定时器0*************************************************/ void timer0() interrupt 1 //定时器0中断服务程序TH0=(65535-50000)/256; //重装定时器初始值TL0=(65535-50000)%256; count++; //中断次数累加if(count==20) //20次50毫秒即⼀秒{count=0;miao++;if(miao==60) //秒加到60时分进位{miao=0;fen++;if(fen==60) //分加到60时时进位{fen=0;shi++;if(shi==24) //时加到24时清0{shi=0;xqnum++;ri++;if(yue==2) //如果是⼆⽉{if(nian%400==0) //闰年判断{if(ri==30){ri=1;yue++;write_yr(5,yue);}}if(nian%400!=0) //平年判断{if(ri==29){ri=1;yue++;write_yr(5,yue);}}}else if(yue<=7&yue!=2) //⼀⽉到七⽉{if(yue%2==0) //偶数⽉(除⼆⽉){if(ri==31){ri=1;yue++;}}else if(yue%2!=0) //奇数⽉{if(ri==32){ri=1;yue++;}}write_yr(5,yue);}else if(yue>=8) //⼋⽉到12⽉{if(yue%2==0) //偶数⽉(除⼆⽉){if(ri==32){ri=1;yue++;if(yue==13) //如果判断⽉份为12⽉,则加⼀后重新定义⽉份为1{yue=1;nian++;write_nian(0,nian);}write_yr(5,yue);}}else if(yue%2!=0) //奇数⽉{if(ri==31){ri=1;yue++;write_yr(5,yue);}}}write_yr(8,ri);if(xqnum==7) //星期写⼊xqnum=0;write_com(0x80+0x0b);for(a=0;a<3;a++){write_data(xingqi[xqnum][a]); delay(5);}}write_sfm(0,shi); //重新写⼊数据}write_sfm(3,fen); //重新写⼊数据}write_sfm(6,miao); //重新写⼊数据}}/*************************************************主函数*************************************************/ void main(){init();while(1){keyscan(); //不停的检测按键是否被按下} }。

基于MCS-51单片机的液晶1602显示设计

基于MCS-51单片机的液晶1602显示设计


J J _ 一 十 卜
) c
wr i t e
_
a d d ( d ) ;
j }
v o i d LCD 1 6 0 2
_
垃 ; P 1 7
P o 6
71 4 .
I N Tl
1 I o . 2
1 6 0 2 , 实 现 显 示 字符 的效 果 。 }
wh i l e ( x 一 一 )
e =O :
vo i d L CD

d i r v e ( b i t x , u c h a r d ]

i f ( x = = 1 )
2 、 硬件组成 液晶1 6 0 2 显示系统实际是由5 1 单片机最 小系统 、 液 晶1 6 0 2 构成 , 如下 图
P 0 1 3 p !


. P , P l
. .. . . .

7 8 l

P1 5 Pt 6 R硒 T D 订
;8 0 5 1螂 P 0 2 = = i 鐾 } j …
P o 4 P 0 5 P0 7 P 2 O P 2 1
1 所示 。


wr i t e
_
d a t a ( d ) ;

p 1 0
P1 2


V C C j 盐 ) ” 睫晶l 鳓 L l
l 4 0


e l s e
- . . . ‘ 一 P I 1
; 4
P o o { 噩p o } _ _
_

e = 0 : L CD1 6 0 2

51单片机控制LCD液晶1602源代码

51单片机控制LCD液晶1602源代码
void Lcd1602_Clear_Line(unsigned char line);
void Lcd1602_Clear_All(void);
void Lcd1602_Demo1(void);
void Lcd1602_Demo2(void);
void Delay_ms(unsigned char second);
if(++row==3)
return;
else
{
switch(row)//这种结构保持以后升级到多行显示液晶
_nop_();
LCD_EN=HIGH ;
_nop_();
LCD_EN=LOW;
LCD_DATA_PORT=0xFF; //prevent port is 0.
}
//===========================
case 2:Lcd1602_Write_Command(0x80+0x40);break; //将数据地址指针定位到第二行
default: break;
}
}
//==================================================
{
while(1)
{
Lcd1602_Demo1();
// Lcd1602_Demo2();
}
}
void Lcd1602_Ini(void)
{
Delay_ms(20);
Lcd1602_Write_Command_Nocheck(0x38);//设定LCD为16*2显示,5*7点阵,8位数据接口
{
Lcd1602_Write_String(row,column," ");

(完整word版)1602液晶时钟程序(51单片机)

(完整word版)1602液晶时钟程序(51单片机)

1602液晶时钟程序程序按郭天袢《新概念51单片机C语言教程》第十四章扩展显示年、月、日、星期调节功能。

1)时间显示在1602液晶上,并按秒实时更新2)能调节按键调整时、分、秒、年、月、日和星期3)每次按键按下时有短滴声响声4)断电后下次上电会接着上次断电前的时间数继续运行原理图如图//原代码如下:#include<reg52.h>//#include"24c02.h"#define uchar unsigned char#define uint unsigned int#include"24c02.h"sbit dula=P2^6;sbit wela=P2^7;sbit LCDEN=P3^4;sbit LCDRS=P3^5;sbit s1=P3^0;//定义按键--功能键sbit s2=P3^1;//定义按键--增大键sbit s3=P3^2;//定义按键--减小键sbit rd=P3^7;//按键公共脚sbit beep=P2^3;//定义蜂鸣器脚uchar count,s1_num;//定义中断次数计数变量功能键按键次数变量uchar week,day,month,year;//定义变量:星期日月年char miao,shi,fen;//定义秒分时变量uchar code table[]=" 2012-11-28 Wed";//void write_week(char we);//显示星期几函数void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void di()//蜂鸣器响一声函数{beep=0;delay(100);beep=1;}void write_com(uchar com) //液晶写命令函数{LCDRS=0;P0=com;delay(5);LCDEN=1;delay(5);LCDEN=0;}void write_date(uchar date) //液晶写数据函数{LCDRS=1;P0=date;delay(5);LCDEN=1;delay(5);LCDEN=0;}void write_week(char we) //写星期几显示函数{write_com(0x80+12);switch(we){case 1: write_date('M');delay(5); //星期一Mondaywrite_date('o');delay(5);write_date('n');delay(5);break;case 2: write_date('T');delay(5); //星期二Tuesdaywrite_date('u');delay(5);write_date('e');delay(5);break;case 3: write_date('W');delay(5); //Wednesdaywrite_date('e');delay(5);write_date('d');delay(5);break;case 4: write_date('T');delay(5); //Thursdaywrite_date('h');delay(5);write_date('u');delay(5);break;case 5: write_date('F');delay(5); //星期五Fridaywrite_date('r');delay(5);write_date('i');delay(5);break;case 6: write_date('S');delay(5); //星期六Saturdaywrite_date('a');delay(5);write_date('t');delay(5);break;case 7: write_date('S');delay(5); //星期日Sundaywrite_date('u');delay(5);write_date('n');delay(5);break;default: break;}}void write_sfm(uchar add,uchar date) //写时分秒函数{uchar shiwei,gewei;shiwei=date/10;gewei=date%10;write_com(0x80+0x40+add);//设置显示位置write_date(0x30+shiwei);//加上0x30是因为数字变成字符串需要加上0x30,看ASCII码值与字符的关系write_date(0x30+gewei);}void write_year_month_day(uchar add,uchar day) //写年月日数函数{uchar shi,ge;shi=day/10;ge=day%10;write_com(0x80+add);//设置显示位置write_date(0x30+shi);//加上0x30是因为数字变成字符串需要加上0x30,看ASCII码值与字符的关系write_date(0x30+ge);}void init() //初始化函数{uchar num;rd=0;beep=1;dula=0;wela=0;LCDEN=0;//将使能端置0以完成高脉冲fen=0;miao=0;shi=0;count=0;//计数初始为0init_24c02();write_com(0x38);//设置16*2显示,5*7点阵,8位数据接口write_com(0x0c);//设置开显示,不显示光标write_com(0x06);//写一个字符后地址指针自动加1write_com(0x01);//显示清0,数据指针清0write_com(0x80); //设置显示初始坐标for(num=0;num<15;num++) //显示年月日{write_date(table[num]);delay(5);}write_com(0x80+0x40+6); //写出时间显示部分的两个冒号write_date(0x3a);delay(5);write_com(0x80+0x40+9);write_date(0x3a);delay(5);miao=read_add(1);//开机上电时读取24c02 IIC的数据赋值fen=read_add(2);shi=read_add(3);week=read_add(4);//读取星期几day=read_add(5);//读取多少日month=read_add(6);year=read_add(7);write_sfm(10,miao);//分别送去液晶显示write_sfm(7,fen);write_sfm(4,shi);write_week(week);//开机从24c02读取的星期几数从新写入液晶显示出来write_year_month_day(9,day);write_year_month_day(6,month);write_year_month_day(3,year);//定时器初始化TMOD=0x01; //设置定时器0工作模式1TH0=(65536-45876)/256; //定时器装初值TL0=(65536-45876)%256;EA=1; //开总中断ET0=1; //打定时器0中断TR0=1; //启动定时器0}void keyscan() //按键扫描函数{if(s1==0){delay(5);if(s1==0){s1_num++; //功能键按下次数记录while(!s1); //按键释放确认di();if(s1_num==1) //只按一次按键时TR0=0; //关闭定时器write_com(0x80+0x40+11);write_com(0x0f); //打开光标闪烁}if(s1_num==2) //第二次按下光标闪烁定位到分钟位置{write_com(0x80+0x40+8);}if(s1_num==3) //第三次按下光标闪烁定位到小时位置{write_com(0x80+0x40+5);}/**************************************if(s1_num==4) //第三四次按下退出{s1_num=0;write_com(0x0c); //取消光标闪栎TR0=1; //启动定时器使时钟开始走}***************************************/if(s1_num==4) //光标处星期{write_com(0x80+14);}if(s1_num==5) //光标处日{write_com(0x80+10);}if(s1_num==6) //光标处月{write_com(0x80+7);}if(s1_num==7) //光标处年{write_com(0x80+4);}if(s1_num==8) //当第八次按功能键时退出光标闪烁及开始计时{s1_num=0;write_com(0x0c); //取消光标闪栎TR0=1; //启动定时器使时钟开始走}}if(s1_num!=0){if(s2==0)//增加键确认按下{delay(5);if(s2==0){while(!s2);di();if(s1_num==1){miao++;if(miao==60)miao=0;write_sfm(10,miao);write_com(0x80+0x40+11);write_add(1,miao);}if(s1_num==2){fen++;if(fen==60)fen=0;write_sfm(7,fen);write_com(0x80+0x40+8);write_add(2,fen);}if(s1_num==3){shi++;if(shi==24)shi=0;write_sfm(4,shi);write_com(0x80+0x40+5);write_add(3,shi);}if(s1_num==4)//按四次功能键后光标至星期几处,可调节星期几{week++;if(week==8)week=1;write_week(week);write_com(0x80+14); //写一个字符后光标会移一位,所以要重新定义光标位置write_add(4,week);}if(s1_num==5) //光标至显示日处,可调节多少日{day++;if(day==32)day=1;write_year_month_day(9,day);write_com(0x80+10);write_add(5,day);}if(s1_num==6) //光标至显示月处调节月份{month++;if(month==13)month=1;write_year_month_day(6,month);write_com(0x80+7);write_add(6,month);}if(s1_num==7){year++;if(year==100)year=00;write_year_month_day(3,year);write_com(0x80+4);write_add(7,year);}}}if(s3==0) //确认减小键被按下{delay(5);//按键防抖延时if(s3==0) //确认减小键被按下{while(!s3);di();if(s1_num==1){miao--;if(miao==-1)miao=59;write_sfm(10,miao);write_com(0x80+0x40+11);write_add(1,miao);}if(s1_num==2){fen--;if(fen==-1)fen=59;write_sfm(7,fen);write_com(0x80+0x40+8);write_add(2,fen);}if(s1_num==3){shi--;if(shi==-1)shi=23;write_sfm(4,shi);write_com(0x80+0x40+5);write_add(3,shi);}if(s1_num==4){week--;if(week==0)week=7;write_week(week);write_com(0x80+14); //写一个字符后光标会移一位,所以要重新定义光标位置write_add(4,week);}if(s1_num==5)//光标至显示日处,可调节多少日{day--;if(day==0)day=31;write_year_month_day(9,day);write_com(0x80+10);//光标位置移回在显示多少日的个位write_add(5,day);}if(s1_num==6) //光标至显示月处调节月份{month--;if(month==0)month=12;write_year_month_day(6,month);write_com(0x80+7);write_add(6,month);}if(s1_num==7){year--;if(year==-1)year=99;write_year_month_day(3,year);write_com(0x80+4);write_add(7,year);}}}}}void main(){init();//首先初始化各数据while(1){keyscan(); //按键扫描函数}}void timer0() interrupt 1 //定时器0中断服务程序{TH0=(65536-45876)/256;TL0=(65536-45876)%256;count++; //中断次数累加,计数if(count==20) //50微秒乘以20等于1秒{count=0;miao++;if(miao==60) //秒加到60则进位分钟{miao=0; //同时秒数清0fen++;if(fen==60) //分钟加到60则进位小时{fen=0; //同时分钟清0shi++;if(shi==24) //小时加到24则小时清0{shi=0;}write_sfm(4,shi);//小时若变化则重新写入write_add(3,shi);//写入24c02存储起来,小时数的写入地址为3 }write_sfm(7,fen);//分钟若变化则重新写入write_add(2,fen);}write_sfm(10,miao);//秒若变化则重新写入write_add(1,miao);}}/***********************************24C02.h头文件,将以下源代码需存为与保存的C代码根目录下。

51单片机1602液晶-(教程)

51单片机1602液晶-(教程)
用户自定义字符发生存储器共64字节地址为0x000x3f可存储8个58点阵图形其中地址0x000x07存储字符代码为0x00的字符图形0x080x0f存储字符代码为0x01的字符图形以此类推
51单片机1602液晶接口设计
51单片机的1602液晶
VL- 液晶屏对比度的调节
L命令是对液晶屏显示的设置 H数据是要显示的东西
51单片机的1602液晶
1602液晶的存储器结构
1. DDRAM:
显示数据RAM,用来寄存待显示的字符代码。共80个字 节,其地址和屏幕的对应关系如下图: 要在屏幕上显示字符,只需向相关DDRAM中写入该字符 的ASCII码即可。
1602液晶的存储器结构
2. CGROM:
字符发生存储器,已经存储了160个不同的点阵字符图形, 按ASCII码排列,如下图所示:
51单片机的1602液晶
51单片机的1602液晶

液晶显示
0x38
5
7
51单片机的1602液晶
பைடு நூலகம்
51单片机的1602液晶
51单片机的1602液晶
写命令子函数 命令选择 DB0-DB7 E使能高电平
使能E开
使能E关 写数据子函数 数据选择 DB0-DB7
E使能高电平
使能E开 使能E关
51单片机的1602液晶
字符代码:
0x00~0x0F为用户自定 义的字符图形RAM。
0x20~0x7F为标准的 ASCII码。 0xA0~0xFF为日文字符 和希腊文字符。
1602液晶的存储器结构
3. CGRAM:
用户自定义字符发生存储器,共64字节,地址为 0x00~0x3f,可存储8个5*8点阵图形,其中地址0x00~0x07 存储字符代码为0x00的字符图形,0x08~0x0f存储字符代码 为0x01的字符图形,以此类推。
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档