LCD与单片机的连接电路图和LCD显示程序
lcd 单片机驱动电路
lcd 单片机驱动电路
LCD单片机驱动电路是指用于驱动液晶显示屏(LCD)的电路。
LCD是一种常用的显示设备,广泛应用于数码产品、电子设备等领域。
LCD的驱动电路主要由以下几部分组成:
1. 控制器:控制器是核心部件,负责接收来自单片机的信号,并控制液晶显示屏的显示内容。
2. 驱动器:驱动器负责将控制器发送的信号转化为液晶显示屏可以理解的电信号,以实现显示功能。
3. 电源管理:电源管理模块负责为液晶显示屏提供所需的电源,包括正负电源以及背光灯等。
4. 通信接口:通信接口用于将单片机与LCD驱动电路连接起来,实现数据传输和控制信号的交互。
5. 储存器:在一些应用中,LCD驱动电路可能需要储存一些显示数据或者程序代码,以实现更复杂的显示效果。
总的来说,LCD单片机驱动电路是一个复杂的系统,根据不同的应用需求,其具体的设计和实现方式会有所差异。
一般来说,需要根据液晶显示屏的规格和单片机的输出能力,选用合适的控制器和驱动器,并合理设计电源管理和通信接口,以实现稳定、可靠的液晶显示功能。
单片机与lcd模块之间的四种基本操作
单片机与lcd模块之间的四种基本操作
单片机与LCD模块之间的四种基本操作包括:初始化LCD模块、发送指令、发送数据和清屏操作。
1. 初始化LCD模块:在与LCD模块通信之前,需要对LCD 模块进行初始化。
初始化步骤包括设置LCD工作模式、功能设置、显示设置等。
具体的初始化流程可以根据LCD模块的型号和使用手册来进行配置。
2. 发送指令:在与LCD模块通信时,需要向其发送指令来进行不同的操作。
指令可以用来设置光标位置、清除LCD屏幕内容、设置显示模式等。
发送指令的方法是设置相应的控制脚或寄存器来表示指定的指令。
3. 发送数据:除了发送指令,还可以向LCD模块发送数据来进行显示。
发送数据的方法是设置相应的数据线或寄存器来传输需要显示的数据。
将要显示的字符、数字、图像等数据按照指定格式发送给LCD模块,即可在屏幕上显示出来。
4. 清屏操作:清屏操作是将整个LCD屏幕的内容清除,一般是通过发送特定的指令或数据来实现。
清屏操作可以用于在刷新屏幕内容或切换显示模式时清除屏幕上的之前内容,然后再显示新的内容。
以上四种基本操作是与LCD模块进行交互的常见操作,通过对这些操作的组合和应用,可以实现复杂的LCD显示功能。
不同的LCD模块可能有不同的通信协议和指令集,具体的操
作方法和指令要根据LCD模块的型号和规格来进行配置和实现。
基于STM32单片机FSMC接口驱动LCD的配置与分析
基于STM32单片机FSMC接口驱动LCD的配置与分析概述:STM32单片机是一款高性能、低功耗的32位ARM Cortex-M系列微控制器。
它具有丰富的外设接口,其中包括FSMC(Flexible Static Memory Controller)接口,用于连接外部存储器,例如LCD显示器。
本文将详细介绍如何配置和驱动LCD显示器,以及分析FSMC接口的工作原理。
一、LCD驱动接口配置1. 在STM32的标准外设库中,FSMC的配置函数位于STM32F10x_stdperiph_driver库的stm32f10x_fsmc.c和stm32f10x_fsmc.h文件中。
通过这些函数,可以配置FSMC接口的参数,以使它能够连接和驱动LCD。
2.首先,需要配置FSMC的时钟预分频值。
根据LCD的要求以及系统时钟频率,选择适当的预分频值。
这可以通过设置FSMC_BCRx寄存器中的MBKEN和PS字段来实现。
3.然后,需要配置FSMC的存储芯片选择使能信号(CSEN)和片选信号(ALE)。
这可以通过设置FSMC_BCRx寄存器中的CSEN和ALEN字段来实现。
4.接下来,需要配置FSMC的读写延迟、数据宽度、存储器类型等参数。
这可以通过设置FSMC_BTRx和FSMC_BWTRx寄存器来实现。
5.最后,需要配置FSMC的地址线、数据线和控制线的映射关系。
这可以通过设置FSMC_BCRx寄存器中的MWID、MTYP、MUXEN、MWID和NWID 字段来实现。
二、FSMC接口工作原理1.FSMC接口是一种高速并行接口,它通过多路复用来连接不同的外部存储器。
它具有独立的读/写数据线和地址线,以及控制线,用于选择读/写操作和片选信号。
2. FSMC接口支持不同类型的存储器,例如SRAM、NOR Flash、NAND Flash和LCD。
每种存储器都有不同的时序和接口要求。
3.FSMC接口的时序参数主要包括时钟预分频值、读/写延迟、数据宽度和地址线宽度等。
LCD原理及显示程序
在日常生活中,我们对液晶显示器并不陌生。
液晶显示模块已作为很多电子产品的通过器件,如在计算器、万用表、电子表及很多家用电子产品中都可以看到,显示的主要是数字、专用符号和图形。
在单片机的人机交流界面中,一般的输出方式有以下几种:发光管、LED 数码管、液晶显示器。
发光管和LED数码管比较常用,软硬件都比较简单,在前面章节已经介绍过,在此不作介绍,本章重点介绍字符型液晶显示器的应用。
在单片机系统中应用晶液显示器作为输出器件有以下几个优点:显示质量高由于液晶显示器每一个点在收到信号后就一直保持那种色彩和亮度,恒定发光,而不像阴极射线管显示器(CRT)那样需要不断刷新新亮点。
因此,液晶显示器画质高且不会闪烁。
数字式接口液晶显示器都是数字式的,和单片机系统的接口更加简单可靠,操作更加方便。
体积小、重量轻液晶显示器通过显示屏上的电极控制液晶分子状态来达到显示的目的,在重量上比相同显示面积的传统显示器要轻得多。
功耗低相对而言,液晶显示器的功耗主要消耗在其内部的电极和驱动IC上,因而耗电量比其它显示器要少得多。
10.8.1 液晶显示简介①液晶显示原理液晶显示的原理是利用液晶的物理特性,通过电压对其显示区域进行控制,有电就有显示,这样即可以显示出图形。
液晶显示器具有厚度薄、适用于大规模集成电路直接驱动、易于实现全彩色显示的特点,目前已经被广泛应用在便携式电脑、数字摄像机、PDA移动通信工具等众多领域。
②液晶显示器的分类液晶显示的分类方法有很多种,通常可按其显示方式分为段式、字符式、点阵式等。
除了黑白显示外,液晶显示器还有多灰度有彩色显示等。
如果根据驱动方式来分,可以分为静态驱动(Static)、单纯矩阵驱动(Simple Matrix)和主动矩阵驱动(Active Matrix)三种。
③液晶显示器各种图形的显示原理:线段的显示点阵图形式液晶由M×N个显示单元组成,假设LCD显示屏有64行,每行有128列,每8列对应1字节的8位,即每行由16字节,共16×8=128个点组成,屏上64×16个显示单元与显示RAM区1024字节相对应,每一字节的内容和显示屏上相应位置的亮暗对应。
LCD12864原理与应用(源程序+原理图+proteus仿真)
LCD12864原理与应用1、LCD12864简介:LCD12864分为两种,带字库的和不带字库的,不带字库的液晶显示汉字的时候可以选择自己喜欢的字体。
而带字库的液晶,只能显示GB2312字体,当然也可以显示其他的字体,不过是用图片的形式显示。
下面介绍不带字库的LCD12864,以Proteus中的AMPIRE128×64为例,如下图所示,它的液晶驱动器为KS0108。
引脚功能:引脚符号状态引脚名称功能CS1,CS2输入芯片片选端,都是低电平有效CS1=0开左屏幕,CS1=1关左屏幕CS2=0开右屏幕,CS2=1关右屏幕RS输入数据/命令选择信号RS=1为数据操作,RS=0为写指令或读状态RW输入读写选择信号R/W=1为读选通,R/W=0为写选通E输入读写使能信号在E下降沿,数据被锁存(写)入液晶,在E高电平期间,数据被读出DB0—DB7三态数据总线数据或指令的传送通道RST 输入复位信号,低电平时复位复位时,关闭液晶显示,使显示起始行为0,可以跟单片机的复位引脚RST相连,也可以直接接VCC,使之不起作用V0液晶显示器驱动电压-Vout-10V LCD驱动负电压与带字库的液晶不同,此块液晶含有两个液晶驱动器,每块驱动器都控制64*64个点,分为左右两个屏幕显示,总共为128*64个点(即有128×64个点)。
这就是为什么AMPIRE128*64有CS1和CS2两个片选端的原因。
此液晶有8页,一页有8行点阵点,左右各64列,共128列。
如下图所示:2、LCD12864中的几条重要指令(一)行(line)设置命令:由此可见显示的起始行地址为0XC0,共64行,有规律地改变起始行号,可以实现滚屏效果。
(二)页(page)设置指令:起始页地址为0XB8,因为液晶有64行点,分为8页,每页就有8行点。
(三)列(column)地址设置指令每块驱动器的列地址都是从0X40到0X7F,共64列,所以此液晶共有128列点。
LCD屏显示电路硬件原理图
1.4相应的波形图是COM0COM1SEGnSEGn+11/2占空比,1/2偏压比驱动波形COM0COM1SEGnSEGn+11/2占空比,1/3偏压比驱动波形COM0SEGnSEGn+1静态驱动波形 COM0COM1COM2SEGnSEGn+1SEGn+21/3占空比,1/3偏压比驱动波形COM0COM1COM2COM3SEGnSEGn+1SEGn+2SEGn+31/4占空比,1/3偏压比驱动波形2.3该类电路的应用场合说明此类电路多用于LCD显示较复杂,显示要求较高,由于LCD驱动集成在芯片内,整个芯片的功耗可以做得很低,适合用于电池供电的产品。
3.4相应的波形图数据传输时序图LCD驱动 同2.2波形3.5该类电路的应用场合说明此类电路多用于单片机I/O口少,LCD显示复杂的情况。
3.6注意事项由于加有抗干扰电容,WR、DATA在时序上需要考虑电容充放电的影响。
4、点阵LCD驱动单色点阵型LCD用作图形或图形和文本混合显示的情况下,小面积LCD常采用单片集成控制驱动器件,其显存中的每一位与LCD显示点一一对应,显示数据量大,与控制单片机主要采用并行或串行的数据接口方式。
由于点阵LCD类型较多,此处只说明注意事项,其余的多与供应商联系。
点阵LCD驱动IC与单片机在使用串行通讯接口时,驱动方式和波形与HT1621相似,需要注意防干扰等。
4.1注意事项显示控制线和数据线尽量短,否则会造成数据传输不可靠,显示不稳定。
在省电模式下LCD显示总是关闭的。
由于数据量大,刷新速度相对较慢。
二、总结LCD显示提供了一种可视的人机操作界面,低功耗是其最大的优点,寿命在5万至10万小时,故在家电控制器中广泛应用,显示驱动方式灵活多样,配上不同的背光源既增加了LCD显示对比度,也使得显示效果更加多样化。
近来又有应用于便携式产品上的“反射式彩色LCD”,加入彩色滤光片使之彩色化,更丰富了LCD的显示方式,在实际选用时,可以根据不同的需求选用不同的显示效果和驱动方案。
12864液晶屏与单片机连接图
12864液晶屏与单片机连接图Protel 制图Protues原理图程序部分:#include<reg51.h>#define uchar unsigned char#define uint unsigned int//sbit databus=P1;#define databus P1//sbit Reset = P3^0; //复位sbit rs = P3^7; //指令数据选择sbit e = P3^5; //指令数据控制sbit cs1 = P3^3; //左屏幕选择,低电平有效sbit cs2 = P3^4; //右屏幕选择sbit wr = P3^6; //读写控制//sbit busy = P1^7; //忙标志void SendCommand(uchar command); //写指令void WriteData(uchar dat);//写数据void LcdDelay(uint time); //延时void SetOnOff(uchar onoff);//开关显示void ClearScreen(uchar screen); //清屏void SetLine(uchar line); //置页地址void SetColum(uchar colum);//置列地址void SetStartLine(uchar startline);//置显示起始行void SelectScreen(uchar screen);//选择屏幕void Show1616(uchar lin,uchar colum,uchar *address);//显示一个汉字void InitLcd(); //初始化void ResetLcd(); //复位void Show_english(uchar lin,uchar colum,uchar *address);const uchar code hzk[] = {/*-- 文字: I --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00,0x00, 0x20,0x20,0x3F,0x20,0x20,0x00,0x00,/*-- 文字: --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0 x00,0x00,0x00,0x00,0x00,0x00,0x00,/*-- 文字: c --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0 x0E,0x11,0x20,0x20,0x20,0x11,0x00,/*-- 文字: a --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0 x19,0x24,0x22,0x22,0x22,0x3F,0x20,/*-- 文字: n --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0 x3F,0x21,0x00,0x00,0x20,0x3F,0x20,/*-- 文字: --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0 x00,0x00,0x00,0x00,0x00,0x00,0x00,/*-- 文字: m --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x20,0 x3F,0x20,0x00,0x3F,0x20,0x00,0x3F,/*-- 文字: a --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0 x19,0x24,0x22,0x22,0x22,0x3F,0x20,/*-- 文字: k --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x08,0xF8,0x00,0x00,0x80,0x80,0x80,0x00,0x20, 0x3F,0x24,0x02,0x2D,0x30,0x20,0x00,/*-- 文字: e --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0 x1F,0x22,0x22,0x22,0x22,0x13,0x00,/*-- 文字: --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0 x00,0x00,0x00,0x00,0x00,0x00,0x00,/*-- 文字: i --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x00,0x80,0x98,0x98,0x00,0x00,0x00,0x00,0x00,0 x20,0x20,0x3F,0x20,0x20,0x00,0x00,/*-- 文字: t --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x00,0x80,0x80,0xE0,0x80,0x80,0x00,0x00,0x00, 0x00,0x00,0x1F,0x20,0x20,0x00,0x00,/*-- 文字: !--*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*-- 文字: 我--*//*-- 楷体_GB231212; 此字体下对应的点阵为:宽x高=16x16 --*/0x00,0x00,0x80,0x90,0xF0,0x48,0x40,0x7F,0xC0, 0x20,0x24,0xA8,0x00,0x00,0x00,0x00,0x08,0x08,0x04,0x14,0x3F,0x02,0x09,0x08,0x05, 0x06,0x09,0x10,0x20,0x78,0x00,0x00,/*-- 文字: 的--*//*-- 楷体_GB231212; 此字体下对应的点阵为:宽x高=16x16 --*/0x00,0xC0,0x60,0x50,0x2C,0xE0,0x80,0x40,0xA 0,0x38,0x26,0x10,0xF0,0x00,0x00,0x00,0x00,0x07,0x19,0x09,0x08,0x1F,0x00,0x00,0x00, 0x03,0x10,0x20,0x1F,0x00,0x00,0x00,/*-- 文字: 未--*//*-- 楷体_GB231212; 此字体下对应的点阵为:宽x高=16x16 --*/0x00,0x00,0x80,0x80,0x90,0x90,0xFF,0xC8,0x48, 0x48,0x40,0x40,0x00,0x00,0x00,0x00,0x10,0x10,0x08,0x04,0x02,0x01,0x7F,0x00,0x01, 0x02,0x04,0x08,0x18,0x10,0x10,0x00,/*-- 文字: 来--*//*-- 楷体_GB231212; 此字体下对应的点阵为:宽x高=16x16 --*/0x00,0x80,0x80,0xA8,0xC8,0x88,0xFF,0x84,0x64 ,0x54,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x08,0x04,0x02,0x7F,0x01,0x02, 0x04,0x0C,0x08,0x08,0x08,0x08,0x00,/*-- 文字: 不--*//*-- 楷体_GB231212; 此字体下对应的点阵为:宽x高=16x16 --*/0x00,0x00,0x08,0x08,0x08,0x88,0x48,0xE4,0x14, 0x8C,0x84,0x04,0x04,0x04,0x00,0x00,0x00,0x04,0x04,0x02,0x01,0x00,0x00,0x3F,0x00, 0x00,0x00,0x01,0x03,0x06,0x00,0x00,/*-- 文字: 是--*//*-- 楷体_GB231212; 此字体下对应的点阵为:宽x高=16x16 --*/0x00,0x00,0x80,0x80,0x82,0x9E,0xAA,0xAA,0x A1,0x5D,0x43,0x40,0x00,0x00,0x00,0x00,0x20,0x20,0x10,0x08,0x06,0x04,0x08,0x1F,0x12, 0x22,0x22,0x20,0x20,0x20,0x20,0x00,/*-- 文字: 梦--*//*-- 楷体_GB231212; 此字体下对应的点阵为:宽x高=16x16 --*/0x00,0x90,0x50,0x30,0xFE,0x28,0x48,0x28,0x18, 0xFF,0x14,0x24,0x24,0x40,0x40,0x00,0x00,0x00,0x40,0x48,0x44,0x26,0x2B,0x12,0x0A, 0x06,0x00,0x00,0x00,0x00,0x00,0x00,/*-- 文字: !--*//*-- 楷体_GB231212; 此字体下对应的点阵为:宽x高=16x16 --*/0x00,0x00,0x00,0xFC,0xFC,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x19,0x19,0x00,0x00,0x00,0x00,0 x00,0x00,0x00,0x00,0x00,0x00,0x00,};void main(){uchar i,line,colum/*,j */;uchar *address ;InitLcd();while(1){/*显示第一行*//********************************** 下面这段程序用来卷页**********************************/ /* line=0;for(j=0;j<4;j++){ClearScreen(2);//清屏line=line+1;colum=0;address=hzk;SetOnOff(1);for(i=0;i<14;i++){if(i<8){SelectScreen(0);Show_english(line,colum,address); address+=16;colum+=8;}else if(i>=8){if(i<13){SelectScreen(1);Show_english(line,colum,address); address+=16;colum+=8;}else{Show1616(line,colum,address); address+=32;colum+=16;}}}for(i = 0;i < 50;i ++) //延时LcdDelay(3000);} */line=1; //开始从第2页(第9行)开始显示,colum=0; //开始从第一列开始显示address=hzk;//给地址指针赋初值SetOnOff(1);//显示开,注意:如果这里设置显示关,显示会出现错误for(i=0;i<14;i++)//设置要显示的字符个数{if(i<8) //i<8时,在左半屏显示(因为每半屏最多只能显示8个英文字符即4个汉字){SelectScreen(0); //选择左屏Show_english(line,colum,address);//显示一个英文字符address+=16; //每个英文字符需要16个十六进制数表示colum+=8; //每个英文字符占8列}else if(i>=8) //当i>8时(当然最多只能是16)在右屏显示{if(i<13) //本程序第一行前13个字符为英文字符,最后一个字符为中文字符,英文字符和中文字符必须分开显示{SelectScreen(1);Show_english(line,colum,address);address+=16;colum+=8;}else //显示中文字符“!”{Show1616(line,colum,address);//显示一个汉字address+=32; //每个汉字要用32个16进制表示colum+=16; //每个汉字占16列}}}/*显示第二行*//****显示原理与第一行完全相同,这里不再赘述了****/line=4;colum=1;SetOnOff(1);for(i=0;i<8;i++){if(i<4){SelectScreen(0);Show1616(line,colum,address);address+=32;colum+=16;}else{SelectScreen(1);Show1616(line,colum,address);address+=32;colum+=16;}}SetOnOff(1);for(i = 0;i < 50;i ++) //延时LcdDelay(30000);if(colum>63)colum=0;}}/********************************** 延时函数**********************************/ void LcdDelay(uint time){while(time--);}/********************************** 写指令**********************************/ void SendCommand(uchar command) {e=1;wr=0;rs=0;databus=command;e=0;}/********************************** 写数据**********************************/ void WriteData(uchar dat){e=1;wr=0;rs=1;databus=dat;e=0;}/********************************** 显示开/关**********************************/ void SetOnOff(uchar onoff){if(onoff==1){SendCommand(0x3f);}else{SendCommand(0x3e);}}/**********************************选择页**********************************/void SetLine(uchar line) //12864总共有8页(0~7),每页有8行{line=line&0x07; //只取后三位xxxx x111 ,这3个是要改变位置的数据line=line|0xb8; //页设置的固定格式SendCommand(line);}/**********************************选择列**********************************/void SetColum(uchar colum) //12864每半屏有64列(0~63),分为左右2屏{colum=colum&0x3f; //xx11 1111,这个是要改变Y位置的数据colum=colum|0x40; //固定格式SendCommand(colum);}/**********************************选择起始行**********************************/void SetStartLine(uchar startline){startline=startline&0x3f;//xx11 1111,这个是要改变x位置的数据startline=startline|0xc0;//11xxxxxx,是起始行设置的固定指令SendCommand(startline);}/**********************************选择左右屏0:左屏,1:右屏,2:全屏**********************************/void SelectScreen(uchar screen){switch(screen){case 0:cs1=0;LcdDelay(2);cs2=1;LcdDelay(2);break;case 1:cs1=1;LcdDelay(2);cs2=0;LcdDelay(2);break;case 2:cs1=0;LcdDelay(2);cs2=0;LcdDelay(2);break;}}显示一个汉字**********************************/void Show1616(uchar lin,uchar colum,uchar *address){uchar i;SetLine(lin);SetColum(colum);for(i=0;i<16;i++){WriteData(*address);address++;}SetLine(lin+1);SetColum(colum);for(i=0;i<16;i++){WriteData(*address);address++;}}显示一个英文字符**********************************/void Show_english(uchar lin,uchar colum,uchar *address){uchar i;SetLine(lin);SetColum(colum);for(i=0;i<8;i++){WriteData(*address);address++;}SetLine(lin+1);SetColum(colum);for(i=0;i<8;i++){WriteData(*address);address++;}}清屏**********************************/ void ClearScreen(uchar screen){uchar i,j;SelectScreen(screen);for(i=0;i<8;i++){SetLine(i);SetColum(0);for(j=0;j<64;j++){WriteData(0);}}}/********************************** 12864初始化**********************************/ void InitLcd(){// ResetLcd();SetOnOff(0);//显示关ClearScreen(2);//清屏SetLine(0);//页设置SetColum(0);//列设置SetStartLine(0);//设置起始页SetOnOff(1);//显示开}仿真实图:。
单片机与LCD显示屏的驱动原理及接口设计
单片机与LCD显示屏的驱动原理及接口设计LCD(Liquid Crystal Display)液晶显示屏是一种常见的显示设备,它通过液晶分子的电场控制实现图像的显示。
单片机作为一种微型计算机,具有运算能力和输入输出接口,能够控制和驱动各种外部设备,包括LCD显示屏。
本文将介绍单片机与LCD显示屏的驱动原理以及接口设计。
一、驱动原理1.1 LCD液晶显示原理LCD液晶显示原理是基于液晶分子光学特性的一个原理。
液晶分子在无电场作用下,分子排列有序,光线经过液晶分子会受到旋转和调整,从而产生不同的偏振方向和相移,导致光线透射情况的变化。
当有电场作用于液晶分子时,分子排列发生改变,从而改变了光线的透射情况,进而实现图像的显示。
1.2 驱动方式常见的LCD驱动方式有并行驱动和串行驱动两种。
并行驱动方式是将LCD驱动器的数据线与单片机相连接,通过同时发送多位数据来驱动LCD显示。
具体的驱动方式有8080并行接口、6800并行接口等。
串行驱动方式是将LCD驱动器的数据线与单片机的串行通信链路相连,通过逐位或逐字节串行传输数据来驱动LCD显示。
常用的串行驱动方式有I2C接口和SPI接口等。
1.3 LCD控制器为了简化单片机与LCD显示屏的连接和驱动,常使用LCD控制器。
LCD控制器是一种特殊的芯片,能够直接与单片机通信,并通过内部逻辑电路将数据转换为LCD所需的信号。
常见的LCD控制器有HD44780、SSD1306等。
二、接口设计2.1 并行接口设计并行接口是将LCD的数据线与单片机的数据线相连接,通过同时发送多位数据来驱动LCD显示。
一般包括数据线、读使能信号(RD)、写使能信号(WR)、使能信号(EN)和控制线(RS、R/W)等。
其中,数据线用于传输图像数据和命令数据,一般为8位数据线。
RD信号用于将LCD指令端或数据端的数据读出;WR信号用于将单片机所发出的数据写入到LCD模块中;EN信号用于控制LCD模块的操作;RS线用于指示数据传输的类型,一般为低电平表示指令,高电平表示数据;R/W线用于指示单片机与LCD模块之间的读写操作。
PIC18单片机LCD液晶显示器驱动程序
//***********************************************//* Main.C *//***********************************************//* W-AP002 MPLAB C18 Advance Workshop *//* Written by: Richard Yang *//* Sr. Corporate Applications Engr.*//* Microchip Technology Inc. *//* Date: 16 January 2003 *//* Revision: 1 *//***********************************************//*********************************************************** #include <p18f452.h>#include <delays.h>#include "P18F_LCD.h"void InitializePORT(void);#pragma idata access My_RAM_1near char LCD_RAM_MSG[ ]="Richard Yang";near unsigned char LCD_Char='0';#pragma romdata RomDataconst rom char LCD_ROM_MSG[ ] ="WAP-002 Workshop";#pragma code//*********************************************************** /* */ /* Main Program */ /* */ //*********************************************************** void main(void){InitializePORT( );OpenLCD( );putcLCD('!');while(1);}//************************************************//* Function: Initialize PORT *//************************************************void InitializePORT(void){PORTA=0x00;TRISA=0b11011011; // RA2 as LCD-E control, RA5 as CS Control for SPIPORTD=0x00;TRISD=0x00; // Set PORTD as Output port}#pragma code#pragma romdata CONFIGconst rom unsigned char CONFIG1L=0xff ; // Don't care byteconst rom unsigned char CONFIG1H=0b00100010 ; // Disable OSC switch , XXXXX010 = HS Oscconst rom unsigned char CONFIG2L=0b00000001 ; // Disable PWRT , Disable BORconst rom unsigned char CONFIG2H=0b00000000 ; // Disable WDT timerconst rom unsigned char CONFIG3L=0xff ; // Don't care byteconst rom unsigned char CONFIG3H=0b00000000 ; // XXXXXXX0 = CCP2 --> RB3const rom unsigned char CONFIG4L=0b00000001 ; // 0XXXXXXX Backgroung Debug Enable ( ICD )const rom unsigned char CONFIG4H=0xff ; // Don't care byteconst rom unsigned char CONFIG5L=0b00001111 ; // Not PROG code protectedconst rom unsigned char CONFIG5H=0b11000000 ; // Not EEPROM code protectedconst rom unsigned char CONFIG6L=0b00001111 ;const rom unsigned char CONFIG6H=0b11100000 ;const rom unsigned char CONFIG7L=0b00001111 ;const rom unsigned char CONFIG7H=0b01000000 ;#pragma romdata// Declaration file for LCD related subroutinesvoid OpenLCD (void) ;void WriteCmdLCD ( unsigned char ) ;void WriteDataLCD( unsigned char ) ;void putsLCD( char * ) ;void putrsLCD( const rom char * ) ;void putcLCD( unsigned char ) ;void puthexLCD( unsigned char ) ;void LCD_Set_Cursor( unsigned char , unsigned char ) ;void LCD_CMD_W_Timing( void ) ;void LCD_L_Delay( void ) ;void LCD_S_Delay( void ) ;void LCD_DAT_W_Timing ( void ) ;#include <p18f452.h>#include <delays.h>#include "P18F_LCD.h"//// Defines for I/O ports that provide LCD data & control// PORTD[0:3]-->DB[4:7]: Higher order 4 lines data bus with bidirectional// : DB7 can be used as a BUSY flag// PORTA,2 --> [E] : LCD operation start signal control// PORTD,5 --> [RW]: LCD Read/Write control// PORTD,4 --> [RS]: LCD Register Select control// : "0" for Instrunction register (Write), Busy Flag (Read) // : "1" for data register (Read/Write)//#define CPU_SPEED 16 // CPU speed is 16 Mhz !!#define LCD_RS PORTDbits.RD4 // The definition of control pins #define LCD_RW PORTDbits.RD5#define LCD_E PORTAbits.RA2#define LCD_DATA LATD // PORTD[0:3] as LCD DB[4:7] //#define LCD_CTRL LATA#define DIR_LCD_DATA TRISD// LCD Module commands#define DISP_2Line_8Bit 0b00111000#define DISP_2Line_4Bit 0b00101000#define DISP_ON 0x00C // Display on#define DISP_ON_C 0x00E // Display on, Cursor on#define DISP_ON_B 0x00F // Display on, Cursor on, Blink cursor#define DISP_OFF 0x008 // Display off#define CLR_DISP 0x001 // Clear the Display#define ENTRY_INC 0x006 //#define ENTRY_INC_S 0x007 //#define ENTRY_DEC 0x004 //#define ENTRY_DEC_S 0x005 //#define DD_RAM_ADDR 0x080 // Least Significant 7-bit are for address#define DD_RAM_UL 0x080 // Upper Left coner of the Display#pragma udataunsigned char Temp_CMD ;unsigned char Str_Temp ;unsigned char Out_Mask ;#pragma codevoid OpenLCD(void){//ADCON1=(ADCON1 & 0xF0)|0b00001110; // Set AN0 for analog inputLCD_E=0;LCD_DATA = 0x00; // LCD DB[4:7] & RS & R/W --> LowDIR_LCD_DA TA = 0x00; // LCD DB[4:7} & RS & R/W are output functionTRISAbits.TRISA2=0; // Set E pin as outputLCD_DATA = 0b00000011 ;LCD_CMD_W_Timing() ;LCD_L_Delay() ;LCD_DATA = 0b00000011 ;LCD_CMD_W_Timing() ;LCD_L_Delay() ;LCD_DATA = 0b00000011 ;LCD_CMD_W_Timing() ;LCD_L_Delay() ;LCD_DATA = 0b00000010 ;LCD_CMD_W_Timing() ;LCD_L_Delay() ;WriteCmdLCD(DISP_2Line_4Bit) ;LCD_S_Delay() ;WriteCmdLCD(DISP_ON) ;LCD_S_Delay() ;WriteCmdLCD(ENTRY_INC) ;LCD_S_Delay() ;WriteCmdLCD(CLR_DISP) ;LCD_L_Delay() ;}//*********************************************// _ ______________________________// RS _>--<______________________________// _____// RW \_____________________________// __________________// E ____________/ \___// _____________ ______// DB _____________>--------------<______//***********************************************// Write Command to LCD module//void WriteCmdLCD( unsigned char LCD_CMD){Temp_CMD = (LCD_CMD & 0xF0)>>4 ; // Send high nibble to LCD bus LCD_DATA= (LCD_DA TA & 0xF0)|Temp_CMD ;LCD_CMD_W_Timing () ;Temp_CMD = LCD_CMD & 0x0F ; // Send low nibble to LCD bus LCD_DATA= (LCD_DA TA & 0xF0)|Temp_CMD ;LCD_CMD_W_Timing () ;LCD_S_Delay() ; // Delay 100uS for execution}//***********************************************// Write Data to LCD module//void WriteDataLCD( unsigned char LCD_CMD){Temp_CMD = (LCD_CMD & 0xF0)>>4 ; // Send high nibble to LCD bus LCD_DATA= (LCD_DA TA & 0xF0)|Temp_CMD ;LCD_DAT_W_Timing () ;Temp_CMD = LCD_CMD & 0x0F ; // Send low nibble to LCD bus LCD_DATA= (LCD_DA TA & 0xF0)|Temp_CMD ;LCD_DAT_W_Timing () ;LCD_S_Delay() ; // Delay 100uS for execution}void putcLCD(unsigned char LCD_Char){WriteDataLCD(LCD_Char) ;}void LCD_CMD_W_Timing( void ){LCD_RS = 0 ; // Set for Command InputNop();// LCD_RW = 0 ;Nop();LCD_E = 1 ;Nop();Nop();LCD_E = 0 ;}void LCD_DAT_W_Timing( void ){LCD_RS = 1 ; // Set for Data InputNop();// LCD_RW = 0 ;Nop();LCD_E = 1 ;Nop();LCD_E = 0 ;}//***********************************************// Set Cursor position on LCD module// CurY = Line (0 or 1)// CurX = Position ( 0 to 15)//void LCD_Set_Cursor(unsigned char CurY, unsigned char CurX) {WriteCmdLCD( 0x80 + CurY * 0x40 + CurX) ;LCD_S_Delay() ;}//***********************************************// Put a ROM string to LCD Module//void putrsLCD( const rom char *Str ){while (1){Str_Temp = *Str ;if (Str_Temp != 0x00 ){WriteDataLCD(Str_Temp) ;Str ++ ;}elsereturn ;}}//***********************************************// Put a RAM string to LCD Module//void putsLCD( char *Str){while (1){Str_Temp = *Str ;if (Str_Temp != 0x00 )WriteDataLCD(Str_Temp) ;Str ++ ;}elsereturn ;}}void puthexLCD(unsigned char HEX_Val){unsigned char Temp_HEX ;Temp_HEX = (HEX_Val >> 4) & 0x0f ;if ( Temp_HEX > 9 )Temp_HEX += 0x37 ;else Temp_HEX += 0x30 ;WriteDataLCD(Temp_HEX) ;Temp_HEX = HEX_Val & 0x0f ;if ( Temp_HEX > 9 )Temp_HEX += 0x37 ;else Temp_HEX += 0x30 ;WriteDataLCD(Temp_HEX) ;}//******************************************************************************* **// Delay for atleast 10 ms//******************************************************************************* **void LCD_L_Delay(void){Delay10KTCYx(CPU_SPEED / 4) ;}//******************************************************************************* **// Delay for 100 us//******************************************************************************* **void LCD_S_Delay(void){Delay100TCYx(CPU_SPEED/4) ;}。
单片机LCD显示
目录1、设计题目2、设计要求及实现功能3、硬件电路原路图4、软件流程图5、程序代码6、实验结果7、实验总结8、参考文献一、设计题目题目三:液晶LCD显示二、设计要求及实现功能要求:用实验台上的16列*1行的字符LCD显示器显示两屏字符:Welcome!Design By 姓名实现功能:编写完程序后,运行时可以在LCD字符显示器上显示:Welcome!Design By 姓名三、硬件电路原理图字符LCD 模块是一种专用显示字符、数字或符号的液晶显示模块。
这种模块每一个符号由5×7、5×8 或5×11 的点阵像素排列组成的,字符间隔为一个点距,行间隔为一个行距,模块本身附有显示驱动控制电路,可以与单片机的I/O 口线直接连接,使用方便。
目前广泛使用的字符LCD 模块其显示驱动控制电路多是HD44780 或兼容品,其接口信号、操作指令相同。
本实验选用的字符LCD 模块是香港精电公司生产的规格为16×1 的字符LCD 模块,可以在一行上显示16 个字符。
该模块与8051 单片机I/O 口线直接连接的电路如图1所示。
字符LCD模块的接口信号:①GND、VCC:电源,VCC=+5V。
②Vee:液晶显示对比度调节电压输入。
可以通过调节LCD 左上角的多圈电位器RW2 来调节。
③DB7~ DB0:数据总线,三态。
用于与模块之间传送信息。
这里连接P1.0~P1.7。
以下3 个信号为控制信号:④RS:寄存器选择信号,输入。
这里连接P3.3(INT1)。
模块中有两类寄存器,一类是指令寄存器,用于写入指令;另一类是数据寄存器,用于写入的数据。
RS=0,选择指令寄存器。
RS=1,选择数据寄存器。
⑤R/W :读/写信号,输入。
这里连接P3.4(T0)。
R/W =1,读操作;R/W =0,写操作⑥E:使能信号,输入。
模块的读/写控制信号。
这里连接P3.5(T1)。
读操作时,E 为高电平时,模块的数据或状态输出至DB7~DB0 上,供单片机读取;写操作时,E 信号的下降沿将单片机送至数据总线上的数据或指令写入模块中。
单片机IO口直接驱动LCD
利用单片机I/O口直接驱动LCD如何将小家电成本降低的同时,又保证其性能,是对应用工程师提出的更高要求。
本控制板需要进行温度控制,显示界面要求LCD显示。
带专用LCD驱动器,又带A/D转换器的单片机成本太高,因此选用台湾义隆公司带A/D的单片机EM78P259N直接驱动LCD。
该款单片机性价比高,性能可靠,很适合在家电控制中应用。
1 LCD简介清华微电子推出高频管分立器件裸片,已做到9G截止频率目前,市面主流LCD(液晶显示器)分成以下几大类:TN(扭曲阵列型)、STN(超扭曲阵列型)、DSTN(双层超扭曲阵列)、HPA(高性能定址或快速DSTN)、TFT(薄膜场效应晶体管)等。
由于成本因素,目前小家电大多数采用的是TN型单色液晶显示器,它的原理是把液晶灌入两个列有细槽的平面之间。
这两个平面上的槽互相垂直(相交成90°),也就是说,若一个平面上的分子南北向排列,则另一平面上的分子东西向排列,而位于两个平面之间的分子被强迫进入一种90°扭转的状态。
由于光线顺着分子的排列方向传播,所以光线经过液晶时也被扭转90°。
当液晶上加一个电压时,分子便会重新垂直排列,使光线能直射出去,而不发生任何扭转。
LCD正是由这样两个相互垂直的极化滤光器构成的,所以在正常情况下应该阻断所有试图穿透的光线。
但是,由于两个滤光器之间充满了扭曲液晶,所以在光线穿出第一个滤光器后,会被液晶分子扭转90°,最后从第二个滤光器中穿出。
另一方面,若为液晶加一个电压,分子又会重新排列并完全平行,使光线不再扭转,所以正好被第二个滤光器挡住。
总之,加电将光线阻断,不加电则使光线射出。
LCD模型可以把其看成一个电容器,一个电极连接着公共极板,另一个连接着字符段。
LCD受电压的均方根值控制,当施加在LCD上的电压为零时,LCD呈透明状态。
当施加在字符段与公共极的电压大于LCD的阀值电压,则该字符段就显示出来。
3.4 单片机控制液晶显示模块1602 LCD的显示
80H+40H=C0H,其中80H为命令代码, 40H是要写入字符处的地址。
5.5.1 LCD 1602液晶显示模块简介
3.字符显Байду номын сангаас位置的确定
图5-17 LCD内部显示RAM的地址映射图
5.5.1 LCD 1602液晶显示模块简介
4.LCD1602的复位
例如,显示字符“A”,单片机只需将字符“A” 的ASCII码41H写入DDRAM,控制电路就会将对 应的字符库ROM(CGROM)中的字符“A”的点 阵数据找出来显示在LCD上。
模块内有80字节数据显示RAM (DDRAM), 除显示192个字符(5×7点阵)的字符库 ROM(CGROM)外,还有64字节的自定义字符 RAM(CGRAM),用户可自行定义8个5×7点阵字符。
5.5.1 LCD 1602液晶显示模块简介
2.LCD1602字符的显示及命令字
5.5.1 LCD 1602液晶显示模块简介
2.LCD1602字符的显示及命令字 表5-3中11个命令功能说明如下:
命令1:清屏,光标返回地址00H位置(显示屏的左上 方)。 命令2:光标返回到地址00H位置(显示屏的左上方)。 命令3:光标和显示模式设置。
而当写入10H~27H或50H~67H地址处时,字符不会 显示出来,该区域也称为隐藏区域。如果要显示写入到隐藏 区域的字符,需要通过字符移位命令(命令5)将它们移入 到可显示区域方可正常显示。
5.5.1 LCD 1602液晶显示模块简介
3.字符显示位置的确定
需说明的是,在向DDRAM写入字符时, 首先要设置DDRAM定位数据指针,此操作可 通过命令8完成。
单片机控制的LCD汉字显示电路设计(独家完整版)
单片机控制的LCD汉字显示电路设计1概述自20世纪以来,电子行业发生着翻天覆地的变化。
电子行业的发展推动着社会的发展,因此,世界各国也大力发展电子行业。
其中,在电子行业中,显示器产业是其中尤为重要的产业之一。
然而,在显示器产业中,LCD技术是最重要的技术之一。
众所周知,单片机像是电子行业中发挥着巨大作用的精灵。
它的能耗小、价格低廉,在简单的电子实验方面的应用非常广泛,在教育教学中深受广大电子教育工作者的喜爱。
1.1课题背景在电子行业中,LCD已被公认为是媒体时代的关键器件,它的低功耗、体积小、易于实现画面显示及优良的全色显示性能等特点,使其在现代社会中得到了广泛的应用。
可以说,LCD是本世纪初最有活力的电子产品之一。
与此同时,单片机的应用领域也非常广泛,大到导弹的导航装置,飞机上各种仪表的控制,小到广泛使用的智能IC卡,比如学校中使用的校园一卡通等,这些都离不开单片机。
因此,通过使用单片机可以使我们完成很多令我们意想不到的事情。
所以,本着理论与实践相结合的原则,本设计以单片机为核心控制器件控制LCD显示模块,通过硬件和软件的共同配合实现在128×64点阵液晶屏上显示汉字、字符等的功能,本系统由ATMEGA8单片机和点阵式液晶显示屏模块构成。
1.2设计要求系统硬件设计:系统选用ATMEGA8单片机作为主控和处理设备,LCD12864模块作为输出设备。
系统软件设计:微控制器处理和LCD模块显示部分的程序设计。
1.3 LCD简介及发展液晶显示器是一种采用了液晶控制透光度技术来实现色彩的显示器。
众所周知,即使长时间观看LCD显示屏幕也不会对眼睛造成伤害,这主要是因为LCD显示器没有辐射,画面图像很稳定。
LCD 可分为段位式LCD、字符式LCD 和点阵式LCD。
其中,段位式LCD 和字符式LCD 只能用于字符和数字的简单显示,不能满足图形曲线和汉字显示的要求;而点阵式LCD 不仅可以显示字符、数字,还可以显示各种图形、曲线及汉字,并且可以实现屏幕上下左右滚动、动画、分区开窗口、反转、闪烁等功能,用途十分广泛。
单片机与LCD显示屏的通信接口技术解析
单片机与LCD显示屏的通信接口技术解析LCD显示屏作为一种重要的输出设备,广泛应用于各个领域中。
为了使单片机能够与LCD显示屏进行有效的通信和控制,需要使用相应的通信接口技术。
本文将对单片机与LCD显示屏的通信接口技术进行详细解析,包括串行接口和并行接口两种常见的通信方式。
首先,我们来介绍串行接口技术。
串行接口是指通过单根数据线进行数据传输的通信方式。
在单片机与LCD显示屏的串行通信中,常用的接口协议有SPI (Serial Peripheral Interface)、I2C(Inter-Integrated Circuit)和UART(Universal Asynchronous Receiver Transmitter)等。
SPI是一种高速全双工的串行通信接口,适用于对传输速度和带宽要求较高的应用场景。
SPI接口使用四根信号线进行通信,包括SCLK(串行时钟)、SS(使能信号)、MISO(主输入从输出)和MOSI(主输出从输入)。
通过SCLK信号同步,SS信号控制数据传输的开始和结束,MISO和MOSI分别用于主从设备之间的数据传输。
SPI接口速度快、实时性好,但是需要使用的引脚较多。
I2C是一种双线制串行总线接口,适用于连接多个器件的通信。
I2C接口只需要两根信号线,包括SCL(串行时钟线)和SDA(串行数据线)。
其中,SCL由主设备控制,用于同步数据的传输;而SDA用于实际的数据传输,包括指令和数据的发送和接收。
I2C接口具有线路简单、器件连接方便的特点,但在传输速度上相对较慢。
UART是一种通用的串行通信接口,适用于比较简单的应用场景。
UART接口通过两根信号线进行通信,包括RX(接收线)和TX(发送线)。
其中,RX负责接收数据,TX负责发送数据。
UART接口提供点对点的通信,通信简单可靠,但是传输速率较低。
除了串行接口,单片机与LCD显示屏的通信还可以使用并行接口。
并行接口是指通过多根数据线同时传输多个数据位的通信方式。
单片机与LCD液晶显示屏接口设计方法
单片机与LCD液晶显示屏接口设计方法随着科技的发展,液晶显示屏已经成为了我们日常生活和工作中不可或缺的一部分。
而单片机作为一种高性能微控制器,也广泛应用于各种电子设备中。
因此,单片机与LCD液晶显示屏之间的接口设计显得非常重要。
本文将介绍几种常见的单片机与LCD液晶显示屏接口设计方法。
1. 并行接口法并行接口法是最基本也是最直接的接口方法。
它使用多个IO口来控制LCD的数据和控制信号。
通常需要8条数据线和3~4条控制线,用于传输显示数据和控制信号。
并行接口法的优点是传输速度较快,对单片机来说比较简单。
缺点是占用IO端口多,对于资源有限的单片机可能不太适用。
2. 串行接口法串行接口法采用串行通信方式来传输数据和控制信号。
它只需要3条IO口即可实现与LCD的通信。
由于只用到少量的IO口,因此在资源有限的情况下比较适用。
串行接口法的缺点是传输速度较慢,显示效果相对较差。
3. I2C接口法I2C接口法是一种常用的串行通信协议,具有多对多的特点。
它只需要2条IO 口,一条用于数据传输,一条用于时钟同步。
I2C接口法适用于单片机与多个外设的通信,能够节省IO资源。
缺点是传输速度较慢,对于要求实时性较高的应用场景可能不太适用。
4. SPI接口法SPI接口法是一种高速串行通信协议,适用于单片机与外设之间的通信。
它需要4条IO口,分别是时钟线、数据线、主设备输出线和主设备输入线。
SPI接口法传输速度快,对于要求实时性较高的应用场景非常适用。
但与此同时,SPI接口法所需的IO资源也比较多。
在设计单片机与LCD液晶显示屏接口时,需要注意以下几点:1. 引脚定义:根据具体的单片机和LCD液晶显示屏的规格书,合理选择引脚定义。
确保引脚连接正确,避免接错导致通信失败。
2. 时序要求:单片机与LCD液晶显示屏之间的通信需要遵循一定的时序要求。
在设计接口时,需根据LCD的规格书中提供的时序要求,设置单片机相应的延时时间,以保证通信稳定。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
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 <reg51.h>/********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与单片机连接的引脚并不是固定的,如有不同只需要在程序里改一下引脚即可。
(注:可编辑下载,若有不当之处,请指正,谢谢!)。