51单片机学习笔记_12 LCD1602 原理及其模块化代码

文章介绍了LCD1602液晶显示屏的基本特性,包括显示模式和内部结构,并详细阐述了初始化过程、显示指令以及模块化编程的方法。提供了LCD1602的C语言函数实现,包括设置光标、显示字符、数字和十六进制数等。此外,还提到了屏幕滚动的实现方式。
摘要由CSDN通过智能技术生成

LCD1602

liquid crystal display 液晶显示屏,一种字符型液晶显示模块,可以显示 16*2 个字符,每个字符是 5*7 点阵。

image-20230203004049189

P0 P2 会和数码管、LED 一定程度上冲突。

  1. 地。

  2. Vcc。

  3. 调对比度的。

  4. RS:数据指令端。1代表 DB 是数据,0代表是指令。

  5. RW:1读0写。

  6. E:类似时钟的使能。高电平有效,下降沿执行。

  7. DB:并行输入。一个字节长。

  8. BG:背光灯电源。

内部结构图

image-20230221024102411

类似 SMG,想显示1并不是直接输入1,而是操纵数码管右侧一竖被点亮。字模库起的就是这个作用,里面有固定的 ROM 和用户课自定义的 RAM。

DDRAM 长于屏幕,可以通过移平实现滚动效果。

AC address controller,可以自动移位写入数据。

字模库中的数据大多数和 ASCII 码是一样的。

指令

image-20230221195404983

image-20230221195434495

image-20230221195450094

image-20230221200656434

image-20230221200839017

image-20230221201026593

image-20230221201247867

image-20230221201355749

image-20230222162315672

image-20230221205604331

初始化指令

初始化要做哪些操作?

规定显示区域(如8位数据接口,2行显示,5*7点阵,即为0011 10xx,如果取0即为 0x38.)。

显示的模式设置(如开启显示,关闭光标,关闭光标闪烁:0000 1101,即 0x0D)。

进入模式设置(如读写后光标++,屏幕不动:0000 0110,0x06。如果是滚动屏幕则为)。

清屏(0x01)。

显示指令

先设置 DDRAM 初始地址,0x80|AC(开头的8是 DDRAM 固定指令信息不能改。后面的全是0,与 AC 光标位置做与,AC 不同位置的值见 DDRAM 地址表).

然后发送数据。

时序

image-20230221210035721 image-20230221210102393 image-20230221210614193

模块化

第一阶段我们先编写 LCD1602 模块化编程代码,这一部分主要显示静态内容,用于程序编写过程中显示变量进行调试。

目标模块化函数:

image-20230203004415880
//LCD1602.h
#ifndef __LCD1602_H__
#define __LCD1602_H__

#include "reg52.h"
#include "intrins.h"
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_E=P2^7;
#define LCD_DATAPORT P0

void LCD_Delay1ms();		//@11.0592MHz
void LCD_WriteCommand(unsigned char Command);
void LCD_WriteData(unsigned char Data);
void LCD_Init();
void LCD_SetCursor(unsigned char line, unsigned char column);
unsigned int LCD_Pow(unsigned char x, unsigned char y);
void LCD_ShowChar(unsigned char line, unsigned char column, unsigned char c);
void LCD_ShowString(unsigned char line, unsigned char column, unsigned char str[]);
void LCD_ShowNum(unsigned char line, unsigned char column, unsigned int num, unsigned char length);
void LCD_ShowSignedNum(unsigned char line, unsigned char column, int num, unsigned char length);
void LCD_ShowHexNum(unsigned char line, unsigned char column, unsigned int num, unsigned char length);
void LCD_ShowBinNum(unsigned char line, unsigned char column, unsigned int num, unsigned char length);
#endif
//LCD1602.c
#include "LCD1602.H"

void LCD_Delay1ms()		//@11.0592MHz
{
	unsigned char i, j;

	_nop_();
	_nop_();
	_nop_();
	i = 11;
	j = 190;
	do
	{
		while (--j);
	} while (--i);
}

void LCD_WriteCommand(unsigned char Command){
	LCD_RS=0;
	LCD_RW=0;
	LCD_E=0;
	LCD_DATAPORT=Command;
	LCD_Delay1ms();
	LCD_E=1;
	LCD_Delay1ms();
	LCD_E=0;
}

void LCD_WriteData(unsigned char Data){
	LCD_RS=1;
	LCD_RW=0;
	LCD_E=0;
	LCD_DATAPORT=Data;
	LCD_Delay1ms();
	LCD_E=1;
	LCD_Delay1ms();
	LCD_E=0;
}

void LCD_Init(){
	LCD_WriteCommand(0x38);
	LCD_WriteCommand(0x0C);
	LCD_WriteCommand(0x06);
	LCD_WriteCommand(0x01);
}

void LCD_SetCursor(unsigned char line, unsigned char column){
	if(line==1){
		LCD_WriteCommand(0x80|(column-1));
	}
	else{
		LCD_WriteCommand(0x80|(column-1)+0x40);
	}
}

unsigned int LCD_Pow(unsigned char x, unsigned char y){
	unsigned char i=y;
	unsigned int res=1;
	for(;i>0;i--)res*=x;
	return res;
}

void LCD_ShowChar(unsigned char line, unsigned char column, unsigned char c){
	LCD_SetCursor(line, column);
	LCD_WriteData(c);
}

void LCD_ShowString(unsigned char line, unsigned char column, unsigned char str[]){
	unsigned int i=0;
	LCD_SetCursor(line, column);
	while(str[i]!='\0'){
		LCD_WriteData(str[i]);
		i++;
	}
}

void LCD_ShowNum(unsigned char line, unsigned char column, unsigned int num, unsigned char length){
	unsigned char i;
	unsigned base;
	LCD_SetCursor(line, column);
	for(i=length;i>0;i--){
		base=LCD_Pow(10, i-1);
		LCD_WriteData(num/base%10+'0');	
	}
}

void LCD_ShowBinNum(unsigned char line, unsigned char column, unsigned int num, unsigned char length){
	unsigned char i;
	unsigned char base;
	unsigned char single_num;
	LCD_SetCursor(line, column);
	for(i=length;i>0;i--){
		base=LCD_Pow(2, i-1);
		single_num=num/base%2+'0';
		LCD_WriteData(single_num);	
	}
}

void LCD_ShowHexNum(unsigned char line, unsigned char column, unsigned int num, unsigned char length){
	unsigned char i;
	unsigned char base;
	unsigned char single_num;
	LCD_SetCursor(line, column);
	for(i=length;i>0;i--){
		base=LCD_Pow(16, i-1);
		single_num=num/base%16;
		if(single_num<=9)single_num+='0';
		else single_num+='A'-10;
		LCD_WriteData(single_num);	
	}
}

void LCD_ShowSignedNum(unsigned char line, unsigned char column, int num, unsigned char length){
	unsigned char i;
	unsigned base;
	LCD_SetCursor(line, column);
	if(num>0)LCD_WriteData('+');
	else {LCD_WriteData('-');num=-num;}
	for(i=length;i>0;i--){
		base=LCD_Pow(10, i-1);
		LCD_WriteData(num/base%10+'0');	
	}
}

如果希望屏幕滚动,一定时间执行一次LCD_WriteCommand(0x18); 屏幕左移指令。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

灰海宽松

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值