STC89C52单片机学习——第32节: [14-2]LCD1602功能函数代码

写这个文章是用来学习的,记录一下我的学习过程。希望我能一直坚持下去,我只是一个小白,只是想好好学习,我知道这会很难,但我还是想去做!

本文写于:2025.03.30

51单片机学习——第32节: [14-2]LCD1602功能函数代码

前言

   本次笔记是用来记录我的学习过程,同时把我需要的困难和思考记下来,有助于我的学习,同时也作为一种习惯,可以督促我学习,是一个激励自己的过程,让我们开始51单片机的学习之路。
   欢迎大家给我提意见,能给我的嵌入式之旅提供方向和路线,现在作为小白,我就先学习51单片机了,就跟着B站上的江协科技开始学习了.
   在这里会记录下江协科技51单片机开发板的配套视频教程所作的实验和学习笔记内容,因为我之前有一个开发板,我大概率会用我的板子模仿着来做.让我们一起加油!
   另外为了增强我的学习效果:每次笔记把我不知道或者问题在后面提出来,再下一篇开头作为解答!

开发板说明

   本人采用的是慧净的开发板,因为这个板子是我N年前就买的板子,索性就拿来用了。不再另外购买视频中的普中开发板了。
   原理图如下
在这里插入图片描述
视频中的都用这个开发板来实现,如果有资源就利用起来。
仔细看了看:开发板的晶振为:11.0592Mhz;12Mhz晶振是用来给CH340G芯片外置晶振;

下图是实物图
在这里插入图片描述

引用

51单片机入门教程-2020版 程序全程纯手打 从零开始入门
还参考了下图中的书籍:
手把手教你学51单片机(C语言版)
在这里插入图片描述
STC89C52手册
在这里插入图片描述

解答和科普

一、LCD1602代码编写

在这里插入图片描述
引脚定义:

sbit  LCD_RS=P1^0;
sbit  LCD_RW=P1^1;
sbit  LCD_EN=P2^5;
#define  LCD_DataPort  P0

在这里插入图片描述
在这里插入图片描述
私有化延迟函数

void LCD_Delay()		//@11.0592MHz 1ms移植后修改
{
	unsigned char i, j;

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

写命令

void  LCD_WriterCommand(unsigned char Command)
{
	LCD_RS=0;
	LCD_RW=0;
	
	LCD_DataPort=Command;
	LCD_EN=1;	//注意时序,
	LCD_Delay();
	
	LCD_EN=0;
	LCD_Delay();
}

写数据

void  LCD_WriterData(unsigned char Data)
{
	
	LCD_RS=1;
	LCD_RW=0;
	
	LCD_DataPort=Data;
	LCD_EN=1;	//注意时序,
	LCD_Delay();
	
	LCD_EN=0;
	LCD_Delay();

}


在这里插入图片描述
初始化

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

在这里插入图片描述
对行和列进行运算转换为实际的地址:

void LCD_ShowChar(unsigned char Line,unsigned char Column,unsigned char Char)
{
	if(Line==1)
	{
		LCD_WriterCommand(0x80|(Column-1));
	}
	
	if(Line==2)
	{
		LCD_WriterCommand(0x80|(Column-1)+0x40);
	}
	
	LCD_WriterData(Char);
}

现象

在这里插入图片描述
在这里插入图片描述
字符串

void LCD_ShowString(unsigned char Line,unsigned char Column,unsigned char *String)
{
	unsigned char i;
	if(Line==1)
	{
		LCD_WriterCommand(0x80|(Column-1));
	}
	
	if(Line==2)
	{
		LCD_WriterCommand(0x80|(Column-1)+0x40);
	}
	
	for(i=0;String[i]!='\0';i++)
	{
		LCD_WriterData(String[i]);
		
	}
	
}

测试字符串
在这里插入图片描述
显示无符号的数字

int LCD_Pow(int X,int Y)
{
	unsigned char i;
	int Result=1;
	for(i=0;i<Y;i++)
	{
		Result*=X;
	}
	return Result;

}

void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
	unsigned char i;
	LCD_SetCursor(Line,Column);		//789 抽取转化为字符		789/100%10=7  789/10%10=8  789/1%10=9
	for(i=Length;i>0;i--)
	{
		LCD_WriterData('0'+Number/LCD_Pow(10,i-1)%10);	//	转换asc码
		
	}
}

在这里插入图片描述

显示有符号的数字

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_WriterData('+');
		Number1=Number;
	}
	else
	{
		LCD_WriterData('-');
		Number1=-Number;
	}
	
	for(i=Length;i>0;i--)
	{
		LCD_WriterData('0'+Number1/LCD_Pow(10,i-1)%10);	//	转换asc码
		
	}

}

在这里插入图片描述
十六进制显示数字

void LCD_ShowHexNum(unsigned char Line, unsigned char Column,unsigned int Number,unsigned char Length)
{
	unsigned char i;
	unsigned char SingNumber;
	LCD_SetCursor(Line,Column);	
	
	for(i=Length;i>0;i--)
	{
		SingNumber=Number/LCD_Pow(16,i-1)%16;
		if(SingNumber<10)
		{
		LCD_WriterData('0'+SingNumber);
		}
		else
		{
		LCD_WriterData('A'+SingNumber-10);
		}
	}
}

在这里插入图片描述
显示二进制数

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_WriterData('0'+Number/LCD_Pow(2,i-1)%2);	//	转换asc码
		
	}
}

在这里插入图片描述显示特殊字符
在这里插入图片描述

	LCD_ShowChar(2,13,0xDF);

流动字幕
要产生流动字幕的效果:写一个超出屏幕范围,但是没有超出DDRM范围的一个东西,162,DDRM是402,

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

void main()
{

	LCD_Init();
	Nixie_OFF();
	DianZhengGuan();
	LCD_ShowChar(1,1,'A');			//不是标准的码表
	LCD_ShowString(1,3,"HELLO");
	LCD_ShowNum(1,9,66,2);
	LCD_ShowSignedNum(1,12,-66,2);
	LCD_ShowHexNum(2,1,0xAB,2);
	LCD_ShowBinNum(2,4,0xA5,8);
	LCD_ShowChar(2,13,0xDF);
	LCD_ShowChar(2,14,'C');
	LCD_ShowString(1,16,"Welcome to AI");
	
	
	while(1)
	{
		LCD_WriterCommand(0x18);
		Delay(500);
	}
}

2、LCD1602.C

#include <REGX52.H>

sbit  LCD_RS=P1^0;
sbit  LCD_RW=P1^1;
sbit  LCD_EN=P2^5;
#define  LCD_DataPort  P0


void LCD_Delay()		//@11.0592MHz 1ms移植后修改
{
	unsigned char i, j;

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




void  LCD_WriterCommand(unsigned char Command)
{
	LCD_RS=0;
	LCD_RW=0;
	
	LCD_DataPort=Command;
	LCD_EN=1;	//注意时序,
	LCD_Delay();
	
	LCD_EN=0;
	LCD_Delay();
}



void  LCD_WriterData(unsigned char Data)
{
	
	LCD_RS=1;
	LCD_RW=0;
	
	LCD_DataPort=Data;
	LCD_EN=1;	//注意时序,
	LCD_Delay();
	
	LCD_EN=0;
	LCD_Delay();

}

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

void LCD_SetCursor(unsigned char Line,unsigned char Column)
{
	if(Line==1)
	{
		LCD_WriterCommand(0x80|(Column-1));
	}
	
	if(Line==2)
	{
		LCD_WriterCommand(0x80|(Column-1)+0x40);
	}
}


void LCD_ShowChar(unsigned char Line,unsigned char Column,unsigned char Char)
{
	LCD_SetCursor(Line,Column);
	
	LCD_WriterData(Char);
}

void LCD_ShowString(unsigned char Line,unsigned char Column,unsigned char *String)
{
	unsigned char i;
	
	LCD_SetCursor(Line,Column);
	
	for(i=0;String[i]!='\0';i++)
	{
		LCD_WriterData(String[i]);
		
	}
	
}

int LCD_Pow(int X,int Y)
{
	unsigned char i;
	int Result=1;
	for(i=0;i<Y;i++)
	{
		Result*=X;
	}
	return Result;

}

void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
	unsigned char i;
	LCD_SetCursor(Line,Column);		//789 抽取转化为字符		789/100%10=7  789/10%10=8  789/1%10=9
	for(i=Length;i>0;i--)
	{
		LCD_WriterData('0'+Number/LCD_Pow(10,i-1)%10);	//	转换asc码
		
	}
	

}

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_WriterData('+');
		Number1=Number;
	}
	else
	{
		LCD_WriterData('-');
		Number1=-Number;
	}
	
	for(i=Length;i>0;i--)
	{
		LCD_WriterData('0'+Number1/LCD_Pow(10,i-1)%10);	//	转换asc码
		
	}

}


void LCD_ShowHexNum(unsigned char Line, unsigned char Column,unsigned int Number,unsigned char Length)
{
	unsigned char i;
	unsigned char SingNumber;
	LCD_SetCursor(Line,Column);	
	
	for(i=Length;i>0;i--)
	{
		SingNumber=Number/LCD_Pow(16,i-1)%16;
		if(SingNumber<10)
		{
		LCD_WriterData('0'+SingNumber);
		}
		else
		{
		LCD_WriterData('A'+SingNumber-10);
		}
		
	}


}

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_WriterData('0'+Number/LCD_Pow(2,i-1)%2);	//	转换asc码
		
	}
}

#ifndef		__LCD1602_H
#define 	__LCD1602_H
void LCD_Init(void);
void  LCD_WriterCommand(unsigned char Command);
void LCD_ShowChar(unsigned char Line,unsigned char Column,unsigned char Char);
void LCD_ShowString(unsigned char Line,unsigned char Column,unsigned 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

实验现象:

LCD1602显示及滚动字幕

问题

总结

本节课主要学了LCD的功能代码编写,定义好引脚。然后根据时序先完成对写指令和写数据的编写,然后就是运用这些底层函数完成初始化,然后完成写指令,然后是位置的定义控制光标位,最后封装了各个功能函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值