LCD1602的电路图和程序

合集下载

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 个地址。对应如下:

LCD1602液晶显示器

LCD1602液晶显示器

实验11:1602液晶显示屏显示(字符型液晶显示器)字符型液晶显示器用于数字、字母、符号并可显示少量自定义符号。

这类液晶显示器通常有16根接口线,下表是这16根线的定义。

字符型液晶接口说明编号符号引脚说明编号符号引脚说明1 Vss 电源地 9 D2 数据线22 Vdd 电源正 10 D3 数据线33 VL 液晶显示偏压信号 11 D4 数据线44 RS 数据/命令选择端 12 D5 数据线55 R/W 读/ 写选择端 13 D6 数据线66 E 使能信号 14 D7 数据线77 D0 数据线0 15 BLA 背光源正极8 D1 数据线1 16 BLK 背光源负极(本学习板配的内部已经接地)下图是字符型液晶显示器与单片机的接线图。

这用了P0口的8根线作为液晶显示器的数据线,用P20、P21、P22做为3根控制线。

字符型液晶显示器与单片机的接线图字符型液晶显示器的使用,字符型液晶显示器一般采用HD44780芯片做为控制器的。

1.字符型液晶显示器的驱动程序这个驱动程序适用于1602型字符液晶显示器,1) 初始化液晶显示器命令(RSTLCD)设置控制器的工作模式,在程序开始时调用。

参数:无。

2) 清屏命令(CLRLCD)清除屏幕显示的所有内容参数:无3) 光标控制命令(SETCUR)用来控制光标是否显示及是否闪烁参数:1个,用于设定显示器的开关、光标的开关及是否闪烁。

4) 写字符命令(WRITECHAR)在指定位置(行和列)显示指定的字符。

参数:共有3个,即行值、列值及待显示字符,分别存放在XPOS、YPOS和A中。

其中行值与列值均从0开始计数,A中可直接写入字符的符号,编译程序自动转化为该字符的ASCII值。

5) 字符串命令(WRITESTRING)在指定位置显示指定的一串字符。

参数:共有3个,即行值、列值和R0指向待显示字符串的内存首地址,字符串须以0结尾。

如果字符串的长度超过了从该列开始可显示的最多字符数,则其后字符被截断,并不在下行显示出来。

lcd1602程序流程图

lcd1602程序流程图

LCD1602:
LCD1602液晶显示器是广泛使用的一种字符型液晶显示模块。

它是由字符型液晶显示屏(LCD)、控制驱动主电路HD44780及其扩展驱动电路HD44100,以及少量电阻、电容元件和结构件等装配在PCB板上而组成。

不同厂家生产的LCD1602芯片可能有所不同,但使用方法都是一样的。

为了降低成本,绝大多数制造商都直接将裸片做到板子上。

字符型液晶显示原理:
点阵图形式液晶由M×N个显示单元组成,假设LCD显示屏有64行,每行有128列,每8列对应1字节的8位,即每行由16字节,共16×8=128个点组成。

显示屏上64×16个显示单元与显示RAM区的1024字节相对应,每一字节的内容与显示屏上相应位置的亮暗对应。

例如显示屏第一行的亮暗由RAM区的000H~00FH的16字节的内容决定,当(000H)=FFH时,屏幕左上角显示一条短亮线,长度为8个点;当(3FFH)=FFH时,屏幕右下角显示一条短亮线;当(000H)=FFH,(001H)=00H,(002H)=00H…,(00EH)=00H,(00FH)=00H时,在屏幕的顶部显示一条由8条亮线和8条暗线组成的虚线。

这就是LCD显示的基本原理。

字符型液晶显示模块是一种专门用于显示字母、数字和符号等的点阵式LCD,常用16×1,16×2,20×2和40×2等的模块。

一般的LCD1602字符型液晶显示器的内部控制器大部分为HD44780,能够显示英文字母、阿拉伯数字、日文片假名和一般性符号。

lcd1602程序流程图

lcd1602程序流程图

LCD1602程序代码和显示流程图LCD1602显示程序代码_ DB P0 //---P0 = DB0〜DB7位LCD_ RS = P2; //--p2.0 = RS 位LCD_ RW = P2; //--p2.1 = RW 位LCD_ E = P2; //-p2.2 = E / /---/--/--定义函数ා 定义uchar unsigned char ා 定义uint unsigned int // //-定义子程序函数void LCD_ Init (void ); //-初始化LCD1602函数void LCD_ write_ Command (uchar command ); //-写指令功能无效LCD 到LCD1602_ write_数据(uchar DAT ); //-将无效的LCD 数据写入LCD1602_ set_ XY (uchar x ,uchar y ); //设置LCD1602的显示位置x (0-16),y(1-2)void LCD_ disp_ Char(uchar x,uchar y,uchar DAT); //-在LCD1602_ disp_ String (uchar x,uchar y,uchar * s)上显示字符无效的LCD;//-在LCD1602上显示字符串// void LCD_ check_ Busy(void); //检查忙功能。

我没有使用此功能,因为通过率非常低。

LCD_ delay_ 10us(uint n); //-一个10微秒的延迟子程序void LCD_ delay_ 50uS(uint n); /-延迟子程序50微秒_ init(无效){LCD_ delay_ 10us(20); LCD_ write_命令(0x38); //-设置8位格式,2行,5x7 LCD_ delay_ 10us(5);LCD_ write_命令(0x0c); //-整体显示,关闭光标,不闪烁LCD_ delay_ 10us(5);LCD_ write_命令(0x06); //-设置输入模式,增量不移位LCD_ delay_ 10us(5);LCD_ write_命令(0x01); // /-清除屏幕上的LCD_ delay_ 50uS(40);} //将无效的LCD指令写入LCD1602_ write_命令(uchar dat){LCD_ delay_ 10us (5);LCD_ Rs = 0; //命令LCD_RW = 0;//写入LCD_ DB = dat; LCD_ delay_ 10us(5); LCD_ E = 1; //允许LCD_delay_10us(5);LCD_ E = 0;} /-将数据无效LCD写入LCD1602_ write_ data(uchar dat){LCD_ delay_ 10us(5);LCD_ Rs = 1; //数据LCD_RW = 0;//写入LCD_ DB = dat; LCD_ delay_ 10us(5); LCD_ E = 1; //允许LCD_delay_10us(5);LCD_ E = 0;} /-设置显示位置无效LCD_ set_ XY(uchar x,uchar y){uchar地址;如果(y = = 1){地址= 0x80 + X; /-第一行位置} else {地址= 0xc0 + X; //第二行位置} LCD_ delay_ 10us(5); LCD_ write_命令(地址);} /-显示字符函数void LCD_ disp_ char(uchar x,uchar y,uchar dat)//--LCD_ disp_ Char(0,1,0x38); /-显示8 {LCD_ set_ xy(x,y); LCD_ delay_ 10us(5); LCD_ write_ Data(DAT);} /-显示字符串函数void LCD_ disp_ string(uchar x,uchar y,uchar * s){LCD_ set_ xy(x,y); LCD_ delay_ 10us(5); while(* s!='\ 0'){LCD_ write_ Data(* s); s + +;} / /≡S + +;} /≡S + _ check_ Busy()// /实践证明,在我的LCD1602上,检查忙指令的通过率非常低,并且{/ /液晶正常使用。

LCD1602数据手册LCD16...

LCD1602数据手册LCD16...

LCD1602数据手册1602采用标准的16脚接口,其中:第1脚:VSS为地电源第2脚:VDD接5V正电源第3脚:V0为液晶显示器对比度调整端,接正电源时对比度最弱,接地电源时对比度最高,对比度过高时会产生“鬼影”,使用时可以通过一个10K的电位器调整对比度第4脚:RS为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器。

第5脚:RW为读写信号线,高电平时进行读操作,低电平时进行写操作。

当RS和RW共同为低电平时可以写入指令或者显示地址,当RS为低电平RW为高电平时可以读忙信号,当RS为高电平RW为低电平时可以写入数据。

第6脚:E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令。

第7~14脚:D0~D7为8位双向数据线。

第15~16脚:空脚1602液晶模块内部的字符发生存储器(CGROM)已经存储了160个不同的点阵字符图形,如表1所示,这些字符有:阿拉伯数字、英文字母的大小写、常用的符号、和日文假名等,每一个字符都有一个固定的代码,比如大写的英文字母“A”的代码是01000001B(41H),显示时模块把地址41H中的点阵字符图形显示出来,我们就能看到字母“A”1602液晶模块内部的控制器共有11条控制指令,如表2所示,它的读写操作、屏幕和光标的操作都是通过指令编程来实现的。

(说明:1为高电平、0为低电平)指令1:清显示,指令码01H,光标复位到地址00H位置指令2:光标复位,光标返回到地址00H指令3:光标和显示模式设置 I/D:光标移动方向,高电平右移,低电平左移 S:屏幕上所有文字是否左移或者右移。

高电平表示有效,低电平则无效指令4:显示开关控制。

D:控制整体显示的开与关,高电平表示开显示,低电平表示关显示 C:控制光标的开与关,高电平表示有光标,低电平表示无光标 B:控制光标是否闪烁,高电平闪烁,低电平不闪烁指令5:光标或显示移位 S/C:高电平时移动显示的文字,低电平时移动光标指令6:功能设置命令 DL:高电平时为4位总线,低电平时为8位总线 N:低电平时为单行显示,高电平时双行显示 F: 低电平时显示5x7的点阵字符,高电平时显示5x10的点阵字符指令7:字符发生器RAM地址设置指令8:DDRAM地址设置指令9:读忙信号和光标地址 BF:为忙标志位,高电平表示忙,此时模块不能接收命令或者数据,如果为低电平表示不忙。

IIC接口 I2C接口 LCD1602 程序

IIC接口 I2C接口 LCD1602 程序

PIC16F1824驱动IIC/I2C接口LCD1602液晶模块前一段时间,做一个显示电路,7段码显示内容太少,LCD1602占用的IO又太多,最后找到一种IIC/I2C接口LCD1602转接板。

T宝上买的LCD1602转接板,有资料,不过是针对Arduino的。

决定自己写程序。

首先得知道从器件地址。

T宝卖家给的地址是0x27(针对Arduino),而单片机使用的时候需要先左移一位,0x4E;测试的时候一直没反应,用示波器看,单片机发送的地址没问题,但转接板没有应答,ACK 一直是高电平,推测还是地址错误;后来搜索发现,PCF8574与PCF8574A的地址是不一样的,而T宝卖的是PCF8574A,给的资料还是PCF8574。

最后确认,从器件PCF8574A地址应该是0x7E;后来发送地址0x7E后,有应答ACK,又搜了写LCD1602的显示程序,稍微改了改,显示成功了;主要的程序如下:MCU:PIC16F1824IIC/I2C接口LCD1602转接板:PCF8574ATmain.c中包含:I2CInit();LCD1602Init();Dip_Single_char(1,5,'A');//********************************************************************// 文件名称: I2C.h// 创建日期: 2016-10-11// 最新更改: 2016-10-11// 描述: I2C初始化//********************************************************************//#define _XTAL_FREQ 2000000 // 延时函数delay_us/ms使用此值#define Slave_Add 0x7E // 从器件地址,PCF8574A,0x7E// PCF8574,0x27,左移1位,0x4E,#define I2C_BPS 0x18 // I2C波特率Fclock = Fosc/((I2C_BPS+1)*4) // 2MHz,20k,0x18#define Idle !(SSP1STATbits.R_nW|(0x1F & SSP1CON2)) // 空闲void I2CInit ( );void I2CStart ( );void I2CStop ( );void ReStart ( );void I2CSendByte(unsigned char I2CSnBy);void WriteCommand(unsigned char Command);void WriteData (unsigned char Data);void LCD1602Init(void);void Dip_Single_char(unsigned char col,unsigned char row,unsigned char sign); void DisDec(unsigned char col_D,unsigned char row_D,unsigned int Temp_k );/*********************************************************************** The End*********************************************************************///********************************************************************// 文件名称: I2C.c// 创建日期: 2016-10-11// 最新更改: 2016-10-11// 描述: I2C初始化//********************************************************************//#include "xc.h"#include "I2C.h"/*********************************************************************** Function name: I2CInit** Descriptions: 注意:必须将SDA、SCL引脚配置为输入引脚,<<DS P293>>** input parameters: 无** output parameters: 无** Returned value: 无**********************************************************************/void I2CInit (void){SSP1STATbits.SMP = 1; // 禁止标准速度模式下的压摆率控制SSP1STATbits.CKE = 0; // 禁止SMBus特定输入SSP1CON1bits.SSPEN = 1; // 使能I2C,并将SDA 和SCL引脚配SSP1CON1bits.SSPM = 0x8; // I2C主模式SSP1ADD = I2C_BPS; // Fclock = Fosc / ((SSP1ADD + 1)*4)}/*********************************************************************** Function name: I2CStart ( )** Descriptions: I2C开始** input parameters: 无** output parameters: 无** Returned value: 无**********************************************************************/void I2CStart ( ){while (!Idle);SSP1CON2bits.SEN = 1; // 在SDA和SCL引脚上发出启动条件,硬件自动清零 while(SSP1CON2bits.SEN); // 启动条件发送完成while(!Idle);}/*********************************************************************** Function name: I2CStop ( )** Descriptions: I2C停止** input parameters: 无** output parameters: 无** Returned value: 无**********************************************************************/void I2CStop(){while (!Idle);SSP1CON2bits.PEN = 1; // 在SDA和SCL引脚上发出停止条件,硬件自动清零 while(SSP1CON2bits.PEN); // 停止条件发送完成while(!Idle);}/*********************************************************************** Function name: ReStart()** Descriptions: I2C ,ReStart** input parameters: 无** output parameters: 无** Returned value: 无**********************************************************************/void ReStart(){while (!Idle);SSP1CON2bits.RSEN = 1; // 在SDA和SCL引脚上发出重复启动条件,硬件自动清零while(SSP1CON2bits.RSEN); // 重复启动条件发送完成while(!Idle);}/*********************************************************************** Function name: I2CSendByte()** Descriptions: SSP1BUF中写入字节** input parameters: I2CSnBy,要发送的数据** output parameters: 无** Returned value: 无**********************************************************************/void I2CSendByte(unsigned char I2CSnBy) {while (!Idle);SSP1BUF = I2CSnBy; // SSP1BUF中写入字节while(!Idle);}/*********************************************************************** Function name:** Descriptions:** input parameters:** output parameters: 无** Returned value: 无**********************************************************************/void WriteCommand(unsigned char Command){I2CStart(); // I2C开始I2CSendByte(Slave_Add); // 从器件地址unsigned char Temp_C;Temp_C = Command & 0xF0;Temp_C |= 0x0C; // P3=1 EN=1 RW=0 RS=0I2CSendByte(Temp_C);Temp_C &= 0xF8; // P3=1 EN=0 RW=0 RS=0I2CSendByte(Temp_C);Temp_C = (Command & 0x0F)<< 4;Temp_C |= 0x0C; // P3=1 EN=1 RW=0 RS=0I2CSendByte(Temp_C);Temp_C &= 0xF8; // P3=1 EN=0 RW=0 RS=0I2CSendByte(Temp_C);I2CStop(); // I2C停止}/********************************************************************* ** Function name:** Descriptions:** input parameters:** output parameters: 无** Returned value: 无**********************************************************************/void WriteData (unsigned char Data){I2CStart(); // I2C开始I2CSendByte(Slave_Add); // 从器件地址unsigned char Temp_D;Temp_D = Data & 0xF0;Temp_D |= 0x0D; // P3=1 EN=1 RW=0 RS=1I2CSendByte(Temp_D);Temp_D &= 0xF9; // P3=1 EN=0 RW=0 RS=1I2CSendByte(Temp_D);Temp_D = (Data & 0x0F)<< 4;Temp_D |= 0x0D; // P3=1 EN=1 RW=0 RS=1I2CSendByte(Temp_D);Temp_D &= 0xF9; // P3=1 EN=0 RW=0 RS=1I2CSendByte(Temp_D);I2CStop(); // I2C停止}/*********************************************************************** Function name: LCD1602Init(void),LCD1602初始化** Descriptions: 写一次,偶尔不能正常显示,重复2次** input parameters:** output parameters: 无** Returned value: 无**********************************************************************/void LCD1602Init(void){__delay_ms(10);WriteCommand(0x33); __delay_ms(5);WriteCommand(0x32); __delay_ms(5);WriteCommand(0x28); __delay_ms(5);WriteCommand(0x0C); __delay_ms(5);WriteCommand(0x06); __delay_ms(5);WriteCommand(0x01); __delay_ms(5); // 清屏__delay_ms(10);WriteCommand(0x33); __delay_ms(5);WriteCommand(0x32); __delay_ms(5);WriteCommand(0x28); __delay_ms(5);WriteCommand(0x0C); __delay_ms(5);WriteCommand(0x06); __delay_ms(5);WriteCommand(0x01); __delay_ms(5); // 清屏}/********************************************************************** Function name: L1602_char(uchar col,uchar row,char sign)** Descriptions: 改变液晶中某位的值,如果要让第一行,第五个字符显示"b" ,调用该函数如,Dip_Single_char(1,5,'A');** input parameters: 行,列,需要输入1602的数据** output parameters: 无** Returned value: 无*********************************************************************/void Dip_Single_char(unsigned char col,unsigned char row,unsigned char sign){ unsigned char a;if(col == 1) a = 0x80;if(col == 2) a = 0xc0;a = a + row - 1;WriteCommand(a);WriteData(sign);}/********************************************************************** Function name: Dip_Single_char** Descriptions: 显示int型数据,5位** input parameters: 行,列,数据** output parameters: 无** Returned value: 无*********************************************************************/void DisDec(unsigned char col_D,unsigned char row_D,unsigned int Temp_k ){if(Temp_k>=65535) Temp_k=65535;unsigned int Temp_Ts;unsigned char Table[5]; // 数字与1602显示码转换Table[0] = Temp_k/10000+48; // 万位Temp_Ts = Temp_k%10000; // 取余,0-9999Table[1] = Temp_Ts/1000+48; // 千位Temp_Ts = Temp_Ts%1000; // 取余,0-999Table[2] = Temp_Ts/100+48; // 百位Temp_Ts = Temp_Ts%100; // 取余,0-99Table[3] = Temp_Ts/10+48; // 十位Table[4] = Temp_Ts%10+48; // 个位unsigned char q;for(q=0;q<5;q++){ // 显示Dip_Single_char(col_D,q+row_D,Table[q]);}}/*********************************************************************** The End*********************************************************************/。

LCD1602中文资料程序和使用说明

LCD1602中文资料程序和使用说明

LCD1602中文资料程序和使用说明一、硬件连接和初始化步骤:1.将LCD1602的16个引脚连接到MCU(单片机)的相应引脚上。

其中,VCC和GND分别接到电源正负极,VO接到可调电位器的中间引脚(用于调节背光亮度),RS、RW和E分别接到MCU的IO口上,D0-D7分别接到MCU的8个IO口上。

2.初始化LCD1602的操作包括设置显示模式、显示光标、输入模式等,具体步骤如下:a.将8位数据接口设置为并行输入模式,即设置D0-D3为输入模式。

b.设置显示模式为2行显示,5x8点阵字符,显示器不移动。

c.将显示光标设置为闪烁显示。

d.设置数据输入方式为向右移动,同时字符显示不移动。

e.清除显示内容,将光标位置设置为第一行第一列。

f.打开显示器和光标显示功能。

二、常用函数和操作方法:1. void lcd1602_init( 初始化LCD1602,包括上述硬件连接和初始化步骤。

2. void lcd1602_clear( 清除显示内容。

3. void lcd1602_setCursor(int row, int column) 设置光标位置,row表示行数(从0开始),column表示列数(从0开始)。

4. void lcd1602_print(String str) 在当前光标位置打印字符串str。

5. void lcd1602_shiftDisplayLeft( 将显示内容向左移动一位。

6. void lcd1602_shiftDisplayRight( 将显示内容向右移动一位。

7. void lcd1602_scrollDisplayLeft( 将整个显示内容向左滚动一格。

8. void lcd1602_scrollDisplayRight( 将整个显示内容向右滚动一格。

9. void lcd1602_noCursor( 关闭光标显示。

10. void lcd1602_cursor( 打开光标显示。

lcd1602程序流程图

lcd1602程序流程图

lcd1602程序流程图lcd1602程序流程图1、引脚3(对⽐调整电压)接正电源时对⽐度最低,接地时对⽐度最⾼,通常通过⼀个10k的电位器相连后接地,上电后需要对电位器进⾏调整以显⽰出相应的字符(就像调节电视的对⽐度使图像清晰,这⾥是使字符清晰)2、D0~D7为8为数据总线,⽤于与单⽚机之间的数据传送了解了引脚功能后,我们再来看其内置芯⽚关于HD44780HD44780内部含有DDRAM,CGROM,CGRAM下⾯我来简单介绍⼀下这三个存储器DDRAM是⽤于寄存待显⽰字符代码的,其内部带有80字节的RAM 缓冲区,与LCD屏幕的位置⼀⼀对应。

通常我们只使⽤前16个地址(两⾏32个),这样⼀来,我们便可以将这32个地址当作是我们的坐标,⽐如要在DDRAM的02H 地址(对应的是屏幕第⼀⾏第三个)显⽰字符“A”,我们就可以分两步⾛,⾸先⽤程序先找到“坐标点”,也就是将地址转到02H(具体如何不做详细说明),然后在这个位置写⼊“A”,写⼊地址和数据都是通过D0~D7实现的,详细的程序在⽂章的后⾯举例说明。

CGROM与CGRAM是LCD内部固化的字模存储器,这相当于芯⽚内部划出的⼀块区域,CGROM⾥⾯存放着我们⽇常所使⽤的⼀些字符(192个),⽽CGRAM则允许⽤户⾃定义⼀些字符(8个)。

具体对应关系如下,0x00~0x0F就是⽤户⾃定义的CGRAM区。

再回到之前的问题,在DDRAM的02H地址显⽰字符“A”,⾸先通过程序找到地址02H,然后在该地址写⼊41H,从图中也可看出该位置对应的字符就是“A”。

我们再来理⼀理这个过程,有关字符显⽰,⾸先便是找到DDRAM 中我们所要显⽰位置对应的地址,接着便是在这个地址写⼊⼀个地址(单⽚机中的间接寻址),LCD根据这个地址在CGROM中找到对应的字符,然后在02H这个位置显⽰出来,这个过程也到此结束。

由于CGROM中的字符代码与PC中的字符代码基本⼀致,通常我们也直接在02H地址直接写⼊“A”,简化了程序设计。

lcd1602流程图

lcd1602流程图

lcd1602流程图LCD1602流程图是指在液晶显示屏模块上显示特定信息的流程图。

下面我们将介绍一个简单的LCD1602流程图,包括初始化液晶模块、设置显示模式、输入要显示的内容等步骤。

首先,我们需要准备一个Arduino开发板和一个LCD1602模块。

将LCD模块的VCC和GND引脚分别连接到Arduino的3.3V和GND引脚上,将SDA和SCL引脚连接到Arduino的A4和A5引脚上。

然后,编写以下步骤来实现流程图。

第一步,初始化液晶模块。

在Arduino开发环境中,我们需要包含LiquidCrystal_I2C.h库文件,然后创建一个LiquidCrystal_I2C对象。

使用begin()函数初始化LCD模块,并设置显示模式和光标的闪烁。

第二步,设置显示模式。

使用setCursor()函数将光标移动到特定位置,并使用print()函数输入要显示的内容。

根据需要可以设置一到两行进行显示。

第三步,设置滚动显示。

使用scrollDisplayLeft()或scrollDisplayRight()函数在屏幕上滚动显示内容。

第四步,设置光标显示状态。

使用noCursor()函数关闭光标显示,使用cursor()函数开启光标显示。

第五步,设置光标闪烁状态。

使用noBlink()函数关闭光标闪烁,使用blink()函数开启光标闪烁。

第六步,设置显示打开/关闭状态。

使用noDisplay()函数关闭显示,使用display()函数开启显示。

第七步,设置自定义字符。

使用createChar()函数在CGRAM (字符生成RAM)中自定义字符,并使用write()函数在屏幕上显示。

第八步,清除屏幕。

使用clear()函数清除屏幕上的内容。

第九步,设置屏幕显示次数。

使用blinkDisplay()函数设置屏幕的显示次数,并使用count()函数检测屏幕的显示次数。

第十步,控制光标位置。

使用setCursor()函数将光标移动到特定位置。

STM32的LCD1602显示程序

STM32的LCD1602显示程序

STM32的LCD1602显⽰程序STM32的LCD1602显⽰程序以下为课设期间为1602显⽰屏驱动写的stm32的程序,其中参考了许多⼤佬的例⼦程序设计:硬件原理:D0-D7⽤的是PD0-PD7,RS为PB10,E为PB11,RW为PB12,使⽤的板⼦是STM32F103VET6下⾯是我的程序,只完成了基础功能,并没有⾃定义字模部分的代码lcd.h#ifndef __LCD_H#define __LCD_H#include "stm32f10x.h"/////////////////////////////////////////////////////////#define D0_1 GPIO_SetBits(GPIOD,GPIO_Pin_0)#define D0_0 GPIO_ResetBits(GPIOD,GPIO_Pin_0)#define D1_1 GPIO_SetBits(GPIOD,GPIO_Pin_1)#define D1_0 GPIO_ResetBits(GPIOD,GPIO_Pin_1)#define D2_1 GPIO_SetBits(GPIOD,GPIO_Pin_2)#define D2_0 GPIO_ResetBits(GPIOD,GPIO_Pin_2)#define D3_1 GPIO_SetBits(GPIOD,GPIO_Pin_3)#define D3_0 GPIO_ResetBits(GPIOD,GPIO_Pin_3)#define D4_1 GPIO_SetBits(GPIOD,GPIO_Pin_4)#define D4_0 GPIO_ResetBits(GPIOD,GPIO_Pin_4)#define D5_1 GPIO_SetBits(GPIOD,GPIO_Pin_5)#define D5_0 GPIO_ResetBits(GPIOD,GPIO_Pin_5)#define D6_1 GPIO_SetBits(GPIOD,GPIO_Pin_6)#define D6_0 GPIO_ResetBits(GPIOD,GPIO_Pin_6)#define D7_1 GPIO_SetBits(GPIOD,GPIO_Pin_7)#define D7_0 GPIO_ResetBits(GPIOD,GPIO_Pin_7)#define RS_1 GPIO_SetBits(GPIOB,GPIO_Pin_10)#define RS_0 GPIO_ResetBits(GPIOB,GPIO_Pin_10)#define RW_1 GPIO_SetBits(GPIOB,GPIO_Pin_12)#define RW_0 GPIO_ResetBits(GPIOB,GPIO_Pin_12)#define E_1 GPIO_SetBits(GPIOB,GPIO_Pin_11)#define E_0 GPIO_ResetBits(GPIOB,GPIO_Pin_11)/////////////////////////////////////////////////////////void LCD_Init(void);//初始化void LCD_Clear(void);//清除显⽰void LCD_CursorReset(void);//光标返回void LCD_SetInput(u16,u16);//置输⼊模式void LCD_Display(u16,u16,u16);//显⽰开关控制void LCD_COD(u16,u16);//光标或显⽰移动指令void LCD_Mode(u16,u16,u16);//⼯作⽅式设置void LCD_CGRAM_Addr(u8);//设置CGRAN地址,除置位位以外共六位void LCD_DDRAM_Addr(u8);//设置DDRAM地址,除置位位以外共七位void LCD_RB(void);//当1602处于忙状态时,不接受指令,当不忙时,接受指令void LCD_Write(u8);//写⼊数据void LCD_Read(void);//读取数据void LCD_WriteStr(u8*,int);//写⼊字符串#endiflcd.c#include "lcd.h"#include "stm32f10x_gpio.h"void LCD_Init(void){GPIO_InitTypeDef GPIO_LCDStr;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);GPIO_LCDStr.GPIO_Mode=GPIO_Mode_Out_PP;GPIO_LCDStr.GPIO_Speed=GPIO_Speed_50MHz;GPIO_LCDStr.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7; GPIO_Init(GPIOD,&GPIO_LCDStr);GPIO_LCDStr.GPIO_Pin=GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_10;GPIO_Init(GPIOB,&GPIO_LCDStr);}//////////////////////////////////////////////////////////////////////////////void LCD_Clear(void){E_0;LCD_RB();RS_0;RW_0;GPIO_Write(GPIOD,0x01);E_1;E_0;}//////////////////////////////////////////////////////////////////////////////////void LCD_CursorReset(void){E_0;LCD_RB();RS_0;RW_0;GPIO_Write(GPIOD,0x02);E_1;E_0;}//////////////////////////////////////////////////////////////////////////////////////void LCD_SetInput(u16 ID,u16 S){E_0;LCD_RB();RS_0;RW_0;D7_0;D6_0;D5_0;D4_0;D3_0;D2_1;if(ID==1)/*⾼电平光标右移,低电平左移*/D1_1;else if(ID==0)D1_0;if(S==1)/*屏幕上所有的⽂字是否左移或右移,⾼电平有效,低电平⽆效*/ D0_1;else if(S==0)D0_0;E_1;E_0;}//////////////////////////////////////////////////////////////////////////////////////////void LCD_Display(u16 D,u16 C,u16 B){E_0;LCD_RB();RS_0;RW_0;D7_0;D6_0;D5_0;D4_0;D3_1;if(D==1)//⾼电平开,低电平关D2_1;else if(D==0)D2_0;if(C==1)//⾼电平有光标,低电平⽆光标D1_1;else if(C==0)D1_0;if(B==1)//光标是否闪烁,⾼电平闪烁,低电平⽆D0_1;else if(B==0)D0_0;E_1;E_0;}////////////////////////////////////////////////////////////////////////////////////////////void LCD_COD(u16 SC,u16 RL){E_0;LCD_RB();RS_0;RW_0;D7_0;D6_0;D5_0;D4_1;D1_1;D0_1;if(SC==1)//⾼电平显⽰移动的⽂字,低电平移动坐标D3_1;else if(SC==0)D3_0;if(RL==1)//⾼电平右移,低电平左移D2_1;else if(RL==0)D2_0;E_1;E_0;}////////////////////////////////////////////////////////////////////////////////////////////void LCD_Mode(u16 DL,u16 N,u16 F){E_0;LCD_RB();E_1;RS_0;RW_0;D7_0;D6_0;D5_1;D1_1;D0_1;if(DL==1)//⾼电平⼋位数据接⼝,低电平四位数据接⼝D4_1;else if(DL==0)D4_0;if(N==1)//⾼电平两⾏显⽰,低电平⼀⾏显⽰D3_1;else if(N==0)D3_0;if(F==1)//⾼电平5x10点阵,低电平5x8点阵D2_1;else if(F==0)D2_0;E_0;}////////////////////////////////////////////////////////////////////////////////////////void LCD_CGRAM_Addr(u8 addr)//{E_0;LCD_RB();RS_0;RW_0;D6_1;E_1;E_0;}//////////////////////////////////////////////////////////////////////////////void LCD_DDRAM_Addr(u8 addr)//{E_0;LCD_RB();RS_0;RW_0;GPIO_Write(GPIOD,0x0000);//清空地址GPIO_Write(GPIOD,addr);E_1;E_0;}//////////////////////////////////////////////////////////////////////////////////void LCD_RB(void)//{GPIO_InitTypeDef pp;RS_0;RW_1;pp.GPIO_Mode=GPIO_Mode_IN_FLOATING;pp.GPIO_Speed=GPIO_Speed_50MHz;pp.GPIO_Pin=GPIO_Pin_7;GPIO_Init(GPIOD,&pp);//将端⼝设为输⼊E_1;while(GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_7));//若忙信号存在,则⼀直循环,直⾄忙信号结束E_0;pp.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7; pp.GPIO_Mode=GPIO_Mode_Out_PP;pp.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOD,&pp);//将端⼝重新设为输出}//////////////////////////////////////////////////////////////////////////////////////////void LCD_Write(u8 data)//{LCD_RB();RS_1;RW_0;E_1;GPIO_Write(GPIOD,data);E_0;}////////////////////////////////////////////////////////////////////////////void LCD_Read(void)//{LCD_RB();RS_1;RW_1;E_1;E_0;}////////////////////////////////////////////////////////////////////////////void LCD_WriteStr(u8 *str,int length)//{int i=0;for(i=0;i<length;i++){if(i<=15){LCD_DDRAM_Addr(0x80+i);LCD_Write(str[i]);}else{LCD_DDRAM_Addr(0xc0+i-16);LCD_Write(str[i]);}}}main.c#include "lcd.h"#include "string.h"int main(){u8 strMCU[]=" **** YOU 1602! TEST TEST "; LCD_Init();LCD_Clear();LCD_SetInput(1,0);LCD_Display(1,0,0);LCD_Mode(1,1,0);LCD_WriteStr(strMCU,strlen(strMCU));。

LCD1602的简单显示程序

LCD1602的简单显示程序

/*========================================================= 1602液晶显示的实验例子-------------------------------------------------| DB4-----P0.4 | RW-------P2.1| DB5-----P0.5 | RS-------P2.2| DB6-----P0.6 | E--------P2.0| DB7-----P0.7 |---------------------------------------------------LCD1602的简简单显示=========================================================*/ #include#include#define LCM_RW P2_1 //定义引脚#define LCM_RS P2_2#define LCM_E P2_0#define LCM_Data P0#define Busy 0x80 //用于检测LCM状态字中的Busy标识/*------------------------------------------子函数声明------------------------------------------*/void Write_Data_LCM(unsigned char WDLCM);void Write_Command_LCM(unsigned char WCLCM,BuysC);void Read_Status_LCM(void);void LCM_Init(void);void Set_xy_LCM(unsigned char x, unsigned char y);void Display_List_Char(unsigned char x, unsigned char y, unsigned char *s);void main(void){LCM_Init(); //LCM初始化delay_nms(5);//延时片刻(可不要)while(1){Display_List_Char(0, 0, "");Display_List_Char(1, 0, "Robot-AT89S52");}}/*=====================================函数名:Read_Status_LCM()功能:忙检测函数======================================*/void Read_Status_LCM(void){unsigned char read=0;LCM_RW = 1;LCM_RS = 0;LCM_E = 1;LCM_Data = 0xff;do{read = LCM_Data;}while(read & Busy);LCM_E = 0;}/*------------------------------------------- 函数名:Write_Data_LCM ( )功能:对LCD 1602写数据--------------------------------------------*/ void Write_Data_LCM(unsigned char WDLCM){Read_Status_LCM(); //检测忙LCM_RS = 1;LCM_RW = 0;LCM_Data &= 0x0f;LCM_Data |= WDLCM&0xf0;LCM_E = 1; //若晶振速度太高可以在这后加小的延时LCM_E = 1; //延时LCM_E = 0;WDLCM = WDLCM<<4;LCM_Data &= 0x0f;LCM_Data |= WDLCM&0xf0;LCM_E = 1;LCM_E = 1; //延时LCM_E = 0;}/*-------------------------------------------函数名:Write_Command_ LCM ( )功能:对LCD 1602写指令--------------------------------------------*/void Write_Command_LCM(unsigned char WCLCM,BuysC) //BuysC为0时忽略忙检测{if (BuysC)Read_Status_LCM(); //根据需要检测忙LCM_RS = 0;LCM_RW = 0;LCM_Data &= 0x0f;LCM_Data |= WCLCM&0xf0;//传输高四位LCM_E = 1;LCM_E = 1;LCM_E = 0;WCLCM = WCLCM<<4; //传输低四位LCM_Data &= 0x0f;LCM_Data |= WCLCM&0xf0;LCM_E = 1;LCM_E = 1;LCM_E = 0;}/*-------------------------------------------函数名:LCM_Init()功能:对LCD 1602初始化--------------------------------------------*/void LCM_Init(void) //LCM初始化{LCM_Data = 0;Write_Command_LCM(0x28,0); //三次显示模式设置,不检测忙信号delay_nms(15);Write_Command_LCM(0x28,0);delay_nms(15);Write_Command_LCM(0x28,0);delay_nms(15);Write_Command_LCM(0x28,1); //显示模式设置,开始要求每次检测忙信号Write_Command_LCM(0x08,1); //关闭显示Write_Command_LCM(0x01,1); //显示清屏Write_Command_LCM(0x06,1); //显示光标移动设置Write_Command_LCM(0x0C,1); //显示开及光标设置}/*-------------------------------------------函数名:Set_xy_LCM ()功能:设定显示坐标位置--------------------------------------------*/void Set_xy_LCM(unsigned char x, unsigned char y){unsigned char address;if( x == 0 )address = 0x80+y;elseaddress = 0xc0+y;Write_Command_LCM(address,1);}/*-------------------------------------------函数名:Display_List_Char()功能:按指定位置显示一串字符--------------------------------------------*/void Display_List_Char(unsigned char x, unsigned char y, unsigned char *s){Set_xy_LCM(x,y);while(*s){LCM_Data = *s;Write_Data_LCM(*s);s++;}}datasheet搜索: 。

lcd1602液晶显示数字钟

lcd1602液晶显示数字钟

{
time[1]=0;//超过,分清零
time[0]++;//小时加1
if(time[0]>23)//是否超过23
{
time[0]=0; //小时清零
•}

}
时间计算
• void main(void)
•{

uchar i;


while(1)

{
• 计时
for(i=0;i<250;i++)//循环调用显示程序250次,实现1秒
display_code[]={0x3f,0x60,0x5b,0x4 f,0x66,0x5d,0x7d,0x07,0x7f,0x6f,0x 40}; • uchar time[4]={0,0,0,0}; //时间初 值全为0
• void delay(void);//延时0.5毫秒 •{
定时1秒
• uchar i;
• for(i=250;i>0;i--);
•}
• void display()
/*程序用于P0口接数码管的断码,P2接数码管的位码*/
•{

uchar i,k;

k=0x80;
//k初始化,指向第一位数码管

for(i=0;i<8;i++) //循环8次,i值为0~7

{

P2=0;
//关闭显示

P0=display_code[time[i]/10]; //输出十位数的断码


{

display();//调用动态显示,动态显示一次约4毫秒

}

LCD1602液晶秒表C51程序

LCD1602液晶秒表C51程序

LCD1602液晶秒表C51程序此程序是基于51hei单片机开发板上面写的,如需要移植到自己的电路上,修改相应的端口即可,开发板完整的电路图下载: 点这里(注意:只需要看1602部分即可,其他部分可以忽略)/*************************************************** *********************** @file main.c* @author xr* @date 2014年5月8日22:11:33 -- 2014年5月9日12:03:49* @version V1.2.3* @brief LCD1602液晶跑表单片机STC89C52RC MCU 晶振 11.0592MHZ************************************************* ***********************/#include ;/* 系统时钟 */#define SYS_XTAL (11059200UL/12)/* 定时器T0重载值 */unsigned char thr0, tlr0;unsigned char thr1, tlr1;/* 跑表计数 */unsigned char timer[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; //分别表示跑表的各个位上的数字bit flag10ms = 0;extern bit stopflag;//跑表走停标志位extern void InitalLCD1602();extern void LcdShowStr(unsigned char x, unsigned char y, unsigned char * str);extern void KeyDriver();extern void KeyScan();void DisplayTimer();void ConfigTimer0(unsigned int xms);void ConfigTimer1(unsigned int xms);/* 主函数main() */void main(void){ConfigTimer0(10); //定时10msConfigTimer1(1);InitalLCD1602();LcdShowStr(0, 0, &quot;stopwatch&quot;);LcdShowStr(2, 1, &quot;0000000.00s&quot;); //液晶初始化显示LcdShowStr(10, 0, &quot;stop!&quot;);while (1){KeyDriver();DisplayTimer();if ((flag10ms == 1) && (stopflag == 1)){flag10ms = 0;timer[0]++;if (timer[0] >; 9){timer[0] = 0;timer[1]++;if (timer[1] >; 9){timer[1] = 0;timer[2]++;if (timer[2] >; 9) {timer[2] = 0;timer[3]++;if (timer[3] >; 9) {timer[3] = 0;timer[4]++;if (timer[4] >; 9) {timer[4] = 0;timer[5]++;if (timer[5] >; 9) {timer[5] = 0;timer[6]++;if (timer[6] >; 9) {timer[6] = 0;timer[7]++;if (timer[7] >; 9){timer[7] = 0;timer[8]++;if (timer[8] >; 9){timer[8] = 0;}}}}}}}}}}}}/* 将跑表时间显示到液晶上 */ void DisplayTimer(){unsigned char str[20];/* 分解timer */str[0] = timer[8] + '0';str[1] = timer[7] + '0';str[2] = timer[6] + '0';str[3] = timer[5] + '0';str[4] = timer[4] + '0';str[5] = timer[3] + '0';str[6] = timer[2] + '0';str[7] = '.';str[8] = timer[1] + '0';str[9] = timer[0] + '0';str[10] = '\0';LcdShowStr(2, 1, str);}/* 定时器T0配置 */void ConfigTimer0(unsigned int xms) {unsigned long tmp;tmp = (SYS_XTAL * xms) / 1000;tmp = 65536-tmp + 18;thr0 = (unsigned char)(tmp >;>; 8) ; tlr0 = (unsigned char)tmp;TMOD &= 0xF0; //清零T0控制位TMOD |= 0x01; //定时器方式1TH0 = thr0;TL0 = tlr0;TR0 = 1; //开启timer0ET0 = 1; //开启T0中断EA = 1; //开启总中断}/* 配置定时器T1 */void ConfigTimer1(unsigned int xms) {unsigned long tmp;tmp = (SYS_XTAL * xms) / 1000;tmp = 65536 - tmp + 18;thr1 = (unsigned char)(tmp >;>; 8); tlr1 = (unsigned char)tmp;TMOD &= 0x0F;TMOD |= 0x10;TH1 = thr1;TL1 = tlr1;TR1 = 1;ET1 = 1;EA = 1;}/* 定时器T0中断服务 */void Timer0_ISP() interrupt 1{TH0 = thr0;TL0 = tlr0;flag10ms = 1; //定时10ms}/* 定时器T1中断服务 */void Timer1_ISP() interrupt 3{TH1 = thr1;TL1 = tlr1; //定时1msKeyScan();}/*************************************************** *********************** @file Lcd1602.c* @author xr* @date 2014年5月7日13:33:17* @version V1.2.3* @brief LCD1602液晶底层驱动************************************************* ***********************/#include ;//LCD1602_IOsbit LCD1602_RS = P1^0;sbit LCD1602_RW = P1^1;sbit LCD1602_EN = P1^5;#define LCD1602_DB P0/* 液晶忙碌等待 */void LCD1602Wait(){unsigned char sta;LCD1602_DB = 0xFF;//总线拉高,检测液晶状态字LCD1602_RS = 0;LCD1602_RW = 1;do{LCD1602_EN = 1;sta = LCD1602_DB;LCD1602_EN = 0;//避免液晶输出数据} while (sta & 0x80);//状态字最高位STA7 == 0空闲,1忙碌}/* 液晶写命令 */void LCD1602WriteCmd(unsigned char cmd){LCD1602Wait();LCD1602_RS = 0;LCD1602_RW = 0;LCD1602_EN = 0;LCD1602_DB = cmd;LCD1602_EN = 1;LCD1602_EN = 0;}/* 液晶写数据 */void LCD1602WriteData(unsigned char dat){LCD1602Wait();LCD1602_RS = 1;LCD1602_RW = 0;LCD1602_EN = 0;LCD1602_DB = dat;LCD1602_EN = 1;LCD1602_EN = 0;}/* 液晶初始化 */void InitalLCD1602(){LCD1602WriteCmd(0x38);LCD1602WriteCmd(0x0C);LCD1602WriteCmd(0x06);LCD1602WriteCmd(0x01);//清屏}/* 写数据到液晶上,字符串str,坐标(x, y),地址addr */void LcdShowStr(unsigned char x, unsigned char y, unsigned char * str){unsigned char addr;if (y == 0){addr = 0x00 + x;}else{addr = 0x40 + x;}LCD1602WriteCmd(addr | 0x80);while (*str != '\0'){LCD1602WriteData(*str++);}}/*************************************************** *********************** @file keyboard.c* @author xr* @date 2014年5月8日22:11:33 -- 2014年5月9日12:03:49* @version V1.2.3* @brief 按键驱动单片机STC89C52RC MCU 晶振11.0592MHZ************************************************* ***********************/#include ;/* 按键输出输入端口定义 */sbit KEY_IN1 = P2^4;sbit KEY_IN2 = P2^5;sbit KEY_IN3 = P2^6;sbit KEY_IN4 = P2^7;sbit KEY_OUT1 = P2^3;sbit KEY_OUT2 = P2^2;sbit KEY_OUT3 = P2^1;sbit KEY_OUT4 = P2^0;extern unsigned char timer[9]; //分别表示跑表的各个位上的数字/* 按键当前状态 */unsigned char volatile keySta[4][4] = {{1, 1, 1, 1},{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}};/* 按键对应标准PC键盘编码 */const unsigned char code keyCodeMap[4][4] = {{'1', '2', '3', 0x26}, /* 数字键 1, 2, 3 和向上键 */{'4', '5', '6', 0x25}, /* 数字键 4, 5, 6 和向左键 */{'7', '8', '9', 0x28}, /* 数字键 7, 8, 9 和向下键 */{'0', 0x1B, 0x0D, 0x27} /* 数字键 0 和向右键*/};bit stopflag = 0;//跑表走停标志位 0 停止,1运行void KeyAction(unsigned char keycode);void LcdShowStr(unsigned char x, unsigned char y, unsigned char * str);/* 按键驱动函数 */void KeyDriver(){/* 上一次按键的备份值 */static unsigned char keybackup[4][4] = {{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}};for (i = 0; i < 4; i++){for (j = 0; j < 4; j++){if (keySta[i][j] != keybackup[i][j]) //当前按键状态和上一次的按键状态不同{ //按键有动作if (keybackup[i][j] != 0) //上一次按键是弹起 {KeyAction(keyCodeMap[i][j]); //当前按键是想、按下}keybackup[i][j] = keySta[i][j]; //备份当前按键值}}}}/* 按键扫描函数 */void KeyScan(){static unsigned char keyout = 0;//按键行索引static unsigned char keybuf[4][4] = {{0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF},{0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF}};/* 按键消抖 */keybuf[keyout][0] = (keybuf[keyout][0] << 1) | KEY_IN1;keybuf[keyout][1] = (keybuf[keyout][1] << 1) | KEY_IN2;keybuf[keyout][2] = (keybuf[keyout][2] << 1) | KEY_IN3;keybuf[keyout][3] = (keybuf[keyout][3] << 1) | KEY_IN4;/* 更新按键的值 */for (i = 0; i < 4; i++){if ((keybuf[keyout][i] & 0x1F) == 0x1F){//五次检测按键的值都是1keySta[keyout][i] = 1;}else if ((keybuf[keyout][i] & 0x1F) == 0x00) {//五次检测的按键值都是0keySta[keyout][i] = 0;}}/* 按键行索引++ */keyout++;keyout &= 0x03;//到4归零/* 根据按键索引选择行按键进行扫描 */switch (keyout){case 0: KEY_OUT1 = 0; KEY_OUT4 = 1;//选择第一行按键case 1: KEY_OUT2 = 0; KEY_OUT1 = 1;case 2: KEY_OUT3 = 0; KEY_OUT2 = 1;case 3: KEY_OUT4 = 0; KEY_OUT3 = 1;default: break;}}/* 按键动作函数 */void KeyAction(unsigned char keycode){unsigned char i = 0;if (keycode == 0x1B) //ESC{/* 跑表复位 */stopflag = 0;for (i = 0; i < 9; i++){timer[i] = 0;}LcdShowStr(2, 1, &quot;0000000.00s&quot;); LcdShowStr(10, 0, &quot;reset!&quot;);}else if (keycode == 0x0D) //回车键跑表走停{if (stopflag == 0){stopflag = 1;LcdShowStr(10, 0, &quot;start!&quot;);}else{stopflag = 0;LcdShowStr(10, 0, &quot;stop! &quot;); //多写入一个空格}}}。

单片机电子密码锁LCD1602显示

单片机电子密码锁LCD1602显示

单片机电子密码锁其电路图连接如下:本人已经用硬件实验,程序可用。

正确~~本程序特点:装载后读者可以自改密码,然后需要再次载入程序时:可以把主程序aa=Sendstring(0xa0,1,table2,6);这一句去掉。

然后程序的电子锁密码就是你个人设置的密码。

程序代码为:#include<reg51.h>#include<string.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned int#define LCDIO P2#define delay4us() _nop_();_nop_();_nop_();_nop_();uchar buffer[6]={0};sbit sda=P3^7;sbit scl=P3^6;sbit beep=P3^5;bit flag=0,aa; //用户蹲渊义定时溢出标志位uchar DSY_BUFFER[16]=" ";uchar DSY_BUFFER1[16]=" ";uchar Userpassword[6]={0};sbit rs=P0^4;sbit rd=P0^3;sbit lcden=P0^2;sbit led=P3^0;uchar code table2[]="";uchar code table[]="Your Password...";void delayms(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void delay() //短延时,两个机器周期,做总线的延时用{;;}void write_com(uchar com){rs=0;rd=0;lcden=0;P2=com;delayms(3);lcden=1;delayms(3);lcden=0;}void write_date(uchar date){rs=1;rd=0;lcden=0;P2=date;delayms(3);lcden=1;delayms(3);lcden=0;}void Display_String(uchar *p,uchar com){ uchar i;write_com(com);for(i=0;i<16;i++){write_date(p[i]);}}void init_lcd(){lcden=0;write_com(0x38);write_com(0x0c);write_com(0x06);write_com(0x01);write_com(0x80);Display_String(table,0x80);Display_String("Lock OK! ",0xc0); }void start(){sda=1;scl=1;delay4us();sda=0;delay4us();scl=0;}void stop(){sda=0;scl=1;delay4us();sda=1;delay4us();scl=0;}void init() //初始化{sda=1;delay();scl=1;delay();}void ack(){sda=0;scl=1;scl=0;sda=1;}void noack(){sda=1;scl=1;delay4us();scl=0;sda=0;}uchar recbyte(){uchar i,rd;rd=0x00;sda=1;for(i=0;i<8;i++){scl=1;rd<<=1;rd|=sda;delay4us();scl=0;delay4us();}scl=0;delay4us();return rd;}uchar sendbyte(uchar wd) {uchar i;bit ack0;for(i=0;i<8;i++){sda=(bit)(wd&0x80);_nop_();_nop_();scl=1;delay4us();scl=0;wd<<=1;}sda=1;scl=1;delay4us();ack0=!sda;scl=0;delay4us();return ack0;}uchar Recstring(uchar slave,uchar subaddr,uchar *buffer,uchar n) {uchar i;start();if(!sendbyte(slave)) return 0;if(!sendbyte(subaddr)) return 0;start();if(!sendbyte(slave+1)) return 0;for(i=0;i<n-1;i++){buffer[i]=recbyte();ack();}buffer[n-1]=recbyte();noack();stop();return 1;}uchar Sendstring(uchar slave,uchar subaddr,uchar *buffer,uchar n) {uchar i;start();if(!sendbyte(slave)) return 0;if(!sendbyte(subaddr)) return 0;for(i=0;i<n;i++){if(!sendbyte(buffer[i])) return 0;}stop();return 1;}void clear_password( ){ uchar i;for(i=0;i<6;i++){Userpassword[i]=' ';}for(i=0;i<16;i++){DSY_BUFFER[i]=' ';}}uchar Keys_Scan(){uchar temp,keynum;P1=0x0F;delayms(5);temp=P1^0x0F;switch(temp){case 1:keynum=0;break;case 2:keynum=1;break;case 4:keynum=2;break;case 8:keynum=3;break;break;}P1=0xF0;delayms(5);temp=P1>>4^0x0F;switch(temp){case 1:keynum+=0;break;case 2:keynum+=4;break;case 4:keynum+=8;break;case 8:keynum+=12;break;break;}delayms(600);return keynum;}void main(){ uchar temp,i=0,j=0,k=0,n;uchar IS_valid_user;beep=1;init();init_lcd();delayms(5);aa=Sendstring(0xa0,1,table2,6);delayms(5);aa=Recstring(0xa0,1,buffer,6);delayms(10);P1=0x0f;while(1){if(P1!=0x0f){temp=Keys_Scan();switch(temp){case 0: case 1: case 2: case 3: case 4:case 5: case 6: case 7: case 8: case 9:if (i<=5) //密码限制在6位以内{Userpassword[i]=temp;DSY_BUFFER[i]='*';Display_String(DSY_BUFFER,0xc0);i++;}break;case 10: //按A键开锁for(k=0;k<6;k++){if(buffer[k]==(Userpassword[k]+48))flag=1;elseflag=0;}if (flag==1){ flag=0;i=0;led=0; //点亮LEDclear_password();Display_String("OPEN OK! ",0xc0);IS_valid_user = 1;j=0;}else{j++;led=1; //关闭LEDclear_password();Display_String("ERROR!Have try ",0xc0);write_com(0xcf);write_date(0x30+j);IS_valid_user=0;}i=0;break;case 11: //按B键上锁led=1;clear_password();Display_String(table,0x80);Display_String("Lock OK! ",0xc0);i=0;IS_valid_user=0;break;case 12: //按C键设置新密码//如果是合法用户则提示输入新密码if ( !IS_valid_user){i=0;Display_String("No rights ! ",0xc0); delayms(1000);Display_String("Your Password...",0x80); Display_String("Lock OK! ",0xc0); }else{i=0;Display_String("New Password: ",0x80);Display_String(" ",0xc0);}break;case 13: //按D键保存新密码if ( !IS_valid_user){ i=0;Display_String("No rights ! ",0xc0);delayms(1000);Display_String("Your Password...",0x80);Display_String("Lock OK! ",0xc0);}else{i = 0;init();delayms(5);for(k=0;k<6;k++){Userpassword[k]=Userpassword[k]+48;}aa=Sendstring(0xa0,1,Userpassword,6);delayms(5);aa=Recstring(0xa0,1,buffer,6);delayms(5);clear_password();Display_String(table,0x00);Display_String("Password Saved! ",0xc0);delayms(1000);Display_String("Do lock agian ? ",0xc0);}break;case 14: //按E键消除所有输入i=0;clear_password();Display_String(" ",0xc0);break;case 15: //清除一位if(i!=0)i--;for(n=0;n<i;n++){DSY_BUFFER1[n]='*';}Display_String(DSY_BUFFER1,0xc0);}P1=0x0f;}if(j==3){ Display_String("THIEFTHIEF",0xc0);j=0;beep=0;}} }。

51单片机LCD1602液晶显示程序

51单片机LCD1602液晶显示程序

LCD1602_E = 1; //写入时序
Lcd1602_Delay1ms(5);
LCD1602_E = 0;
}
#endif
/******************************************************************************
*
*函数名 * 函数功能
: 初始化 LCD 屏 :无 :无
*******************************************************************************
/
#ifndef
LCD1602_4PINS
void LcdInit()
//LCD 初始化子程序
{ LcdWriteCom(0x38); //开显示
//以下程序都是在 VC++6.0 上调试运行过的程序,没有错误,没有警告。 //单片机是 STC89C52RC,但是在所有的 51 52 单片机上都是通用的。51 只是一个学习的基础 平台,你懂得。 //程序在关键的位置添加了注释。 //用//11111111111111111 代表第一个程序。//2222222222222222222222222 代表第二个程序, 以此类推
for(a=1;a>0;a--); } }
//误差 0us
}
/******************************************************************************
*
*函数名 * 函数功能
: LcdWriteCom : 向 LCD 写入一个字节的命令
LCD1602_E = 0;

加个模块,实现IIC方式驱动LCD1602

加个模块,实现IIC方式驱动LCD1602

加个模块,实现IIC驱动LCD1602 PCF8574模块使实现IIC驱动LCD1602成为现实。

下图是PCF8574模块与1602的连接电路图:实物接法如下:想要使用PCF8574模块来实现IIC驱动LCD1602,首先非常必要弄清楚IIC的时序、PCF8574设备地址、四线控制LCD1602方法。

下面是两个重要的h文件。

通过修改这两个h文件中的部分代码(接线有所不同)即可移植到你的程序中去。

PCF8574.h程序:sbit scl=P1^6;sbit sda=P1^7;void delay()//{ ;; }void init()//IIC初始化{sda=1;delay();scl=1;delay();}void start() //IIC开始信号{sda=1;delay();sda=0;delay();}void stop() //IIC停止{sda=0;delay();scl=1;delay();sda=1;delay();}void respons() //IIC应答{uchar i;scl=1;delay();while((sda==1)&&(i<250))i++;}void write_byte(uchar date)//IIC写入数据{uchar i,temp;temp=date;for(i=0;i<8;i++){temp=temp<<1;scl=0;delay();sda=CY;delay();scl=1;delay();}scl=0;delay();sda=1;uchar read_byte()//IIC读取字节{uchar i,k;scl=0;delay();sda=1;delay();for(i=0;i<8;i++){scl=1;delay();k=(k<<1)|sda;scl=0;delay();}return k;}start();write_byte(0x7e); //8574设备地址(写)respons();write_byte(date1);respons();stop();}uchar read_add()//向IO读取数据{uchar date1;start();write_byte(0x71); //8574设备地址(读)respons();date1=read_byte();respons();stop();return date1;}PCF8574+LCD1602_4.h程序:uchar a,b;for(a=x;a>0;a--)for(b=200;b>0;b--);}void write_com(uchar com) //写命令函数{ uchar com1,com2;com1=com|0x0f;write_add(com1&0xfc);delay1(2);write_add(com1&0xf8);com2=com<<4;com2=com2|0x0f;write_add(com2&0xfc);delay1(2);write_add(com2&0xf8);}void write_date(uchar date) //写数据函数{date1=date|0x0f;write_add(date1&0xfd);delay1(2);write_add(date1&0xf9);date2=date<<4;date2=date2|0x0f;write_add(date2&0xfd);delay1(2);write_add(date2&0xf9);}void init_lcd() //初始化函数{write_com(0x33); //显示模式设置delayms(6);write_com(0x32); //显示模式设置delayms(6);write_com(0x28); //4位总线,双行显示,显示5×7的点阵字符delayms(6);write_com(0x01); //清屏write_com(0x06); //字符进入模式:屏幕不动,字符后移delayms(6);write_com(0x0c); //显示开,关光标//write_LCD_Command(0x0f); //显示开,开光标,光标闪烁delayms(6);}//显示字符串:第x行第y列显示什么内容void ShowString(unsigned char x,unsigned char y,unsigned char *str){//设置起始位置if(x == 1){write_com(0x80 | y-1);// |相当于加法}if(x == 2){write_com(0xc0 | y-1);}//输出字符串while(*str!='\0') {write_date(*str);str++;}}。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
}
# define LCD_DB PORTB
# define LCD_RS PORTA_PA0
# define LCD_RW PORTA_PA1
# define LCD_E PORTA_PA2
void LCD_init(void);//初始化函数
void LCD_write_command(uchar command);//写指令函数
3.void LCD_write_command(uchar dat):写指令
4.void LCD_write_data(uchar dat):写数据
5.void LCD_disp_char(uchar x,uchar y,uchar dat):显示字符
6.void main(void):主函数
#include <hidef.h> /* common defines and macros */
0x01清屏
0x0F开显示,显示光标,光标闪烁
0x08只开显示
0x0e开显示,显示光标,光标不闪烁
0x0c开显示,不显示光标
0x06地址加1,当写入数据的时候光标右移
0x02地址计数器AC=0;(此时地址为0x80)光标归原点,但是DDRAM中断内容不变
0x18光标和显示一起向左移动
(2)飞思卡尔单片机的功能及特点:MC9S12XS128是16位单片机,由16位中央处理单元(CPU12X)、128KB程序、Flash(P-lash)、8KB RAM、8KB数据Flash(D-lash)组成片内存储器。主要功能模块包括:内部存储器,内部PLL锁相环模块,2个异步串口通讯SCI,1个串行外设接口SPI MSCAN模块,1个8通道输入/输出比较定时器模块TIM,周期中断定时器模块PIT,16通道A/D转换模块ADC,1个8通道脉冲宽度调制模块PWM,输入/输出数字I/O口。
#include "derivative.h" /* derivative-specific definitions */
#include "MC9S12XS128.h"
unsigned char a=0;
unsigned char b=0;
unsigned char c=0;
unsigned char d=0;
以下具体阐述这三个管脚:
RS为寄存器选择,高电平选择数据寄存器,低电平选择指令寄存器。
R/W为读写选择,高电平进行读操作,低电平进行写操作。
E端为使能端,后面和时序联系在一起。
除此外,D0~D7分别为8位双向数据线。
操作时序:RS源自R/W操作说明00
写入指令码D0~D7
0
1
读取输出的D0~D7状态字
1
b.数据方向寄存器DDRA
DDRA寄存器配置引脚为输出口还是输入口,“0”,输入口;“1”,输出口。MCU复位后,DDRA值为0x00,引脚默认为输入口。例:DDRA=0xFF //配置PORTA口为输出
PORTB:PORTB为通用数字I/O口,共8个。其使用与PORTA基本一样。主要配置寄存器有:数据寄存器PORTB、数据方向寄存DDRB。上拉电阻控制寄存器PUCR和驱动控制寄存器RDR与PORTA、PORTB、PORTE、PORTK共用。
void PLL_Init(void) //PLLCLK=2*OSCCLK*(SYNR+1)/(REFDV+1)
{ //锁相环时钟=2*16*(2+1)/(1+1)=48MHz
REFDV=1; //总线时钟=48/2=24MHz
SYNR=2;
while(!(CRGFLG&0x08));
CLKSEL=0x80; //选定锁相环时钟
a.数据寄存器PORTB
b.数据方向寄存器DDRB
四、原理图:
器件说明:LCD1602(16管脚),2个排阻,4个10k电阻,一个1K电阻,飞思卡尔芯片(64管脚)
管脚连接:
VSS
GND
DB6
PB6
VCC
VCC
DB7
PB7
VEE
GND
A
VCC
RS
PA0
K
GND
RW
PA1
K1
PA4
E
PA2
K2
PA5
DB0
二、实验设备与器件
CodeWarrior软件,BDM仿真器,万用电路板,飞思卡尔单片机,LCD1602液晶显示器,
三、实验内容
内容:利用飞思卡尔单片机制作基于1602字符液晶显示器的显示系统
要求:用四个按键控制,按下第一个按键显示1,按下第二个按键显示2,以此类推。
(1)LCD1602液晶显示器的原理:1602共16个管脚,但是编程用到的主要管脚不过三个,分别为:RS(数据命令选择端),R/W(读写选择端),E(使能信号);以后编程便主要围绕这三个管脚展开进行初始化,写命令,写数据。
0
写入数据D0~D7
1
1
从D0~D7读取数据
注:关于E=H脉冲——开始时初始化E为0,然后置E为1,再清0.
读取状态字时,注意D7位,D7=1,禁止读写操作;D7=0,允许读写操作;
所以对控制器每次进行读写操作前,必须进行读写检测。(即后面的读忙子程序)
指令集:
LCD_1602初始化指令小结:
0x38设置16*2显示,5*7点阵,8位数据接口
PB0
K4
PA6
DB1
PB1
K4
PA7
DB2
PB2
DB3
PB3
DB4
PB4
DB5
PB5
五、流程图


六、程序设计
1.void PLL_Init(void):内部锁相环模块,单片机使用PLL功能能够获得更高的总线频率,这对于需要提高单片机运行速度的应用场合非常必要。
2.void LCD_init(void):初始化LCD1602液晶显示屏,
MS
基于1602字符型液晶显示器的显示系统
姓名:杨越
班级:电子11-1
学号:110400104
1、实习目的
(1)了解飞思卡尔单片机的基本原理,掌握其基本的工作流程。
(2)了解LCD1602的基本原理及用法。
(3)能够熟练使用CodeWarrior软件编写C语言程序,使用BDM仿真器下载程序。
(4)能够熟练焊接电路板。
本次设计中主要用到PORTA,PORTB端口:
PORTA:PORTA为通用I/O口,共8个,作为通用数字I/O口使用,未集成特殊功
能.主要配置寄存器有:数据寄存器PORTA、数据方向寄存DDRA、上拉电阻控制寄存器
PUCR和驱动控制寄存器RDR。
a.数据寄存器PORTA
通过写1/0使单片机对应引脚输出高低电平,或通过读取数据寄存器获得对应引脚的高低电平值。例:PORTA_PB0=1
相关文档
最新文档