当前位置: 首页 > news >正文

C51单片机学习笔记——LCD1602调试

在学习完数码管显示后发现具有局限性只能显示0—9的数字,而1602显示屏可以字符,数字等就具有灵活性,可以更直观的显示出想显示的东西。

一、LCD1602模块

1602液晶显示屏(LCD 1602)是一种常见的字符型液晶显示模块。

1. 硬件结构

1602显示屏的核心由以下部分组成:

  • 液晶面板:由16×2个字符单元组成,每个单元由5×8或5×11点阵构成。

  • 控制器芯片:通常采用 HD44780 或其兼容芯片,负责控制显示内容和通信。

  • 背光:可选LED背光,提高显示对比度。

  • 接口引脚:16个引脚(部分型号可能简化),包括电源、控制信号和数据总线。

2. 工作原理

(1) 控制芯片(HD44780)
  • 内部寄存器

    • 指令寄存器(IR):存储控制指令(如清屏、光标移动等)。

    • 数据寄存器(DR):存储待显示的字符数据。

  • 显示数据RAM(DDRAM):存储屏幕上实际显示的字符码,容量为80字节(足够2行×40字符,但1602仅显示前16字符)。

  • 字符生成ROM(CGROM):内置标准ASCII字符(5×8点阵)的字模库。

  • 自定义字符RAM(CGRAM):允许用户定义8个5×8点阵的自定义字符。

(2) 通信方式
  • 并行接口:通过8位(或4位)数据总线传输数据。

  • 控制信号

    • RS(Register Select)

      • RS=0:选择指令寄存器(发送命令)。

      • RS=1:选择数据寄存器(发送显示内容)。

    • RW(Read/Write)

      • RW=0:写入模式(常用)。

      • RW=1:读取模式(较少使用)。

    • E(Enable):使能信号,高电平到低电平的跳变触发芯片执行操作。

(3) 操作时序
  • 写操作流程

    1. 设置 RS 和 RW 电平。

    2. 将数据/指令放到数据总线(DB0-DB7)。

    3. 拉高 E 信号并保持至少450ns。

    4. 拉低 E 信号,完成写入。

3. 显示流程

  • 初始化

    • 发送指令设置显示模式(如4位/8位总线、显示行数、字体大小)。

    • 开启显示、清屏、设置光标移动方向等。

  • 写入数据

    • 通过 RS=1 发送字符的ASCII码到数据寄存器。

    • 字符码被存入DDRAM,并自动显示在屏幕上。

  • 地址控制

    • 第一行地址范围:0x00-0x0F(实际DDRAM地址为0x80-0x8F)。

    • 第二行地址范围:0x40-0x4F(实际DDRAM地址为0xC0-0xCF)。

4. 关键指令

常用指令(通过 RS=0 发送):

  • 0x01:清屏。

  • 0x0C:开启显示,关闭光标。

  • 0x80:设置DDRAM地址到第一行开头。

  • 0xC0:设置DDRAM地址到第二行开头。

5. 对比度与背光

  • 对比度调节:通过 V0 引脚连接电位器(典型值:10kΩ),调整电压(0-5V)控制显示清晰度。

  • 背光控制:引脚15(A)和16(K)连接LED背光,需串联限流电阻(通常220Ω)。

二、1602模块头文件和源文件代码

#ifndef __LCD1602_H__
#define __LCD1602_H__

//用户调用函数:
void LCD_Init();
void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char);
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String);
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length);
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);

#endif
#include <REGX52.H>

//引脚配置:
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_EN=P2^7;
#define LCD_DataPort P0

//函数定义:
/**
  * @brief  LCD1602延时函数,12MHz调用可延时1ms
  * @param  无
  * @retval 无
  */
void LCD_Delay()
{
	unsigned char i, j;

	i = 2;
	j = 239;
	do
	{
		while (--j);
	} while (--i);
}

/**
  * @brief  LCD1602写命令
  * @param  Command 要写入的命令
  * @retval 无
  */
void LCD_WriteCommand(unsigned char Command)
{
	LCD_RS=0;
	LCD_RW=0;
	LCD_DataPort=Command;
	LCD_EN=1;
	LCD_Delay();
	LCD_EN=0;
	LCD_Delay();
}

/**
  * @brief  LCD1602写数据
  * @param  Data 要写入的数据
  * @retval 无
  */
void LCD_WriteData(unsigned char Data)
{
	LCD_RS=1;
	LCD_RW=0;
	LCD_DataPort=Data;
	LCD_EN=1;
	LCD_Delay();
	LCD_EN=0;
	LCD_Delay();
}

/**
  * @brief  LCD1602设置光标位置
  * @param  Line 行位置,范围:1~2
  * @param  Column 列位置,范围:1~16
  * @retval 无
  */
void LCD_SetCursor(unsigned char Line,unsigned char Column)
{
	if(Line==1)
	{
		LCD_WriteCommand(0x80|(Column-1));
	}
	else if(Line==2)
	{
		LCD_WriteCommand(0x80|(Column-1+0x40));
	}
}

/**
  * @brief  LCD1602初始化函数
  * @param  无
  * @retval 无
  */
void LCD_Init()
{
	LCD_WriteCommand(0x38);//八位数据接口,两行显示,5*7点阵
	LCD_WriteCommand(0x0c);//显示开,光标关,闪烁关
	LCD_WriteCommand(0x06);//数据读写操作后,光标自动加一,画面不动
	LCD_WriteCommand(0x01);//光标复位,清屏
}

/**
  * @brief  在LCD1602指定位置上显示一个字符
  * @param  Line 行位置,范围:1~2
  * @param  Column 列位置,范围:1~16
  * @param  Char 要显示的字符
  * @retval 无
  */
void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char)
{
	LCD_SetCursor(Line,Column);
	LCD_WriteData(Char);
}

/**
  * @brief  在LCD1602指定位置开始显示所给字符串
  * @param  Line 起始行位置,范围:1~2
  * @param  Column 起始列位置,范围:1~16
  * @param  String 要显示的字符串
  * @retval 无
  */
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String)
{
	unsigned char i;
	LCD_SetCursor(Line,Column);
	for(i=0;String[i]!='\0';i++)
	{
		LCD_WriteData(String[i]);
	}
}

/**
  * @brief  返回值=X的Y次方
  */
int LCD_Pow(int X,int Y)
{
	unsigned char i;
	int Result=1;
	for(i=0;i<Y;i++)
	{
		Result*=X;
	}
	return Result;
}

/**
  * @brief  在LCD1602指定位置开始显示所给数字
  * @param  Line 起始行位置,范围:1~2
  * @param  Column 起始列位置,范围:1~16
  * @param  Number 要显示的数字,范围:0~65535
  * @param  Length 要显示数字的长度,范围:1~5
  * @retval 无
  */
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
	unsigned char i;
	LCD_SetCursor(Line,Column);
	for(i=Length;i>0;i--)
	{
		LCD_WriteData(Number/LCD_Pow(10,i-1)%10+'0');
	}
}

/**
  * @brief  在LCD1602指定位置开始以有符号十进制显示所给数字
  * @param  Line 起始行位置,范围:1~2
  * @param  Column 起始列位置,范围:1~16
  * @param  Number 要显示的数字,范围:-32768~32767
  * @param  Length 要显示数字的长度,范围:1~5
  * @retval 无
  */
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length)
{
	unsigned char i;
	unsigned int Number1;
	LCD_SetCursor(Line,Column);
	if(Number>=0)
	{
		LCD_WriteData('+');
		Number1=Number;
	}
	else
	{
		LCD_WriteData('-');
		Number1=-Number;
	}
	for(i=Length;i>0;i--)
	{
		LCD_WriteData(Number1/LCD_Pow(10,i-1)%10+'0');
	}
}

/**
  * @brief  在LCD1602指定位置开始以十六进制显示所给数字
  * @param  Line 起始行位置,范围:1~2
  * @param  Column 起始列位置,范围:1~16
  * @param  Number 要显示的数字,范围:0~0xFFFF
  * @param  Length 要显示数字的长度,范围:1~4
  * @retval 无
  */
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
	unsigned char i,SingleNumber;
	LCD_SetCursor(Line,Column);
	for(i=Length;i>0;i--)
	{
		SingleNumber=Number/LCD_Pow(16,i-1)%16;
		if(SingleNumber<10)
		{
			LCD_WriteData(SingleNumber+'0');
		}
		else
		{
			LCD_WriteData(SingleNumber-10+'A');
		}
	}
}

/**
  * @brief  在LCD1602指定位置开始以二进制显示所给数字
  * @param  Line 起始行位置,范围:1~2
  * @param  Column 起始列位置,范围:1~16
  * @param  Number 要显示的数字,范围:0~1111 1111 1111 1111
  * @param  Length 要显示数字的长度,范围:1~16
  * @retval 无
  */
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
	unsigned char i;
	LCD_SetCursor(Line,Column);
	for(i=Length;i>0;i--)
	{
		LCD_WriteData(Number/LCD_Pow(2,i-1)%2+'0');
	}
}

三、1602调试

例如:我们显示一个字符串

代码如下:

#include <REGX52.H>
#include "LCD1602.h"

void main()
{	
	LCD_Init();//初始化
	LCD_ShowString(1,1,"HelloWorld");//显示字符串“HelloWorld”
	while(1)
	{
		//
	}
}

 

LED1602就显示了HelloWorld。 

 

 

 

相关文章:

  • SEO长尾关键词优化策略
  • 语法: value=kbhit( );和 value=kbhit( stream );
  • 10天速通强化学习-009--DDPG、SAC、TD3
  • 闭包和装饰器
  • 工业自动化领域边缘计算机崛起:PLC 替代之势渐显
  • 基于spring boot 鲜花销售系统PPT(源码+lw+部署文档+讲解),源码可白嫖!
  • 微软主要收入云计算,OFFICE,操作系统和游戏10大分类
  • 【项目管理】第2章 信息技术发展 --知识点整理
  • AutowiredAnnotationBeanPostProcessor
  • AIDD-人工智能药物设计-双扩散模型结合多目标优化策略助力3D小分子药物设计
  • 产品经理课程
  • Go语言常用算法实现
  • c++进阶--c++11
  • 更详细的广度优先搜索合集
  • LLM-大语言模型浅谈
  • 【Python使用】嘿马python数据分析教程第3篇:全渠道业务概述,目的,获取数据,连带率【附代码文档】
  • 浔川代码编辑器v1.1.0(测试版)使用教程
  • Python学习之numpy
  • JSX、支持HTML标签、Ref的使用、虚拟DOM的使用
  • 设计模式 Day 3:抽象工厂模式(Abstract Factory Pattern)详解
  • hb网页设计软件/关键词优化工具有哪些
  • 一个服务器可以备案几个网站吗/郑州百度关键词seo
  • 济南想建设网站/seo是广告投放吗
  • 溧阳网站制作/十大最靠谱教育培训机构
  • 福田专业网站建设公司哪家好/国内新闻摘抄
  • 广州开发网站技术/网络营销实训个人总结