单片机与LCD液晶显示器应用程序举例
- 格式:doc
- 大小:85.00 KB
- 文档页数:12
单片机lcd液晶屏电子时钟C程序————————————————————————————————作者:————————————————————————————————日期:/********************************************************************* 文件名:液晶1602显示.c* 描述: 该程序实现了对液晶1602的控制。
* 创建人:东流,2009年4月10日* 版本号:2.0***********************************************************************/ #include<reg52.h>#define uchar unsigned char#define uint unsigned intuint count,t;int shi=1,fen=11,miao=22,nian=12,yue=7,ri=1;uchar shijian[16]={"time 00-00-00 t"},shijian1[16]={"date 00-00-00 "};//这三个引脚参考资料sbit E=P2^7; //1602使能引脚sbit RW=P2^6; //1602读写引脚sbit RS=P2^5; //1602数据/命令选择引脚sbit LE = P3^7;sbit key1 = P3^2; //小时修改建sbit key2 = P3^3; //分钟修改键sbit key3 = P3^4; //显示选择键/********************************************************************* 名称: delay()* 功能: 延时,延时时间大概为5US。
* 输入: 无* 输出: 无***********************************************************************/void delay(){uint n=250;while(n--);}/********************************************************************* 名称: bit Busy(void)* 功能: 这个是一个读状态函数,读出函数是否处在忙状态* 输入: 输入的命令值* 输出: 无***********************************************************************/ bit Busy(void){bit busy_flag = 0;RW = 1;E = 1;delay();busy_flag = (bit)(P0 & 0x80);E = 0;return busy_flag;}/********************************************************************* 名称: wcmd(uchar del)* 功能: 1602命令函数* 输入: 输入的命令值* 输出: 无***********************************************************************/ void wcmd(uchar del){while(Busy());RS = 0;RW = 0;E = 0;delay();P0 = del;delay();E = 1;delay();E = 0;}/********************************************************************* 名称: wdata(uchar del)* 功能: 1602写数据函数* 输入: 需要写入1602的数据* 输出: 无***********************************************************************/void wdata(uchar del){while(Busy());RS = 1;RW = 0;E = 0;delay();P0 = del;delay();delay();E = 0;}/********************************************************************* 名称: L1602_init()* 功能: 1602初始化,请参考1602的资料* 输入: 无* 输出: 无***********************************************************************/void L1602_init(void){wcmd(0x38);wcmd(0x0c);wcmd(0x06);wcmd(0x01);}void timeInit(){TMOD = 0X01; //定义定时器1工作方式16位定时c/t选为定时器GATE 选TR1控制TL0 = (65536-10000)%256;TH0 = (65536-10000)/256;TR0=1;EA=1;ET0=1;}void timeint() interrupt 1{TL0 = (65536-10000)%256;TH0 = (65536-10000)/256;count++;}/****************************时间日期设定*************************/void shijianxian(){if(count>=100){miao++;count=0;}if(miao>=60){fen++;miao=0;}if(fen>=60){shi++;fen=0;}if(shi>=24){ri++;shi=0;}if(ri>30){yue++;ri=1;}if(yue>12){nian++;;yue=1;}if(nian==99){nian=0;}if((key1==0)&((t%6)==0)){delay();if((key1==0)&((t%6)==0)){shi++;if(shi>23) shi=0;}delay();}if((key3==0)&((t%6)==0)){delay();if((key3==0)&((t%6)==0)){shi--;if(shi<0) shi=23;}}if((key1==0)&((t%6)==1)){delay();if((key1==0)&((t%6)==1)){fen++;if(fen>59) fen=0;}delay();}if((key3==0)&((t%6)==1)){delay();if((key3==0)&((t%6)==1)){fen--;if(fen<0) fen=59;}delay();}if((key1==0)&((t%6)==2)){delay();if((key1==0)&((t%6)==2)) yue++;delay();}if((key1==0)&((t%6)==3)){delay();if((key1==0)&((t%6)==3)) ri++;delay();}}/**********************************时间显示*******************************/void shijianxian1(){shijian[6]=shi/10+48;shijian[7]=shi%10+48;shijian[9]=fen/10+48;shijian[10]=fen%10+48;shijian[12]=miao/10+48;shijian[13]=miao%10+48;shijian[8]=45;shijian[11]=45;shijian[15]=t+48;}/**********************************日期显示*******************************/void riqi(){shijian1[6]=nian/10+48;shijian1[7]=nian%10+48;shijian1[9]=yue/10+48;shijian1[10]=yue%10+48;shijian1[12]=ri/10+48;shijian1[13]=ri%10+48;shijian1[8]=45;shijian1[11]=45;}/********************************************************************* 名称: Main()* 功能: 主函数* 输入: 无* 输出: 无***********************************************************************/ void Main(){uint i;L1602_init();timeInit();while(1){shijianxian();shijianxian1();if(key2==0){delay();if( (key2==0))t++;if(t>=6) t=0;delay();}riqi();for(i=0;i<16;i++){wcmd(0xc0+i);wdata(shijian[i]);wcmd(0x80+i);wdata(shijian1[i]);}}}。
实验三矩阵键盘检测一、实验目的:掌握键盘的识辨方法及键盘消抖知识。
二、实验要求:依次按动键盘,使LED数码管依次显示0—F。
请自行设计电路、编写程序。
三、实验原理:通过在Keil C51中对单片机AT89C52进行编程,硬件电路中单片机P2口与4×4键盘矩阵连接,P0口与七段数码管连接。
通过keyscan()子程序进行键盘扫描,返回键值并显示在数码管上。
四、实验电路图:五、程序代码:/*16键盘3数码管显示平方,使用P0+锁存器控制3个LED*/#include<reg52.h>#define uchar unsigned char#define uint unsigned intuchar keyscan();uchar num,num1,num2,temp,bai,shi,ge;void display(uchar bai,uchar shi,uchar ge);uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=100;y>0;y--);}void main(){while(1){num2=keyscan();P3=table[num2];}}uchar keyscan()//行扫描方法识别矩阵键盘{P2=0xfe;temp=P2;temp=temp&0xf0;while(temp!=0xf0){delay(5);temp=P2;temp=temp&0xf0;if(temp!=0xf0){temp=P2;switch(temp){case 0xee:num=0;break;case 0xde:num=1;break;case 0xbe:num=2;break;case 0x7e:num=3;break;}}}P2=0xfd;temp=P2;temp=temp&0xf0;while(temp!=0xf0){delay(5);temp=P2;temp=temp&0xf0;if(temp!=0xf0){temp=P2;switch(temp){case 0xed:num=4;break;case 0xdd:num=5;break;case 0xbd:num=6;break;case 0x7d:num=7;break;}}}P2=0xfb;temp=P2;temp=temp&0xf0;while(temp!=0xf0){delay(5);temp=P2;temp=temp&0xf0;if(temp!=0xf0){temp=P2;switch(temp){case 0xeb:num=8;break;case 0xdb:num=9;break;case 0xbb:num=10;break;case 0x7b:num=11;break;}}}P2=0xf7;temp=P2;temp=temp&0xf0;while(temp!=0xf0){delay(5);temp=P2;temp=temp&0xf0;if(temp!=0xf0){temp=P2;switch(temp){case 0xe7:num=12;break;case 0xd7:num=13;break;case 0xb7:num=14;break;case 0x77:num=15;break;}}}return num;}。
液晶显示器一.实验目的:1.了解全点阵图形LCD的结构和原理掌握在MSP430上如何使用外设。
2.了解LCD显示器的工作原理、种类(笔段型、点阵字符型、点阵图形)及主要性能指标。
3.掌握图形点阵LCD的编程使用方法;理解LCD显示模块命令的种类、功能及使用方法。
4.了解LCD字符生成软件的使用方法(见附录)。
二.实验内容:1.在LCD上显示Hello和中文字“南京工业大学”。
2.通过键盘控制Hello或者中文字符在LCD上左右、上下移动。
3.学会使用字符生成软件来实现任意字符代码的生成和显示。
4.其他另外可以实现的目标:使字符在按键没有松动的情况下连续移动;实现字符的循环移动,即当字符串移动到边界时仍可以移动,显示不完的部分从另一边显示出来。
三.实验原理:1.图形点阵式液晶原理液晶是一种具有规则性分子排列的有机化合物,它既不是液体也不是固体,而是介于固态和液态之间的物质。
液晶具有电光效应和偏光特性,这是它能用于显示的主要原因。
常用的液晶显示器可分成3类,分别是扭曲向列型(Twisted Nematic)、超扭曲向列型(Super TN)和彩色薄膜型。
字符点阵式属于扭曲向列型LCD。
典型的字符点阵式液晶显示器是由控制器、驱动器、字符发生器ROM、字符发生器RAM和液晶屏组成,字符由5*7 点阵或5*10点阵组成。
一般结果如图一所示:图一 128x64 点阵图形液晶模块方框示意图此次实验所用的LCD型号是RT12864CT。
12864是一种图形点阵液晶显示器,它主要由行驱动器/列驱动器及128*64全点阵液晶显示器组成。
可完成图形显示,也可以显示8*4个(16*16)汉字。
管脚号管脚名称LEVER 管脚功能描述1 VSS 0 电源地2 VDD +5.0V 电源电压3 V0 - 液晶显示器驱动电压4 D/I(RS) H/L D/I=“H”,表示DB7∽DB0为显示数据D/I=“L”,表示DB7∽DB0为显示指令数据5 R/W H/L R/W=“H”,E=“H”数据被读到DB7∽DB0R/W=“L”,E=“H→L”数据被写到IR或DR6 E H/ R/W=“L”,E信号下降沿锁存DB7∽DB0R/W=“H”,E=“H”DDRAM数据读DB7∽DB07 DB0 H/L 数据线8 DB1 H/L 数据线9 DB2 H/L 数据线10 DB3 H/L 数据线11 DB4 H/L 数据线12 DB5 H/L 数据线13 DB6 H/L 数据线14 DB7 H/L 数据线15 CS1 H/L H:选择芯片(右半屏)信号16 CS2 H/L H:选择芯片(左半屏)信号17 RET H/L 复位信号,低电平复位18 VOUT -10V LCD驱动负电压19 LED+ - LED背光板电源20 LED- - LED背光板电源表1:12864LCD的引脚说明128x64 点阵图形液晶模块的内部结构可分为三个部分:LCD 控制器,LCD 驱动器,LCD 显示装置。
单片机与液晶显示屏的接口设计与形显示应用案例在电子产品中,单片机与液晶显示屏的接口设计至关重要。
本文将介绍单片机与液晶显示屏的接口设计原理,并结合一个实际案例,详细说明其应用过程。
接口设计原理单片机是一种集成了微处理器、存储器和IO接口等功能于一体的芯片。
而液晶显示屏是一种利用电压控制液晶分子排列方向来呈现图像的显示设备。
要使单片机与液晶显示屏正常工作,首先需要设计一个合适的接口。
接口设计的主要原则包括:电平匹配、速度匹配、稳定性和可靠性。
在连接单片机和液晶显示屏时,需要根据它们的电气特性,选择合适的电平转换电路,保证信号传输的稳定性和可靠性。
此外,需要考虑数据传输速度的匹配,确保数据能够及时准确地传输。
形显示应用案例以一个简单的温度计设计为例,介绍单片机与液晶显示屏的接口设计与显示应用过程。
假设我们使用STM32单片机和16x2字符液晶显示屏。
接口设计步骤如下:1. 连接单片机和液晶显示屏。
2. 设计并实现驱动程序,包括初始化液晶显示屏、发送数据等功能。
3. 编写主程序,采集温度传感器数据,并将其显示在液晶显示屏上。
通过以上步骤,我们可以实现一个简单的温度计应用。
当温度传感器检测到环境温度变化时,单片机采集温度数据,并将其实时显示在液晶显示屏上,方便用户观察。
总结单片机与液晶显示屏的接口设计是电子产品中的重要环节,合理的接口设计可以有效提高产品的性能和稳定性。
通过一个温度计设计案例,我们可以更好地理解接口设计的过程和应用。
希望以上内容对您有所帮助。
单片机与LCD显示屏接口技术原理及应用实践概述单片机与LCD显示屏的接口技术是现代电子设备中广泛应用的一项重要技术。
它使得单片机能够与液晶显示屏进行通信,实现信息的输入与输出。
本文将介绍单片机与LCD显示屏接口的原理、常用接口类型以及在实际应用中的应用实践。
一、单片机与LCD显示屏接口原理单片机与LCD显示屏之间通过接口进行数据的传输和控制命令的发送。
接口主要包括数据总线、控制线以及时钟信号。
数据总线用于传输图像数据和字符数据,控制线用于发送控制命令,时钟信号用于同步数据传输。
1.1 数据总线数据总线是单片机与LCD显示屏之间进行数据传输的通道。
位数不同的单片机使用的数据总线宽度也不同,例如8位单片机使用8位数据总线,16位单片机使用16位数据总线。
数据总线的宽度决定了单次传输的数据量,进而影响了图像显示的分辨率和刷新速度。
1.2 控制线控制线用于发送控制命令,例如清屏命令、光标移动命令等。
控制线的数量取决于显示屏的功能需求,常见的控制线包括使能线(EN)、读写线(R/W)、数据/命令选择线(RS)等。
1.3 时钟信号时钟信号用于同步单片机与LCD显示屏之间的数据传输。
单片机通过时钟信号来控制数据的发送和接收时间。
时钟信号的频率决定了数据传输的速度,而数据传输的速度则影响了图像显示的刷新率。
二、常用单片机与LCD显示屏接口类型常见的单片机与LCD显示屏接口类型包括并行接口和串行接口。
2.1 并行接口并行接口是指单片机与LCD显示屏之间通过多根线同时传输数据和控制命令。
并行接口的优点是传输速度快,数据传输稳定可靠,适用于要求高刷新率和高分辨率的应用场景。
然而,并行接口需要占用较多的IO口,使得接口的布线复杂。
2.2 串行接口串行接口是指单片机与LCD显示屏之间通过一根线逐位传输数据和控制命令。
串行接口的优点是占用IO口较少,布线简单,适用于资源有限的应用场景。
然而,串行接口传输速度较慢,对刷新率和分辨率要求较低。
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();}}。
基于MSP430单片机的液晶LCD048应用程序TI公司系列是一种超低功耗的混合信号控制器,其中包括一系列器件,它们针对不用的应用由不同的模块组成。
其中FLASH系列使高效系统变得轻便,FLASH存储器也具有很强的灵便性。
同时为了在低频率的驱动下得到较高的稳定频率,某些MSP430器件上用法了锁频技术FLL或增加型锁频环技术FLL+。
如MSP430F425的时钟模块中用法了FLL+技术,这样可以得到稳定的频率。
液晶驱动MSP430器件上的液晶的控制/驱动将简化液晶显示器的显示。
不同型号的液晶驱动能力不同,我们采纳 MSP430的F42X系列,有128段驱动能力。
液晶的驱动有4种办法:静态,2MUX或1/2占空比,3MUX或1/3占空比, 4MUX或1/4占空比。
对于不同系列、不同型号的液晶驱动原理,控制办法都是一样的,不同点在于驱动液晶段数不一样,或可显示信息的多少不一样。
我们采纳4MUX,这种方式也最容易。
其中需要注重以下两点:(1)液晶的偏压。
因为液晶驱动用法沟通,所以必需按照液晶的工作模MSP430举行偏压设置,详细的操作是:STATIC模式下,R33开路,R03-R23接地,2MUX模式下,分离在R33、R13以及R13、R03之间接上 10K的;3/4MUX模式下,分离在R33、R23之间,R23、R13以及R13、R03之间接上10K的电阻,这样就能保证COM0-COM3 出来供应液晶块的电压符合要求。
(2)频率的设置。
MSP430有三种时钟ACLK(辅助时钟)、MCLK(主时钟)、SMCLK(子时钟),其中液晶的驱动频率FCLK来自ACLK。
在XTIN和XTOUT之间接上振荡频率为32KHz的晶振,Fclk可以按照需要选为1024Hz、512Hz、256Hz、128Hz等。
由FRFQ0和FRFQ1的设置可以满足不同液晶对频率的要求,其中Flcd=2*MUX(rate)*F(framing)。
单片机与液晶显示器的接口及应用引言液晶显示器(LCD)具有工作电压低、微功耗、显示信息量大和接口方便等优点,现在已被广泛应用于计算机和数字式仪表等领域,成为测量结果显示和人机对话的重要工具。
液晶显示器按其功能可分为三类:笔段式液晶显示器、字符点阵式液晶显示器和图形点阵式液晶显示器。
前两种可显示数字、字符和符号等,而图形点阵式液晶显示器还可以显示汉字和任意图形,达到图文并茂的效果,其应用越来越广泛。
本文在介绍以T6963C为控制器的GTG240128液晶显示模块的结构和功能的基础上,讨论了其与AT89C55单片机的硬件接口电路及接口软件编程方法。
GTG240128液晶显示模块1 模块特点GTG240128图形点阵式液晶显示器的点阵的大小为240×128,带背光功能。
内置1片T6963C液晶显示控制器和5片KS0086驱动器。
该液晶显示模块具有如下特点。
● 8位并行总线接口,能直接与80系列的微处理器相连;● 可以显示数字、字母、汉字和图形等;● 具有128种5×8点阵的ASCI字符字模库CGROM;● 具有64kb的显示存储器(可被划分为文本显示区、图形显示区、文本属性区和自定义字符库区),并允许MCU随时访问;● 可用图形方式、文本方式以及图形和文本合成方式显示。
2 模块接口引脚功能GTG240128液晶显示模块与微处理器的接口共有21个引脚,各引脚功能如表1所示。
3 模块指令集简介GTG240128液晶显示模块使用了硬件初始化设置,使得其指令功能集中于显示功能的设置上,从而加强了显示能力。
该模块的指令可带一个或两个参数,也可不带参数。
若指令中含有参数,则参数必须在指令之前输入。
在每次数据或指令的写入操作和数据的读取操作之前都要进行状态字检测,只有在不“忙”的状态下,MCU对模块的操作才有效。
其状态位由低位到高位的含义如表2所示。
---在MCU写指令或一次读/写数据时,S0和S1要同时有效;当MCU使用自动读/写功能时,S2和S3将取代S0和S1作为忙标志位,此时MCU就要判别它是否有效;S6是考察T6963C屏读或屏拷贝指令执行情况的标志位;S5和S7表示模块内部的运行状态,一般不用。
计算机科学与工程系实验报告课程名称:单片机原理与应用实验题目:单片机开控制液晶显示器LCD1602班级:姓名:学号:日期:一、实验目的掌握单片机控制字符型液晶显示器LCD1602的接口设计与软件编程二、实验要求1、用单片机控制字符型液晶显示器LCD1602字符信息“Happy New Year”和“Welcome to Hit”;2、上述信息分别从LCD1602右侧第1行、第2行滚动移入,然后从左侧滚动移出,反复循环显示。
三、实验要求提交的实验报告中应包括:电路原理图、实验设计思路、C51源程序(含注释语句)、运行效果(含运行截图与说明)、实验小结三、硬件电路原理图的设计四、编程思路及C51源程序(1)编程思路:首先 1.LCD初始化2.检查忙标志函数3.写命令函数4.写数据函数5.设置延时函数,然后是主函数调用对LCD初始化函数,插入数据。
(2)C51源程序:#include <reg51.h>#include <intrins.h> //包含_nop_( )空函数指令的头文件#define uchar unsigned char#define uint unsigned int#define out P0sbit RS=P2^0; //位变量sbit RW=P2^1; //位变量sbit E=P2^2; //位变量void lcd_initial(void); //LCD初始化函数void check_busy(void); //检查忙标志函数void write_command(uchar com); //写命令函数void write_data(uchar dat); //写数据函数void delay(uint); //延时函数void main(void) //主函数{uchar tab1[]="Happy New Year";uchar tab2[]="Welcome to HIT";uchar i,j,t;lcd_initial( ); //调用对LCD初始化函数for(t=0;t<29;t++) //实现循环移动{for(i=0;i<14;i++) //循环完成14个字符的字符串{write_command(0x8f+1+i); //指针加1write_data(tab1[i]); //显示对应指针的字符}for(j=0;j<14;j++){write_command(0xcf+1+j);write_data(tab2[j]);}write_command(0x18); //外循环,t循环一次,画面左平移一个字符 delay(200);}}void delay(uint a) //1ms延时子程序{uchar b=250;for(;a>0;a--){while(--b);b=249;while(--b);b=250;}}void check_busy(void) //检查忙标志函数{uchar dt;do{dt=0xff;E=0;RS=0;RW=1;E=1;dt=out;}while(dt&0x80);E=0;}void write_command(uchar com) //写命令函数{check_busy();E=0;RS=0;RW=0;out=com;E=1;_nop_( );E=0;delay(1);}void write_data(uchar dat) //写数据函数{check_busy();E=0;RS=1;RW=0;out=dat;E=1;_nop_();E=0;delay(1);}void LCD_initial(void) //液晶显示器初始化函数{write_command(0x38); //写入命令0x38:16*2显示,5×7点阵字符write_command(0x0C); //写入命令0x0C:开整体显示,光标关,无黑块write_command(0x06); //写入命令0x06:光标右移write_command(0x01); //写入命令0x01:清屏delay(1);}五、仿真运行效果展示六、实验小结通过本次实验,我对LCD1602液晶显示屏有了一个初步的认识,并且在这次实验中,自己对软件的操作更加娴熟,希望自己以后能够把理论知识与实践操作能够紧紧的相结合起来。
LCD与单片机的连接电路图和LCD显示程序LCD与单片机的连接电路图和LCD显示程序/LCD测试程序3.2.5 LCD显示电路液晶显示器简称LCD显示器,它是利用液晶经过处理后能改变光线的传输方向的特性来显示信息的。
要使用点阵型LCD显示器,必须有相应的LCD控制器、驱动器来对LCD显示器进行扫描、驱动,以及一定空间的ROM和RAM来存储写入的命令和显示字符的点阵。
现在往往将LCD控制器、驱动器、RAM、ROM和LCD显示器连接在一起,称为液晶显示模块。
液晶显示模块是一种常见的人机界面,在单片机系统中的应用极其广泛。
液晶显示模块既可以显示字符,又可以显示简单的图形。
本系统采用的是1602的LCD接口。
1602是一种点阵字符型液晶显示模块,可以显示两行共32个字符。
根据LCD型号的不同,所需要的背光电阻大小会不同,可自行调节。
本系统采用的LCD为RT-1602C,其主要引脚的功能如下:RS:数据/命令选择端,高电平时选择数据寄存器,低电平时选择指令寄存器。
RW:读/写选择端,高电平时进行读操作,低电平时进行写操作。
当RS和RW共同为低电平时,可以写入指令或者显示地址;当RS为低电平、RW为高电平时,可以读忙信号;当RS为高电平、RW为低电平时,可以写入数据。
E:使能端,当E端由高电平跳变成低电平时,液晶模块执行命令。
图3-9 LCD显示电路LCD测试程序#include <>/********IO引脚定义*********************************************************** /sbit LCD_RS=P2^7;//定义引脚sbit LCD_RW=P2^6;sbit LCD_E=P2^5;/********宏定义*********************************************************** / #define LCD_Data P0#define Busy 0x80 //用于检测LCD状态字中的Busy标识/********数据定义*********************************************************** **/ unsigned char code uctech[] = {"Happy every day"};unsigned char code net[] = {""};/********函数声明*********************************************************** **/ void WriteDataLCD(unsigned char WDLCD); //写数据void WriteCommandLCD(unsigned char WCLCD,BuysC); //写命令unsigned char ReadDataLCD(void); //读数据unsigned char ReadStatusLCD(void); //读状态void LCDInit(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 Delay5Ms(void); //延时void Delay400Ms(void); //延时/***********主函数开始********************************************************/ void main(void){Delay400Ms(); //启动等待,等LCD讲入工作状态LCDInit(); //初始化Delay5Ms(); //延时片刻(可不要)DisplayListChar(0, 0, uctech);DisplayListChar(1, 5, net);ReadDataLCD(); //测试用句无意义while(1);}/***********写数据********************************************************/ void WriteDataLCD(unsigned char WDLCD){ReadStatusLCD(); //检测忙LCD_Data = WDLCD;LCD_RS = 1;LCD_RW = 0;LCD_E = 0; //若晶振速度太高可以在这后加小的延时LCD_E = 0; //延时LCD_E = 1;}/***********写指令********************************************************/ void WriteCommandLCD(unsigned char WCLCD,BuysC) //BuysC为0时忽略忙检测{if (BuysC) ReadStatusLCD(); //根据需要检测忙LCD_Data = WCLCD;LCD_RS = 0;LCD_RW = 0;LCD_E = 0;LCD_E = 0;LCD_E = 1;}/***********读数据********************************************************/ unsigned char ReadDataLCD(void){LCD_RS = 1;LCD_RW = 1;LCD_E = 0;LCD_E = 0;LCD_E = 1;return(LCD_Data);}/***********读状态*******************************************************/ unsigned char ReadStatusLCD(void){LCD_Data = 0xFF;LCD_RS = 0;LCD_RW = 1;LCD_E = 0;LCD_E = 0;LCD_E = 1;while (LCD_Data & Busy); //检测忙信号return(LCD_Data);}/***********初始化********************************************************/ void LCDInit(void){LCD_Data = 0;WriteCommandLCD(0x38,0); //三次模式设置,不检测忙信号Delay5Ms();WriteCommandLCD(0x38,0);Delay5Ms();WriteCommandLCD(0x38,0);Delay5Ms();WriteCommandLCD(0x38,1); //显示模式设置,开始要求每次检测忙信号WriteCommandLCD(0x08,1); //关闭显示WriteCommandLCD(0x01,1); //显示清屏WriteCommandLCD(0x06,1); //显示光标移动设置WriteCommandLCD(0x0C,1); //显示开及光标设置}/***********按指定位置显示一个字符*******************************************/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; //算出指令码WriteCommandLCD(X, 0); //这里不检测忙信号,发送地址码WriteDataLCD(DData);}/***********按指定位置显示一串字符*****************************************/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坐标应小于0xFDisplayOneChar(X, Y, DData[ListLength]); //显示单个字符ListLength++;X++;}}}/***********短延时********************************************************/ void Delay5Ms(void){unsigned int TempCyc = 5552;while(TempCyc--);}/***********长延时********************************************************/ void Delay400Ms(void){unsigned char TempCycA = 5;unsigned int TempCycB;while(TempCycA--){TempCycB=7269;while(TempCycB--);}LCD与单片机连接的引脚并不是固定的,如有不同只需要在程序里改一下引脚即可。
几个单片机应用实例例一:一个液晶显示的数字式电脑温度计液晶显示器分很多种类,按显示方式可分为段式,行点阵式和全点阵式。
段式与数码管类似,行点阵式一般是英文字符,全点阵式可显示任何信息,如汉字、图形、图表等。
这里我们介绍一种八段式四位LCD显示器,该显示器内置驱动器,串行数据传送,使用非常方便。
原理图如下图:下图是长沙太阳人科技开发有限公司生产的4位带串行接口的液晶显示模块SMS0403 的外部引线简图:有关该模块的具体参数,请查看该公司网站。
此例中使用的温度传感器为美国DALLAS公司生产的单总线式数字温度传感器。
该传感器本站有其详细的资料可供下载。
此例稍加改动,即可做成温控器。
下载驱动该模块的源程序LCD.PLM例2: LED显示电脑电子钟本例介绍一种用LED制作的电脑电子钟(电脑万年历)。
原理图如下图所示:上图中,CPU选用的是AT89C2051,时钟芯片选用的是Dallas公司的DS1302, 温度传感器选用的是Dallas公司的数字温度传感器DS1820,显示驱动芯片选用的是德州仪器公司的TPIC6B595,也可选用与其兼容的芯片NC595或国产的AMT9595。
整个电子钟用两个键来调节时间和日期。
一个是位选键,一个是数字调节键。
按一下位选键,头两位数字开始闪动,进入设定调节状态,此时按数字调节键,当前闪动位的数字就可改变。
全部参数调节完后,五秒钟内没有任何键按下,则数字停止闪动,退出设定调节状态。
源程序清单如下(无温度显示程序):start:do;$include(reg51.dcl)declare (sclk,io,rst) bit at (0b3h) register; /* p33,p34,p35 */ declare (command,data,n,temp1,num) byte;declare a(9) byte;declare ab(6) byte;declare aco(11) byte constant (0fdh,60h,0dah,0f2h,66h,0b6h,0beh,0e0h,0feh,0f6h,00h);declare week(11) byte constant (0edh,028h,0dch,7ch,39h,75h,0f5h,2ch,0fdh,7dh,00h);declare da literally 'p15',clk literally 'p16',ale literally 'p17', mk literally 'p11',sk literally 'p12';clear:procedure;sclk=0;io=0;rst=0;end clear;send1302:procedure(comm);declare (i,comm) byte;do i=0 to 7;comm=scr(comm,1);io=cy;call time(1);sclk=0;call time(1);sclk=1;end;end send1302;wbyt1:procedure(com,dat);/*字节写过程*/ declare (com,dat) byte;call clear;rst=1;call send1302(com);call send1302(dat);call clear;end wbyt1;wbyt8:procedure;/*时钟多字节突发模式写过程*/ declare j byte;call clear;a(7)=A(6);a(6)=a(0);rst=1;call send1302(command);do j=1 to 8;call send1302(a(j));end;call clear;end wbyt8;RBYT1:PROCEDURE;DECLARE I BYTE;CALL CLEAR;RST=1;call send1302(0c1h);IO=1;DO I=0 TO 7;SCLK=1;SCLK=0;CY=IO;N=SCR(N,1);END;A(8)=N;CALL CLEAR;END RBYT1;send595:procedure;declare k byte;do k=0 to 7;data=scr(data,1);da=cy;clk=1;clk=0;end;end send595;send595_1:procedure;declare k byte;do k=0 to 7;data=scr(data,1);da1=cy;clk1=1;clk1=0;end;end send595_1;rb1:procedure(abc,j);DECLARE (I,j,abc) BYTE;CALL CLEAR;RST=1;call send1302(abc);IO=1;DO I=0 TO 7;SCLK=1;SCLK=0;CY=IO;N=SCR(N,1);END;ab(j)=N;ab(j)=dec(ab(j));CALL CLEAR;end rb1;rbyt6:procedure;call rb1(0f1h,0);call rb1(0f3h,1);call rb1(0f5h,2);call rb1(0f7h,3);call rb1(0f9h,4);call rb1(0fbh,5);call rb1(0fdh,6);end rbyt6;wbyt6:procedure;call wbyt1(8eh,0); /* write enable */ call wbyt1(0f0h,ab(0));call wbyt1(0f2h,ab(1));call wbyt1(0f4h,ab(2));call wbyt1(0f6h,ab(3));call wbyt1(0f8h,ab(4));call wbyt1(0fah,ab(5));call wbyt1(0fch,ab(6));call wbyt1(8eh,80h); /* write disable */end wbyt6;rbyt8:procedure;/*时钟多字节突发模式读过程*/ declare (i,j) byte;call clear;rst=1;call send1302(command);io=1;do j=1 to 8;do i=0 to 7;sclk=1;call time(1);sclk=0;cy=io;n=scr(n,1);end;a(j)=n;end;call clear;a(0)=a(6);a(6)=A(7);a(0)=a(0) and 0fh;if a(0)>6 then a(0)=0;CALL RBYT1;if (a(1)=0 and a(2)=0 and a(3)=0) thendo;do num=0 to 35;call time(250);end;temp1=1;end;if temp1=1 thendo;temp1=0;ab(4)=ab(4)+1;if ab(4)>99h thendo;ab(4)=0;ab(5)=ab(5)+1;if ab(5)>99h then ab(5)=0;end;call wbyt6;end;end rbyt8;display:procedure; /*jieya,yima,fasong*/ declare (i,n,m) byte;n=a(0) and 0fh; /* send week */data=week(n);call send595;n=a(4); /* send date */n=n and 0fh;data=aco(n);call send595;n=a(4);n=shr(n,4);data=aco(n);call send595;do i=1 to 3; /* send second,minute,hour */ n=a(i);n=n and 0fh;data=aco(n);call send595;n=a(i);n=shr(n,4);data=aco(n);call send595;end;do i=5 to 6; /* send month,year */n=a(i);n=n and 0fh;data=aco(n);call send595;n=a(i);n=shr(n,4);data=aco(n);call send595;end;n=a(8); /* send 19 or 20 */n=n and 0fh;data=aco(n);call send595;n=a(8);n=shr(n,4);data=aco(n);call send595;do m=0 to 5;n=ab(m);n=n and 0fh;data=aco(n);call send595_1;n=ab(m);n=shr(n,4);data=aco(n);call send595_1;end;ale=0;ale=1;end display;beginset:procedure;a(0)=06h;a(1)=58h;a(2)=59h;a(3)=23h;a(4)=30h;a(5)=06h;a(6)=97h;a(7)=00;a(8)=19h; /* set date/time (1997,7,1,8:00:00,week 3) */ call wbyt1(8eh,0); /* write enable*/call wbyt1(80h,00h);/* start colock */call wbyt1(0beh,0abh);/*两个二极管与8K电阻串联充电*/ command=0beh; /* write colock/date */call wbyt8;call wbyt1(0c0h,a(8));call wbyt1(8eh,80h); /* set write protect bit */end beginset;key:procedure;declare (i,time1,k1,tem) byte;call time(100);k1=7;time1=30;if mk=0 thendo;do while time1>0;week: if k1=0 thendo;do i=0 to 5;/* call hz(a(0)); */end;do i=0 to 3;/* call hz0; */end;end;tem=a(k1);if k1=7 then tem=a(8);a(k1)=0aah;if k1=7 then a(8)=0aah;call display;call time(254);call time (254);a(k1)=tem;if k1=7 then a(8)=tem;call display;call time(254);call time(254);call time(254);time1=time1-1;if mk=0 thendo;call time(100); /*MOD KEY PROCESS*/TIME1=30;IF MK=0 THENDO;k1=k1-1;DO WHILE K1=0FFH;K1=7;END;END;end;IF SK=0 THENDO;CALL TIME(100); /*SET KEY PROCESS*/ TIME1=30;IF SK=0 THENDO;tem=tem+1;tem=dec(tem);DO CASE K1;DO WHILE tem=7;/*week*/tem=0;END;DO WHILE tem=60H;/*scond*/tem=0;END;DO WHILE tem=60H;/*minute*/tem=0;END;DO WHILE tem=24H;/*hour*/tem=0;END;DO WHILE tem=32H;/*date*/tem=1;END;DO WHILE tem=13H;/*month*/tem=1;END;DO while tem=100h; /* YEAR */tem=00;END;DO WHILE TEM>=21H;tem=19H;END;END;A(K1)=tem;if k1=7 then a(8)=tem;END;END;END;END;end key;main$program:mk=1;sk=1;temp1=0;num=0;p32=1;if sk=0 then call beginset;clk=0;da=0;ale=1;loop:do while mk=1 ;if a(0)>6 then a(0)=0;command=0bfh;call rbyt8;call display;do while mk=0;call key;call wbyt1(8eh,0);command=0beh;call wbyt8;call wbyt1(0C0H,A(8));call wbyt1(8eh,80h);end;end;goto loop;end start;例3:一个6位LED、4个按键的显示板按键和显示是单片机系统的基本输入输出部件,下面介绍一个由74LS164驱动的6位数码管和4个按键组成的通用仪表面板。