① LCD1602单片机(STC51/STM32)驱动程序详解
LCD1602是广泛使用的字符型液晶显示模块,主要由字符型液晶显示屏、控制驱动主电路HD44780及其扩展驱动电路HD44100,以及电阻、电容元件和结构件等装配在PCB板上构成。
在电子产品的设计与开发中,LCD1602因其易用性和低成本而被广泛应用。本文将详细介绍如何驱动LCD1602单片机(包括STC51和STM32)。
LCD1602拥有特定的引脚配置。重点关注的引脚包括:读写引脚RW、使能引脚E、数据/命令选择端RS、以及数据线D0~D7。在写操作时序中,RW需保持低电平,E为高电平,D0~D7为要传输的数据,RS则用于区分数据和命令。
常用的写指令有多种,详细指令可在1602的datasheet中查询。特别注意写入CGRAM指令时,地址设置为0x40+Address。
驱动LCD1602时,51单片机和STM32单片机的操作大体一致,但需注意引脚配置差异。51单片机和STM32单片机的驱动代码大致如下:LCD1602.h和LCD1602.c。
在STM32驱动中,考虑到引脚资源的限制,可以采用并行或串行接口形式。并行接口需要11条线来控制LCD1602,而并行接口可以精简为6条线。为实现此精简接口,可以使用74HC595芯片进行串并转换,通过3条线控制数据输入,实现8位数据输出。
具体实现中,需要设计原理图和对应的STM32驱动代码:LCD1602.h和LCD1602.c。
如需获得更多内容或技术支持,请关注公众号【加班猿】并点赞关注。
② LCD1602怎么实现连续的滚动
步骤:
1.显示一行字符;
2.延时0.5秒
3.把上一行字符内容向左/向右移动一个位置;
4.显示一行字符(移动内容以后的);
5.延时0.5秒;重复3-5 次就可以了。
注:写指令38H(不检测忙信号)
延时5mS
写指令38H(不检测忙信号)
以后每次写指令、读/写数据操作均需要检测忙信号
写指令38H:显示模式设置
写指令08H:显示关闭
写指令01H:显示清屏
写指令06H:显示光标移动设置
写指令0CH:显示开及光标设置
没有滚动的指令
一次移动一个字符,把显示缓冲区的内容向左移动,移动到最左边时,从新开始
③ LCD1602用C语言编程如何显示字符
void delay(uint z);//延时,1微妙时间有点短
你看看下面我做的程序,在2051+12M晶振通过你可以套用这个程序,不行的话就改长延时
/******************AT89S51使用12M晶振*******************/
//LCD脚接法,根据实际接法定义
#define LCM_D4_RS P3_2//第4脚数据/命令
#define LCM_D5_RW P3_5//第5脚读/写
#define LCM_D6_E P3_7//第6脚使能
#define LCM_D16_BLK P3_0//背光负极
#define LCM_D7_Data P1//第7-14脚数据
//LCD脚接法,根据实际接法定义
#define Busy 0x80 //用于检测LCM状态字中的Busy标识
#define _LCD_BIT_IS 4 //CPU与LCD1602间使用DB7-DB4这4根数据线进行传输
#include <at89x51.h> //头文件
#include <string.h> //strlen()函数头文件
void LCMInit(void); //LCM初始化化
void WriteDataLCM(unsigned char WDLCM); //写数据
void WriteCommandLCM(unsigned char WCLCM,int BuysC); //写指令
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData); //按指定位置显示一个字符
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData);//按指定位置显示一串字符
void Delay5Ms(void); //5ms延时
unsigned char ReadStatusLCM(void); //读状态
unsigned char code Greetings_Line1[] = {"Welcome Control"};
unsigned char code Greetings_Line2[] = {" ChuLong Make "};
data unsigned char cou = 0; // 定义软计数器,放在程序最前面的寄存器定义部分
void main(void)
{
LCMInit(); //LCM初始化
LCM_D16_BLK = 0; //开背光灯
TMOD = 0x11; // 定时/计数器0,1工作于方式1 16位定时
TH0 = 0x3c; // 预置产生50ms时基信号
TL0 = 0xb0;
EA = 1; // 开总中断
ET0 = 1; // 定时/计数器0允许中断
TR0 = 1; // 开定时/计数器0
DisplayListChar(0, 0, Greetings_Line1);
DisplayListChar(0, 1, Greetings_Line2);
// while(1);
}
//
void LCMInit(void) //LCM初始化
{
WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号
Delay5Ms();
WriteCommandLCM(0x38,0);
Delay5Ms();
WriteCommandLCM(0x38,0);
#if(_LCD_BIT_IS == 8) //CPU与LCD1602间使用DB0-DB8这8根数据线进行传输
WriteCommandLCM(0x38,1); //显示8位模式设置,开始要求每次检测忙信号
#else //CPU与LCD1602间使用DB0-DB4这4根数据线进行传输
WriteCommandLCM(0x28,1); //显示4位模式设置,开始要求每次检测忙信号
#endif
WriteCommandLCM(0x08,1); //关闭显示
WriteCommandLCM(0x01,1); //显示清屏
WriteCommandLCM(0x06,1); // 显示光标移动设置
WriteCommandLCM(0x0C,1); // 显示开及光标设置
}
//写数据
void WriteDataLCM(unsigned char WDLCM)
{
ReadStatusLCM(); //检测忙
LCM_D4_RS = 1;
LCM_D5_RW = 0;
#if(_LCD_BIT_IS == 8) //CPU与LCD1602间使用DB0-DB8这8根数据线进行传输
{
LCM_D7_Data = WDLCM;
}
#else //CPU与LCD1602间使用DB0-DB4这4根数据线进行传输
{
LCM_D7_Data &= 0x0f; //清高四位
LCM_D7_Data |= WDLCM & 0xf0; //写高四位
LCM_D6_E = 0;
LCM_D6_E = 1;
WDLCM = WDLCM << 4; //低四位移到高四位
LCM_D7_Data &= 0x0f; //清高四位
LCM_D7_Data |= WDLCM & 0xf0; //写低四位
}
#endif
LCM_D6_E = 0;
LCM_D6_E = 1;
}
//写指令
void WriteCommandLCM(unsigned char WCLCM,int BuysC) //BuysC为0时忽略忙检测
{
if(BuysC)
ReadStatusLCM(); //根据需要检测忙
LCM_D4_RS = 0;
LCM_D5_RW = 0;
#if(_LCD_BIT_IS == 8) //CPU与LCD1602间使用DB7-DB4这4根数据线进行传输
{
LCM_D7_Data = WCLCM;
}
#else
{
LCM_D7_Data &= 0x0f; //清高四位
LCM_D7_Data |= WCLCM & 0xf0; //写高四位
LCM_D6_E = 0;
LCM_D6_E = 1;
WCLCM = WCLCM << 4; //低四位移到高四位
LCM_D7_Data &= 0x0f; //清高四位
LCM_D7_Data |= WCLCM & 0xf0; //写低四位
}
#endif
LCM_D6_E = 0;
LCM_D6_E = 1;
}
//读状态
unsigned char ReadStatusLCM(void)
{
LCM_D7_Data = 0xff;
LCM_D4_RS = 0;
LCM_D5_RW = 1;
LCM_D6_E = 1;
while (LCM_D7_Data & Busy); //检测忙信号
return(LCM_D7_Data);
}
//按指定位置显示一个字符
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
{
Y &= 0x1;
X &= 0xF; //限制X不能大于15,Y不能大于1
if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;
X |= 0x80; //算出指令码
WriteCommandLCM(X, 0); //这里不检测忙信号,发送地址码
WriteDataLCM(DData);
}
//按指定位置显示一串字符
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)
{
int ListLength;
Y &= 0x1;
X &= 0xF; //限制X不能大于15,Y不能大于1
for(ListLength = 0;ListLength < strlen(DData);ListLength++) //若到达字串尾则退出
{
if (X <= 0xF) //X坐标应小于0xF
{
DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符
X++;
}
}
}
//5ms延时
void Delay5Ms(void)
{
unsigned int TempCyc = 5552;
while(TempCyc--);
}
//10s延时
void tiem0(void) interrupt 1
{ // T/C0中断服务程序(产生50ms时基信号)
if(cou < 60)
{ // 计数值到1000(1s) (****时间为倒计时****)
cou = 0; // 软计数器清零
}
cou++; // 软计数器加1
TH0 = 0x3c; // 重置定时常数
TL0 = 0xb0;
}
④ keil中编译显示不能打开lcd1602.h,我尝试添加头文件,但不知道源代码的目录怎么打开
只要这个1602的.h和.c文件都正确有效,那么将这个1602的.h和.c文件放到你的这个工程文件夹里,而后只要主程序中有#include"lcd1602.h"这样的包含头文件声明,就能正确使用了。如下图是用keil uv2建立的一个DS3231的时钟工程,图片中相关文件都能正常打开的:
⑤ 求助51单片机 显示器1602的输出代码
在使用51单片机与1602液晶显示器进行通信时,可以参考以下代码来实现基本功能。代码中定义了LCD1602的引脚,并提供了一些关键的函数,如初始化、发送命令和数据等。
为了使1602液晶显示器正常工作,需要先进行初始化。初始化函数`lcd1602_init()`通过发送一系列的初始化命令来配置LCD的模式、显示模式等参数。初始化过程如下:
1. 通过`lcd1602_write(0,0x38);`发送8位数据模式的指令,使LCD进入8位数据通信模式。
2. 通过`lcd1602_write(0,0x38);`再次发送8位数据模式的指令,重复一次是为了确保LCD能够稳定进入8位通信模式。
3. 通过`lcd1602_write(0,0x0C);`发送显示控制指令,使LCD显示开启,但不显示光标。
4. 通过`lcd1602_write(0,0x01);`发送清除屏幕指令,清空LCD上的显示内容。
初始化完成后,可以通过`lcd1602_display_str`函数在指定位置显示字符串。该函数接受三个参数:列位置、行位置(0或1)和要显示的字符串。函数内部首先根据行位置调整光标位置,然后逐字符发送到LCD。
此外,还可以使用`lcd1602_display_byte`函数单独显示单个字符。这个函数同样需要指定位置和字符。
以上代码中,`delay_1ms`函数用于生成必要的延时。根据实际应用需求,可能需要调整延时函数的具体实现。
示例代码展示了如何使用这些函数在第一列第二行显示字符串“Hello,World”。实际应用中,可以将字符串存储在`table`数组中,然后通过`lcd1602_init()`初始化LCD,最后调用`lcd1602_display_str(0,1,table);`来显示。
需要注意的是,1602液晶显示器一行最多可以显示16个字符,且不支持中文显示。因此,在设计显示内容时,应确保字符数量符合这一限制。
如果使用的是STC89C52单片机,可以参考提供的`delay_1ms`函数实现。该函数通过嵌套循环生成1毫秒的延时,具体延迟时间可以根据实际需求调整。
⑥ LCD1602操作控制
在操作LCD1602模块时,初始化过程至关重要。开始时,应将控制信号E设置为0,然后将其置为1,以触发相应的脉冲操作。E信号的控制是模块通信的关键步骤。
LCD1602内部的字符发生存储器(CGROM)内置了160种不同点阵字符,包括阿拉伯数字、大小写英文字母、常用符号以及日文假名。每个字符都有其独特的代码,例如大写'A'的代码是0x41(1000001B),通过读取地址41H中的字符图形,我们就能在屏幕上看到'A'这个字符。
由于1602模块采用ASCII码进行识别,可以直接使用ASCII码值进行赋值。在单片机编程中,可以使用字符型常量或变量来表示字符,比如用'A'代表ASCII码0x41。
在查看或读取字符时,需要遵循特定的地址顺序:先读取左列,再读取上行。例如,感叹号'!'的ASCII码为0x21,字母'B'的ASCII码则为0x42,注意前面的'0x'表示这是十六进制格式。