LCD1602 单片机驱动程序深度解析

更新:11-07 民间故事 我要投稿 纠错 投诉

今天给各位分享LCD1602 单片机驱动程序深度解析的知识,其中也会对进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

一、LCD1602简介

LCD1602液晶显示器是一种广泛使用的字符液晶显示模块。它由字符型液晶显示器(LCD)、主控和驱动电路HD44780及其扩展驱动电路HD44100以及组装在PCB板上的少量电阻、电容和结构件组成。

LCD1602应用广泛。在各大电子公司的产品中,在各大高校的比赛中都可以看到它的身影。下面我们就来说说如何驱动这个1602液晶屏。

二、LCD1602引脚

在此插入图片说明图1:引脚说明

此处插入图片描述图2:原理图

1、我们重点关注的几个引脚:

LCD偏置电压:VL对应原理图中的V0引脚。其功能是调节1602的显示对比度,可外接电位器调节对比度。上图原理图中接地引脚的对比度在电压为0时为0。数据/命令选择端:RS对应原理图中的RES引脚。引脚高电平:数据字节进行传输。引脚低电平:命令字节进行传输。读/写选择端:R/W对应原理图中的R/W引脚。引脚高电平:1602 为读数据。 引脚低电平:1602 为写数据。一般应用为直接拉低只进行写数据。 使能信号:E对应E引脚。示意图。该密码是上升沿代表对1602开始数据传输,下降沿代表数据传输结束。背光控制:原理图中的K+引脚,引脚高电平:背光关闭,引脚低电平:背光打开。2.我们只需向1602显示器写入数据,只看写入操作时序:

对比2写命令和4写数据,可以看到RW读写引脚为低电平,E为高电平,D0~D7为传输的数据是命令/数据,RS数据/命令选择端(高:数据 , 低:命令)。【图片上传失败.(image-8031e7-1639217075281)】

此处插入图片描述3.常用的书写指令如下。其他说明可以查看1602数据表:

[图片上传失败.(image-dd35b6-1639217075281)]

4、向CGRAM写入数据指令:

此指令可以自定义显示一个字符,我们写地址的丝毫应该是0x40+Address[图片上传失败.(image-729705-1639217075281)]

三、LCD1602驱动(11脚)

51单片机的驱动与STM32单片机基本相同主要是引脚的配置不怎么一样,特别注意STM32驱动写指令/数据GPIO_Write(GPIOA,(GPIO_ReadOutputData(GPIOA) 0xff00) | cmd/data)为对电平的读取再写数据,其他均与51驱动一致。

1、51单片机:LCD1602.h

#ifndef __LCD1602_H

#定义__LCD1602_H

#define LCD1602_BKL_ON 0 //背光打开

#define LCD1602_BKL_OFF 1 //背光关闭

#define LCD1602_DB P2 //数据端口D0~D7

位LCD_RES=P4^1; //1602数据/命令选择控制线

位LCD_EN=P4^2; //1602使能控制线

sbit Lcd1602_light=P0^2; //背光引脚

/**************************************************** * ******************************/

无效LCD1602_Init();

无效LCD1602_Clear();

无效LCD1602_write_cmd(无符号字符cmd);

无效LCD1602_write_data(无符号字符日期);

无效LCD1602_wtire_CGRAM();

无效LCD1602_SetCursor(无符号字符x,无符号字符y);

无效LCD1602_ShowChar(无符号字符xpos,无符号字符ypos,无符号字符xsz);

无效LCD1602_ShowStr(无符号char xpos,无符号char ypos,char *p);

void LCD1602_ShowNum(char x, char y, unsigned int num);

无效LCD1602_BKLSet(无符号字符值);

无符号字符LCD1602_BKLGet();

void Delay_ms(无符号整数nms);

#endif

2、51单片机:LCD1602.c

#include "LCD1602.h"

/**************************************************** * **********************************

* 函数名称:void Delay_ms(unsigned int nms) *

*功能功能:写命令功能*

* 输入参数: //nms为要延迟的ms数*

* 返回值: 无*

* 其他说明: *

****************************************************** * **************************/

void Delay_ms(unsigned int nms) //@11.0592MHz

{

无符号字符i, j; //使用单片机小工具根据自己的单片机类型和晶振直接生成对应的延时函数。

同时(nms--)

{

我=15;

j=90;

{

同时(--j);

而(--i);

}

}

/**************************************************** * **********************************

* 函数名称:void LCD1602_write_cmd(unsigned char cmd) *

*功能功能:写命令功能*

* 输入参数: cmd命令*

* 返回值: 无*

* 其他说明: *

****************************************************** * **************************/

无效LCD1602_write_cmd(无符号字符cmd)

{

LCD1602_DB=cmd;

LCD_RES=0;

LCD_EN=1;

延迟_毫秒(10);

LCD_EN=0;

}

/**************************************************** * **********************************

* 函数名称:void LCD1602_write_data(unsigned char date) *

*功能函数:写数据函数*

* 输入参数:日期数据*

* 返回值: 无*

* 其他说明: *

****************************************************** * **************************/

无效LCD1602_write_data(无符号字符日期)

{

LCD1602_DB=日期;

LCD_RES=1;

LCD_EN=1;

延迟_毫秒(10);

LCD_EN=0;

}

/**************************************************** * **********************************

* 函数名称:void LCD1602_Init(void) *

* 函数功能:1602初始化函数*

* 输入参数: 无*

* 返回值: 无*

* 其他说明: *

****************************************************** * **************************/

无效LCD1602_Init()

{

LCD1602_BKLSet(LCD1602_BKL_ON); //背光打开

LCD1602_write_cmd(0x01); //显示清屏

LCD1602_write_cmd(0x38); //显示模式设置

LCD1602_write_cmd(0x0C); //显示和光标设置

LCD1602_write_cmd(0x06); //显示光标移动位置

}

/**************************************************** * **********************************

* 函数名称:void LCD1602_Clear(void) *

*功能功能:1602清屏功能*

* 输入参数: 无*

* 返回值: 无*

* 其他说明: *

****************************************************** * **************************/

无效LCD1602_Clear()

{

LCD1602_write_cmd(0x01);

}

/**************************************************** * **********************************

* 函数名称:void LCD1602_BKLSet(unsigned char val) *

*功能功能:开启1602背光功能*

* 输入参数: LCD1602_BKL_ON 打开LCD1602_BKL_OFF 关闭*

* 返回值: 无*

* 其他说明: *

****************************************************** * **************************/

无效LCD1602_BKLSet(无符号字符值)

{

LCD1602_light=val;

}

/**************************************************** * **********************************

* 函数名称:unsigned char LCD1602_BKLGet() *

*功能函数:获取1602背光功能*

* 输入参数: 无*

* 返回值: 0 开1 关*

* 其他说明: *

****************************************************** * **************************/

无符号字符LCD1602_BKLGet()

{

返回Lcd1602_light;

}

/**************************************************** * **********************************

* 函数名称:void LCD1602_SetCursor(unsigned char x, unsigned char y) *

*功能功能:组1602位置功能*

* 输入参数:x 横坐标y 纵坐标*

* 返回值: 无*

* 其他说明: *

****************************************************** * **************************/

无效LCD1602_SetCursor(无符号字符x,无符号字符y)

{

无符号字符地址;

如果(y==0)

地址=0x00+x;

别的

地址=0x40+x;

LCD1602_write_cmd(地址|0x80);

}

/**************************************************** * **********************************

* 函数名称:void LCD1602_ShowNum(char x, char y, unsigned int num) *

*功能:指定显示数字功能的位置*

* 输入参数:x 横坐标y 纵坐标num 编号*

* 返回值: 无*

* 其他说明: *

****************************************************** * **************************/

void LCD1602_ShowNum(char x, char y, unsigned int num)

{

无符号整型i,j,k,l,n;

我=数字/10000;

j=(num-10000*i)/1000;

k=(num-10000*i-1000*j)/100;

l=(num-10000*i-1000*j-100*k)/10;

n=num%10;

LCD1602_SetCursor(x,y);

if(i!=0)LCD1602_write_data(i+0x30);

if((i!=0)||(j!=0))LCD1602_write_data(j+0x30);

if((i!=0)||(j!=0)||(k!=0))LCD1602_write_data(k+0x30);

if((i!=0)||(j!=0)||(k!=0)||(l!=0))LCD1602_write_data(l+0x30);

LCD1602_write_data(n+0x30);

}

/**************************************************** * **********************************

* 函数名称:void LCD1602_ShowChar(unsigned char xpos, unsigned char ypos, char xsz) *

* 功能: 在指定位置显示字符功能*

* 输入参数:xpos 横坐标ypos 纵坐标xsz 字符*

* 返回值: 无*

* 其他说明: *

****************************************************** * **************************/

无效LCD1602_ShowChar(无符号字符xpos,无符号字符ypos,字符xsz)

{

ypos%=2;

if(ypos==0)

{

LCD1602_write_cmd(0x80+xpos);

}

别的

{

LCD1602_write_cmd(0x80+0x40+xpos);

}

LCD1602_write_data(xsz);

}

/**************************************************** * **********************************

* 函数名称:void LCD1602_ShowStr(unsigned char xpos, unsigned char ypos, char *p) *

* 函数:在指定位置显示字符串函数*

* 输入参数:xpos 横坐标ypos 纵坐标*p 字符串*

* 返回值: 无*

* 其他说明:

* ******************************************************************************/ void LCD1602_ShowStr(unsigned char xpos,unsigned char ypos,char *p) { if(ypos>1)return; while(*p!="") { LCD1602_ShowChar(xpos++,ypos,*p++); if(*p=="n") { xpos=0; ypos++; p++; } } } unsigned char code code_Y[8]={0x11,0x0A,0x04,0x04,0x04,0x04,0x04,0x00};//类似Y的字模 /****************************************************************************** * 函数名称:void LCD1602_wtire_CGRAM(void) * * 函数功能:自定义显示字符函数 * * 输入参数: 无 * * 返回值 : 无 * * 其他说明: * ******************************************************************************/ void LCD1602_wtire_CGRAM() { unsigned char num; LCD1602_write_cmd(0x40); //对CGRAM第一个自定义字符操作,若是第二个则为0x48, //其次类推(上面有对顶的关系) for(num=0;num<8;num++) { LCD1602_write_data(code_Y[num]); } LCD1602_write_cmd(0x80); //规定显示在第一行第一个位置 LCD1602_write_data(0x00); //显示第一个自定义字符 (0x40对应第一个:0x00) } /********************************************************************/

3、STM32:LCD1602.h

#ifndef __LCD1602_H #define __LCD1602_H /***************************根据自己的硬件引脚做修改*****************************/ #define LCD_RS_Set() GPIO_SetBits( GPIOB, GPIO_Pin_12 )//1602的数据/指令选择控制线 #define LCD_RS_Clr() GPIO_ResetBits( GPIOB, GPIO_Pin_12 ) #define LCD_RW_Set() GPIO_SetBits( GPIOB, GPIO_Pin_13 )//1602的读写控制线 #define LCD_RW_Clr() GPIO_ResetBits( GPIOB, GPIO_Pin_13 ) #define LCD_EN_Set() GPIO_SetBits( GPIOB, GPIO_Pin_14 )//1602的使能控制线 #define LCD_EN_Clr() GPIO_ResetBits( GPIOB, GPIO_Pin_14 ) #define DATAOUT( x ) GPIO_Write( GPIOA, x ) //1602的8条数据控制线 void GPIO_Configuration(); void LCD1602_Init(); void LCD1602_Wait_Ready(); void LCD1602_Write_Cmd( u8 cmd ); void LCD1602_Write_Dat( u8 data ); void LCD1602_ClearScreen(); void LCD1602_Set_Cursor( u8 x, u8 y ); void LCD1602_Show_Str( u8 x, u8 y, u8 *str ); #endif

4、STM32:LCD1602.c

#include "LCD1602.h" /****************************************************************************** * 函数名称:void GPIO_Configuration() * * 函数功能:LCD1602引脚初始化 *

* 输入参数:无 * * 返回值 :无 * * 其他说明: * ******************************************************************************/ /*******************根据自己的硬件引脚做修改*****************************************/ void GPIO_Configuration() { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE ); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//选择工作频率 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//设置工作模式 GPIO_Init( GPIOB, &GPIO_InitStructure ); GPIO_InitStructure.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_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//设置工作模式 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//选择工作频率 GPIO_Init( GPIOA, &GPIO_InitStructure ); } /****************************************************************************** * 函数名称:void LCD1602_Init() * * 函数功能:LCD1602初始化 * * 输入参数:无 * * 返回值 :无 * * 其他说明: * ******************************************************************************/ void LCD1602_Init() { GPIO_Configuration(); //初始化引脚 LCD1602_Write_Cmd( 0x38 ); //显示模式设置 delay_ms( 5 ); LCD1602_Write_Cmd( 0x0c ); //显示开及光标设置 delay_ms( 5 ); LCD1602_Write_Cmd( 0x06 ); //显示光标移动位置 delay_ms( 5 ); LCD1602_Write_Cmd( 0x01 ); //显示清屏 delay_ms( 5 ); } /****************************************************************************** * 函数名称:void LCD1602_Write_Cmd(u8 cmd) * * 函数功能:写命令函数 * * 输入参数: cmd 命令 * * 返回值 :无 * * 其他说明: * ******************************************************************************/ void LCD1602_Write_Cmd( u8 cmd ) { LCD_RS_Clr(); LCD_RW_Clr(); LCD_EN_Set(); GPIO_Write( GPIOA, (GPIO_ReadOutputData( GPIOA ) & 0xff00) | cmd );//对电平的读取 DATAOUT( cmd ); delay_ms( 5 ); LCD_EN_Clr(); } /****************************************************************************** * 函数名称:void LCD1602_Write_Dat(u8 date) * * 函数功能:写数据函数 * * 输入参数: date 数据 * * 返回值 :无 * * 其他说明: * ******************************************************************************/ void LCD1602_Write_Dat( u8 data ) { LCD_RS_Set(); LCD_RW_Clr(); LCD_EN_Set(); GPIO_Write( GPIOA, (GPIO_ReadOutputData( GPIOA ) & 0xff00) | data );//对电平的读取 delay_ms( 5 ); LCD_EN_Clr(); } /****************************************************************************** * 函数名称:void LCD1602_ClearScreen() * * 函数功能:1602清屏函数 * * 输入参数:无 * * 返回值 :无 * * 其他说明: * ******************************************************************************/ void LCD1602_ClearScreen() { LCD1602_Write_Cmd( 0x01 ); } /****************************************************************************** * 函数名称:void LCD1602_Set_Cursor(u8 x, u8 y) * * 函数功能:设置1602位置函数 * * 输入参数:x 横坐标 y 纵坐标 * * 返回值 :无 * * 其他说明: * ******************************************************************************/ void LCD1602_Set_Cursor( u8 x, u8 y ) { u8 addr; if ( y == 0 ) addr = 0x00 + x; else addr = 0x40 + x; LCD1602_Write_Cmd( addr | 0x80 ); } /****************************************************************************** * 函数名称:void LCD1602_Show_Str( u8 x, u8 y, u8 *str ) * * 函数功能:指定位置显示字符串函数 * * 输入参数:x 横坐标 y 纵坐标 *str 字符串 * * 返回值 : 无 * * 其他说明: * ******************************************************************************/ void LCD1602_Show_Str( u8 x, u8 y, u8 *str ) { LCD1602_Set_Cursor( x, y ); while ( *str != "" ) { LCD1602_Write_Dat( *str++ ); } }

四、LCD1602 STM32驱动(6线)

LCD1602 的接口形式是并行的,它有 8 条数据线、3 条控制线。这样就需要 11 条线来控制它的正常工作。虽然它还可以工作在 4 位数据线的形式,最精简的形式是 6 条线。 我们可以用74HC595 进行串-并转换,74HC595 是“串入并出”的移位寄存器芯片,它需要用 3 条线控制数据的输入,才能正常的输出 8 位数据,总共6条线即可进行LCD1602的控制。 这里多用了一块芯片但是省了5个IO口,对于某些项目单片机引脚不够用的情况下可以应用上。 在这里插入图片描述 在这里插入图片描述

1、STM32:LCD1602.h

#ifndef __LCD1602_H #define __LCD1602_H //1602液晶指令/数据或选择引脚 #define LCD_RS_PORT GPIOB #define LCD_RS_PIN GPIO_Pin_10 #define LCD_RS_0 GPIO_ResetBits(LCD_RS_PORT, LCD_RS_PIN) #define LCD_RS_1 GPIO_SetBits(LCD_RS_PORT, LCD_RS_PIN) //1602液晶使能引脚 #define LCD_EN_PORT GPIOB #define LCD_EN_PIN GPIO_Pin_11 //PB11 #define LCD_EN_0 GPIO_ResetBits(LCD_EN_PORT, LCD_EN_PIN) #define LCD_EN_1 GPIO_SetBits(LCD_EN_PORT, LCD_EN_PIN) //1602液晶数据端口 #define MOSIO PBout(0) #define R_CLK PCout(5) #define S_CLK PCout(4) /*********************函数声明*****************/ void LCD1602_Init(void); void LCD1602_Clear(void); void LCD1602_ShowStr(unsigned char xpos,unsigned char ypos,char *p); void LCD1602_BKLSet(unsigned char on); unsigned char LCD1602_BKLGet(void); void LCD1602_ShowLineStr(unsigned char xpos,unsigned char ypos,char *p); void LCD1602_ShowState(unsigned char Signal, unsigned char GprsState); /**********************************************/ #endif

2、STM32:LCD1602.c

#include "LCD1602.h" #include "delay.h"//程序中的延时函数根据自己32单片机来就行 void hc595SendData(unsigned char sendVal) { unsigned char i; //从CPU中向595一位一位发送,595一位一位接收 for(i = 0; i< 8; i++) { if((sendVal<< i) & 0x80) MOSIO = 1; else MOSIO = 0; S_CLK = 0; S_CLK = 1; } //CPU发送完后,R_CLK将数据并行输出, //实现了只占用CPU一个输出口就可以输出8bit数据 R_CLK = 0; R_CLK = 1; } void LCD1602_write_com(unsigned char com) { hc595SendData(com); LCD_RS_0; LCD_EN_0; delay_ms(10); LCD_EN_1; } void LCD1602_write_data(unsigned char date) { hc595SendData(date); LCD_RS_1; LCD_EN_0; delay_ms(10); LCD_EN_1; } void LCD1602_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC, ENABLE ); GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Pin = LCD_RS_PIN | LCD_EN_PIN | GPIO_Pin_0; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5; GPIO_Init(GPIOC, &GPIO_InitStructure); LCD1602_write_com(0x01); LCD1602_write_com(0x38); LCD1602_write_com(0x0C);//开显示,不需要光标 LCD1602_write_com(0x06); } void LCD1602_Clear(void) { LCD1602_write_com(0x01); } void LCD1602_ShowChar(unsigned char xpos,unsigned char ypos,char xsz) { ypos%=2; if(ypos==0) { LCD1602_write_com(0x80+xpos); } else { LCD1602_write_com(0x80+0x40+xpos); } LCD1602_write_data(xsz); } void LCD1602_ShowLineStr(unsigned char xpos,unsigned char ypos,char *p) { unsigned char i=0; if(ypos>1 || xpos>=16)return; while(*p!="" && i<16 && xpos<16) { i++; LCD1602_ShowChar(xpos++,ypos,*p++); delay_us(500); } } void LCD1602_ShowStr(unsigned char xpos,unsigned char ypos,char *p) { if(ypos>1)return; while(*p!="") { LCD1602_ShowChar(xpos++,ypos,*p++); if(*p=="n")//当检测到换行符时,进行换行检测 { xpos=0; ypos++; p++; } }

用户评论

长裙绿衣

我想学习使用单片机控制LCD显示器!

    有7位网友表示赞同!

不离我

这篇文章是不是讲解了如何编写代码驱动LCD1602?

    有18位网友表示赞同!

漫长の人生

之前用PIC控制过LCD,想了解STC51和STM32的实现方式比较。

    有20位网友表示赞同!

素颜倾城

我的课题里有这个需求,剛好!

    有17位网友表示赞同!

ok绷遮不住我颓废的伤あ

希望能解释一下不同平台(STC51/STM32)中数据传输的方式,以及对应的代码差异。

    有11位网友表示赞同!

别悲哀

我已经学会了基本的单片机编程,想进一步深入学习驱动外部设备的知识。

    有15位网友表示赞同!

此生一诺

LCD这种显示器还是挺重要的,掌握驱动它感觉很实用!

    有18位网友表示赞同!

烬陌袅

我之前遇到过关于LCD数据接口的问题,希望这篇文章能给我一些帮助。

    有16位网友表示赞同!

凉话刺骨

平时做嵌入式项目都会用到类似的模块,期待这篇文章详细讲解驱动程序的设计思路。

    有13位网友表示赞同!

呆檬

STC51和STM32都是常用的单片机型号,对比一下他们的区别很有意义。

    有5位网友表示赞同!

闲肆

了解了LCD1602的接口规范后,就可以灵活使用它来实现各种功能了吗?

    有17位网友表示赞同!

作业是老师的私生子

这篇文章是不是包含具体的代码实例?我很想实践一下。

    有8位网友表示赞同!

隔壁阿不都

LCD驱动程序需要考虑哪些因素才能写得高效可靠呢?

    有16位网友表示赞同!

哭花了素颜

如果想扩展LCD1602的功能,比如连接背光源,应该怎么做?

    有8位网友表示赞同!

雪花ミ飞舞

我想学习关于单片机和外部设备之间通信协议的知识。

    有20位网友表示赞同!

情如薄纱

这篇文章能够帮助我理解使用单片机控制电子显示器的基本原理吗?

    有6位网友表示赞同!

关于道别

想通过学习LCD1602驱动程序来提高我的嵌入式开发能力!

    有19位网友表示赞同!

安好如初

对于硬件电路连接部分,这篇文章也会提供一些说明吗?

    有6位网友表示赞同!

【LCD1602 单片机驱动程序深度解析】相关文章:

1.蛤蟆讨媳妇【哈尼族民间故事】

2.米颠拜石

3.王羲之临池学书

4.清代敢于创新的“浓墨宰相”——刘墉

5.“巧取豪夺”的由来--米芾逸事

6.荒唐洁癖 惜砚如身(米芾逸事)

7.拜石为兄--米芾逸事

8.郑板桥轶事十则

9.王献之被公主抢亲后的悲惨人生

10.史上真实张三丰:在棺材中竟神奇复活

上一篇:深入解析:卷积核在图像处理中的关键角色 下一篇:阿里云提供免费云服务器服务,新用户可免费试用一个月ECS