29-51 微控制器-LCD1602 液晶显示器实验
一 主要涉及到的知识点:
1.1 LCD1602功能脚:
3 脚:VL,液晶显示偏压信号,用于调整 LCD1602的显示对比度,一般会外接电位器用以调
整偏压信号,注意此脚电压为 0 时可以得到最强的对比度。
4 脚:RS,数据/命令选择端,当此脚为高电平时,可以对 1602 进行数据字节的传输操作,
而为电平时,则是进行命令字节的传输操作。命令字节,即是用来对 LCD1602 的一些工作方式设
置的字节;数据字节,即使用以在 1602 上显示的字节。值得一提的是,LCD1602 的数据是 8 位
的。
5 脚:R/W,读写选择端。当此脚为高电平可对 LCD1602 进行读数据操作,反之进行写数据操
作。
6 脚:E,使能信号,其实是 LCD1602 的数据控制时钟信号,利用该信号的上升沿实现对
LCD1602 的数据传输。
7~14 脚:8 位并行数据口,而 51 单片机一组 IO 也是 8 位,使得对 LCD1602的数据读写大
为方便
1.2 LCD1602显示两行,显示地址如图:
1.3 LCD1602常用命令:
1.3.1 清屏命令:
0x01写入实现清屏;
1.3.2 模式设置指令:
I/D:0=写入新数据后光标左移; 1=写入新数据后光标右移;
S: 0=写入新数据后显示屏不移动 ; 1=写入新数据后显示屏整体右移 1 个;字符
1.3.3 显示开关控制指令:
D:0=显示功能关; 1=显示功能开;
C:0=无光标; 1=有光标;
B:0=光标闪烁; 1=光标不闪烁;
1.3.4 功能设定指令:
DL:0=数据总线为 4 位; 1=数据总线为 8 位;
N: 0=显示 1 行; 1=显示 2 行;
F: 0=5×7 点阵/每字符 ; 1=5×10 点阵/每字符;
1.4 LCD1602 使用:
首先根据这个时序图进行编程:
1.4.1 LCD1602写命令函数定义:
1.4.2 LCD1602读数据函数定义:
1.4.3 初始化LCD1602:
这里就是设置命令通过LCD1602常用命令进行设定;
1.4.4 LCD1602显示字符函数定义:
二 源代码:
2.1 代码文件详情:
2.2 main.c文件:
#include "public.h"
#include "lcd1602.h"
//主函数
int main()
{
lcd1602_init(); //初始化LCD1602
lcd1602_show_string(0,0,"hell0 world!");
lcd1602_show_string(0,1,"0123456789");
while(1)
{
}
return 0;
}
2.3 public.c文件:
#include "public.h"
//延时函数定义delay_10us,当time_num_us=1时,相当于10us.
void delay_10us(u16 time_num_us)
{
while(time_num_us--);
}
//延时函数定义delay_ms,当time_num_us=1时,相当于1ms.
void delay_ms(u16 time_num_us)
{
u8 i = 0;
u8 j = 0;
for(i = 0; i < time_num_us; i++)
for(j = 101; j > 0; j++);
}
2.4 public.h文件:
#ifndef _public_H
#define _public_H
#include "reg52.h"
//对系统默认的数据类型进行重定义
typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;
void delay_10us(u16 time_num_us);
void delay_ms(u16 time_num_us);
#endif
2.5 lcd1602.c文件:
#include "lcd1602.h"
//LCD1602写命令函数定义
void lcd1602_write_cmd(u8 cmd)
{
LCD1602_RS = 0; //选择命令
LCD1602_RW = 0; //选择写
LCD1602_EN = 0;
LCD1602_PORT = cmd; //准备命令
delay_ms(1);
LCD1602_EN = 1; //使能脚E先上升沿写入
delay_ms(1);
LCD1602_EN = 0; //使能脚E后负跳变完成写入
}
//LCD1602读数据函数定义
void lcd1602_read_data(u8 dat)
{
LCD1602_RS = 1; //选择命令
LCD1602_RW = 0; //选择写
LCD1602_EN = 0;
LCD1602_PORT = dat; //准备命令
delay_ms(1);
LCD1602_EN = 1; //使能脚E先上升沿写入
delay_ms(1);
LCD1602_EN = 0; //使能脚E后负跳变完成写入
}
//初始化LCD1602
void lcd1602_init(void)
{
lcd1602_write_cmd(0x06); //模式设置指令,写入数据后光标右移,显示屏不动
lcd1602_write_cmd(0x0c); //显示开关控制指令, 显示功能打开1,无光标0;光标闪烁0
lcd1602_write_cmd(0x38); //功能设定指令,数据总线为8位,显示2行,5*7点阵/字符
lcd1602_write_cmd(0x01); //清屏-
}
//LCD1602清屏函数定义
void lcd1602_clear(void)
{
lcd1602_write_cmd(0x01); //清屏
}
//LCD1602显示字符函数定义
void lcd1602_show_string(u8 x, u8 y, u8 *str)
{
u8 i = 0;
if(x>15||y>1)return;//行列参数不对则强制退出
if(y<1) //第一行显示
{
while(*str != '\0') //因为字符是\0结尾的,通过判断当*str==\0就退出循环
{
if(i<16-x) //i是显示长度数.如果超过第一行的显示范围,则进行第二行显示
{
lcd1602_write_cmd(0x80 + i + x);//第一行显示地址设置
}
else
{
lcd1602_write_cmd(0x80 + 0x40 + i + x - 16);//第二行显示地址设置
}
lcd1602_read_data(*str);//写入数据显示;
str++;
i++;
}
}
else //第二行显示
{
while(*str != '\0') //因为字符是\0结尾的,通过判断当*str==\0就退出循环
{
if(i<16-x) //i是显示长度数.如果超过第二行的显示范围,则进行第二行显示
{
lcd1602_write_cmd(0x80 + 0x40 + i + x );//第二行显示地址设置
}
else
{
lcd1602_write_cmd(0x80 + i + x - 16);//第一行显示地址设置
}
lcd1602_read_data(*str);//写入数据显示;
str++;
i++;
}
}
}
2.6 lcd1602.h文件:
#ifndef _lcd1602_H
#define _lcd1602_H
#include "public.h"
sbit LCD1602_EN = P2^7;
sbit LCD1602_RS= P2^6;
sbit LCD1602_RW = P2^5;
//通过宏定义P0端口
#define LCD1602_PORT P0
void lcd1602_init(void);
void lcd1602_clear(void);
void lcd1602_show_string(u8 x, u8 y, u8 *str);
#endif
上一篇: 莱迪思 FPGA 开发】钻石的使用