使用51单片机控制lcd1602字体显示

部分效果图:

准备工作:

51单片机(BST)+1602显示屏

基础知识:

注:X表示可以是0,也可以是1;

DL 1,

N 1,

F 0,

代码一: 要求显示字母‘a’

#include <reg52.h>

sbit E = P2^5; // enable 数据读写操作控制位 1: 写 0: 读
sbit RW = P1^1; // 读写控制线 0: 写操作, 1: 读操作
sbit RS = P1^0; // 数据和指令选择控制端, 0: 命令状态; 1:数据状态

Write_CMD(unsigned char x){
	int i = 1000;
	// 设置进入命令状态
	RS = 0;
	// 写操作
	RW = 0;
	// 0x01 清屏  0x38 设置 ......等指令内容
	P0 = x;
  // 打开指令读写操作控制允许
	E = 1;
	// 等待1秒
	while(i--);
	// 关闭指令读写操作控制允许
	E = 0;
}
Write_DATA(unsigned char x) {
	int i = 1000;
	// 设置进入数据状态
	RS = 1;
	// 写操作
	RW = 0;
	// 数据内容
	P0 = x;
  // 打开数据读写操作控制允许
	E = 1;
	// 等待1秒
	while(i--);
	// 关闭数据读写操作控制允许
	E = 0;
}
main(){
	
  // 清屏
	Write_CMD(0x01);
  // 设置16X2显示,5X7点阵,8位数据接口;
	Write_CMD(0x38);
  // 开显示,显示光标,光标闪烁;
	Write_CMD(0x0f);
	// 地址加1,当写入数据的时候光标右移:
	Write_CMD(0x06);
	// 写入字符a
	Write_DATA('a');
	while(1);
}

效果结果图:

代码优化一下:

#include <reg52.h>

sbit E = P2^5; // enable 数据读写操作控制位 1: 写 0: 读
sbit RW = P1^1; // 读写控制线 0: 写操作, 1: 读操作
sbit RS = P1^0; // 数据和指令选择控制端, 0: 命令状态; 1:数据状态

void Write_CMD(unsigned char x){
	int i = 1000;
	// 设置进入命令状态
	RS = 0;
	// 写操作
	RW = 0;
	// 0x01 清屏  0x38 设置 ......等指令内容
	P0 = x;
  // 打开指令读写操作控制允许
	E = 1;
	// 等待1秒
	while(i--);
	// 关闭指令读写操作控制允许
	E = 0;
}
void Write_DATA(unsigned char x) {
	int i = 1000;
	// 设置进入数据状态
	RS = 1;
	// 写操作
	RW = 0;
	// 数据内容
	P0 = x;
  // 打开数据读写操作控制允许
	E = 1;
	// 等待1秒
	while(i--);
	// 关闭数据读写操作控制允许
	E = 0;
}

// 初始化代码
void LCDinit(void){
  // 清屏
	Write_CMD(0x01);
  // 设置16X2显示,5X7点阵,8位数据接口;
	Write_CMD(0x38);
  // 开显示,显示光标,光标闪烁;
	Write_CMD(0x0f);
	// 地址加1,当写入数据的时候光标右移:
	Write_CMD(0x06);
}

main(){
	
// 初始化代码
	LCDinit();
	// 写入字符a
	Write_DATA('a');
	while(1);
}

例2: 从C7的位置显示字符“W”

#include <reg52.h>

sbit E = P2^5; // enable 数据读写操作控制位 1: 写 0: 读
sbit RW = P1^1; // 读写控制线 0: 写操作, 1: 读操作
sbit RS = P1^0; // 数据和指令选择控制端, 0: 命令状态; 1:数据状态

void Write_CMD(unsigned char x){
	int i = 1000;
	// 设置进入命令状态
	RS = 0;
	// 写操作
	RW = 0;
	// 0x01 清屏  0x38 设置 ......等指令内容
	P0 = x;
  // 打开指令读写操作控制允许
	E = 1;
	// 等待1秒
	while(i--);
	// 关闭指令读写操作控制允许
	E = 0;
}
void Write_DATA(unsigned char x) {
	int i = 1000;
	// 设置进入数据状态
	RS = 1;
	// 写操作
	RW = 0;
	// 数据内容
	P0 = x;
  // 打开数据读写操作控制允许
	E = 1;
	// 等待1秒
	while(i--);
	// 关闭数据读写操作控制允许
	E = 0;
}

// 初始化代码
void LCDinit(void){
  // 清屏
	Write_CMD(0x01);
  // 设置16X2显示,5X7点阵,8位数据接口;
	Write_CMD(0x38);
  // 开显示,显示光标,光标闪烁;
	Write_CMD(0x0f);
	// 地址加1,当写入数据的时候光标右移:
	Write_CMD(0x06);
}

main(){
	
  //初始化代码
	LCDinit();
	// 指令显示从C7位置开始写字母
	Write_CMD(0xC7);
	// 写入字符W
	Write_DATA('W');
	while(1);
}

例子三,输出“I Love China !”

#include <reg52.h>

sbit E = P2^5; // enable 数据读写操作控制位 1: 写 0: 读
sbit RW = P1^1; // 读写控制线 0: 写操作, 1: 读操作
sbit RS = P1^0; // 数据和指令选择控制端, 0: 命令状态; 1:数据状态

void Write_CMD(unsigned char x){
	int i = 1000;
	// 设置进入命令状态
	RS = 0;
	// 写操作
	RW = 0;
	// 0x01 清屏  0x38 设置 ......等指令内容
	P0 = x;
  // 打开指令读写操作控制允许
	E = 1;
	// 等待1秒
	while(i--);
	// 关闭指令读写操作控制允许
	E = 0;
}
void Write_DATA(unsigned char x) {
	int i = 1000;
	// 设置进入数据状态
	RS = 1;
	// 写操作
	RW = 0;
	// 数据内容
	P0 = x;
  // 打开数据读写操作控制允许
	E = 1;
	// 等待1秒
	while(i--);
	// 关闭数据读写操作控制允许
	E = 0;
}

// 初始化代码
void LCDinit(void){
  // 清屏
	Write_CMD(0x01);
  // 设置16X2显示,5X7点阵,8位数据接口;
	Write_CMD(0x38);
  // 开显示,显示光标,光标闪烁;
	Write_CMD(0x0f);
	// 地址加1,当写入数据的时候光标右移:
	Write_CMD(0x06);
}

main(){
	int i;
	char a[] = {"I Love China !"};
  //初始化代码
	LCDinit();
  for(i = 0; i < 14; i++){
	  // 指令显示从C1位置开始写字母
		Write_CMD(0xC1 + i);
		// 写入字符
		Write_DATA(a[i]);
	}
	while(1);
}

附官方提供的示例代码:


/**********************BST-V51实验开发板例程************************
*  平台:BST-V51 + Keil U3 + STC89C52
*  名称:LCD1602模块实验
*  公司:深圳市XXXX科技有限公司        
*  日期:2013-11
*  晶振:11.0592MHZ
*  说明:免费开源,不提供源代码分析.
******************************************************************/
//实验目的:
/*-----------------------------------------------
  名称:LCD1602
  内容:通过标准程序静态显示字符
  引脚定义如下:1-VSS 2-VDD 3-V0 4-RS 5-R/W 6-E 7-14 DB0-DB7 15-BLA 16-BLK
------------------------------------------------*/
#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include<intrins.h>
#include<string.h>

#define uchar unsigned char

sbit RS = P1^0;   //定义端口 
sbit RW = P1^1;
sbit EN = P2^5;
sbit DU = P2^0;
sbit WE = P2^1;

#define RS_CLR RS=0 
#define RS_SET RS=1

#define RW_CLR RW=0 
#define RW_SET RW=1 

#define EN_CLR EN=0
#define EN_SET EN=1

#define DataPort P0

/*协议定义*/
bit startBit = 0;  				//串口接收开始标志位
bit newLineReceived = 0; 		//串口一帧协议包接收完成
unsigned char inputString[50];  //接收数据协议
/*------------------------------------------------
                 串口初始化函数
------------------------------------------------*/
void init_com(void)
{
	TMOD|=0x20;		   //设T0为方式1,GATE=1;
	SCON=0x50;
	TH1=0xFD;
	TL1=0xFD;
	TR1=1;			   //开启定时器
	//TI=1;
	EA=1;			   //开启总中断
	ES=1;			   //串口中断打开
}


void cmg88()//关数码管,点阵函数
{
	DU=1;  
	P0=0X00;
	DU=0;
}
/*------------------------------------------------
 uS延时函数,含有输入参数 unsigned char t,无返回值
 unsigned char 是定义无符号字符变量,其值的范围是
 0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
 长度如下 T=tx2+5 uS 
------------------------------------------------*/
void DelayUs2x(unsigned char t)
{   
	while(--t);
}
/*------------------------------------------------
 mS延时函数,含有输入参数 unsigned char t,无返回值
 unsigned char 是定义无符号字符变量,其值的范围是
 0~255 这里使用晶振12M,精确延时请使用汇编
------------------------------------------------*/
void DelayMs(unsigned char t)
{
     
 while(t--)
 {
     //大致延时1mS
     DelayUs2x(245);
	 DelayUs2x(245);
 }
}
/*------------------------------------------------
              判忙函数
------------------------------------------------*/
 bit LCD_Check_Busy(void) 
 { 
	 DataPort= 0xFF; 
	 RS_CLR; 
	 RW_SET; 
	 EN_CLR; 
	 _nop_(); 
	 EN_SET;
	 return (bit)(DataPort & 0x80);
 }
/*------------------------------------------------
              写入命令函数
------------------------------------------------*/
 void LCD_Write_Com(unsigned char com) 
 {  
	 while(LCD_Check_Busy()); //忙则等待
	 RS_CLR; 
	 RW_CLR; 
	 EN_SET; 		
	 DataPort= com; 
	 _nop_(); 
	 EN_CLR;
 }
/*------------------------------------------------
              写入数据函数
------------------------------------------------*/
 void LCD_Write_Data(unsigned char Data) 
 { 
	 while(LCD_Check_Busy()); //忙则等待
	 RS_SET; 
	 RW_CLR; 
	 EN_SET; 
	 DataPort= Data; 
	 _nop_();
	 EN_CLR;
 }

/*------------------------------------------------
                清屏函数
------------------------------------------------*/
 void LCD_Clear(void) 
 { 
	 LCD_Write_Com(0x01); 
	 DelayMs(5);
 }
/*------------------------------------------------
              写入字符串函数
------------------------------------------------*/
 void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s) 
 {     
	 if (y == 0) 
	 {     
		 LCD_Write_Com(0x80 + x);     //表示第一行
	 }
	 else 
	 {      
	 	LCD_Write_Com(0xC0 + x);      //表示第二行
	 }        
	 while (*s) 
	 {     
		 LCD_Write_Data( *s);     
		 s ++;     
	 }
 }
/*------------------------------------------------
              写入字符函数
------------------------------------------------*/
 void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data) 
 {     
 	if (y == 0) 
 	{     
 		LCD_Write_Com(0x80 + x);     
 	}    
 	else 
 	{     
 		LCD_Write_Com(0xC0 + x);     
 	}        
 	LCD_Write_Data( Data);  
 }
/*------------------------------------------------
              初始化函数
------------------------------------------------*/
void LCD_Init(void) 
{
   LCD_Write_Com(0x38);    /*显示模式设置*/ 
   DelayMs(5); 
   LCD_Write_Com(0x38); 
   DelayMs(5); 
   LCD_Write_Com(0x38); 
   DelayMs(5); 
   LCD_Write_Com(0x38);  
   LCD_Write_Com(0x08);    /*显示关闭*/ 
   LCD_Write_Com(0x01);    /*显示清屏*/ 
   LCD_Write_Com(0x06);    /*显示光标移动设置*/ 
   DelayMs(5); 
   LCD_Write_Com(0x0C);    /*显示开及光标设置*/
}
   
/*------------------------------------------------
                    主函数
------------------------------------------------*/ 
void main(void) 
{ 
	uchar temp[17] = {0};
	cmg88();//关数码管,点阵函数
	LCD_Init(); 
	LCD_Clear();//清屏
	init_com();
	
	LCD_Write_Char(7,0,'o');
	LCD_Write_Char(8,0,'k');
	LCD_Write_String(1,1,"I Love TT");
	while (1) 
	{  
		//开始解析协议 $51,LCD1602,1,0123456789abcdef# 第一行	 $51,LCD1602,2,0123456789abcdef# 第二行
		while (newLineReceived)  //协议数据接收完毕一包
		{
			//判断是否是51的协议
			if(inputString[1] != '5' || inputString[2] != '1')
			{
			 	newLineReceived = 0;  
		   		memset(inputString, 0x00, sizeof(inputString)); 
				break; 
			}
			//判断是否是1602的协议数据
		 	if(inputString[4] != 'L' || inputString[5] != 'C' || inputString[6] != 'D'
			|| inputString[7] != '1'|| inputString[8] != '6'|| inputString[9] != '0'|| inputString[10] != '2')
			{
				newLineReceived = 0;  
	   			memset(inputString, 0x00, sizeof(inputString)); 
				break;	
			}
		
			//开始取数据  位置12 开始  $51,HS00ff3003#
			if(inputString[12] == '0') //清屏
			{
				LCD_Clear();//清屏	
			}
			if(inputString[12] == '1') //显示第一行
			{
				memcpy(temp, inputString+14, 16);
				LCD_Write_String(0, 0, temp);
			}		
			if(inputString[12] == '2') //显示第二行
			{
				memcpy(temp, inputString+14, 16);
				LCD_Write_String(0, 1, temp);
			}

		 	newLineReceived = 0;  
	   		memset(inputString, 0x00, sizeof(inputString)); 
			break;
		}
	
	}
}

/******************************************************************/
/* 串口中断程序*/
/******************************************************************/
void UART_SER () interrupt 4
{
	unsigned char n; 	//定义临时变量
	static int num = 0;

	if(RI) 		//判断是接收中断产生
	{
		RI = 0; 	//标志位清零
		n = SBUF; //读入缓冲区的值

		//control=n;
	    if(n == '$')
	    {
	      startBit = 1;
		  num = 0;
	    }
	    if(startBit == 1)
	    {
	       inputString[num] = n; 
		   num++;    
	    }  
	    if (startBit == 1 && n == '#') 
	    {
	       newLineReceived = 1; 
	       startBit = 0;
		   num = 0;
	    }
		
		if(num >= 50)
		{
			num = 0;
			startBit = 0;
			newLineReceived	= 0;
		}
	}

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/445124.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

NIN网络中的网络

是什么 intro LeNet→AlexNet→VGG→NiN→GoogLeNet→ResNetLeNet→AlexNet→VGG 卷积层模块充分抽取空间特征全连接层输出分类结果AlexNet & VGG 改进在于把两个模块加宽 、加深&#xff08;加宽指增加通道数&#xff0c;那加深呢&#xff1f;&#xff08;层数增加叭 Ni…

【STM32】HAL库 CubeMX 教程 --- 通用定时器 TIM2 定时

实验目标&#xff1a; 通过CUbeMXHAL&#xff0c;配置TIM2&#xff0c;1s中断一次&#xff0c;闪烁LED。 一、常用型号的TIM时钟频率 1. STM32F103系列&#xff1a; 所有 TIM 的时钟频率都是72MHz&#xff1b;F103C8不带基本定时器&#xff0c;F103RC及以上才带基本定时器。…

ClickHouse Grafana插件4.0版 - 升级SQL可观测性

本文字数&#xff1a;3396&#xff1b;估计阅读时间&#xff1a;9 分钟 作者&#xff1a;Clickhouse team 审校&#xff1a;庄晓东&#xff08;魏庄&#xff09; 本文在公众号【ClickHouseInc】首发 自2022年5月Grafana的ClickHouse插件首次发布以来&#xff0c;两种技术都有了…

AOP的常见使用方法

面向切面编程&#xff08;AOP&#xff0c;Aspect-Oriented Programming&#xff09; 面向切面编程是一种软件设计和编程范式&#xff0c;它旨在解决在传统面向对象编程&#xff08;OOP&#xff09;中难以模块化处理的“横切关注点”问题。横切关注点是指那些跨越多个对象、类或…

每日OJ题_牛客HJ74 参数解析(IO型OJ)

目录 牛客HJ74 参数解析 解析代码1 解析代码2 牛客HJ74 参数解析 参数解析_牛客题霸_牛客网 解析代码1 #include <iostream> #include <string> #include <vector> using namespace std; int main() {string str "";getline(cin, str);vecto…

windows安装ElasticSearch踩坑记

ElasticSearch是一个开源的分布式搜索和分析引擎。它提供实时分布式搜索功能&#xff0c;可以索引和搜索大量的结构化和非结构化数据。Elasticsearch以其速度、可伸缩性和处理复杂查询的能力而闻名。它常用于日志分析、全文搜索、文档搜索和数据分析等领域。使用ElasticSearch的…

AHU 数据库 实验五

【实验名称】 实验5 数据库的数据更新与视图管理 【实验目的】 1. 熟悉数据更新操作的概念与操作类型&#xff1b; 2. 熟练掌握INSERT、UPDATE、DELETE语句的基本语法&#xff1b; 3. 熟练运用INSERT、UPDATE、DELETE语句实现数据的插入、修改与删除…

git学习(创建项目提交代码)

操作步骤如下 git init //初始化git remote add origin https://gitee.com/aydvvs.git //建立连接git remote -v //查看git add . //添加到暂存区git push 返送到暂存区git status // 查看提交代码git commit -m初次提交git push -u origin "master"//提交远程分支 …

获取bean的几种情况总结

1. 情景一 bean 对应的类没有实现任何接口 根据 bean 本身的类型获取 bean 测试&#xff1a;IOC容器中同类型的 bean 只有一个 正常获取到 IOC 容器中的那个 bean 对象 测试&#xff1a;IOC 容器中同类型的 bean 有多个 会抛出 NoUniqueBeanDefinitionException 异常&#xf…

STM32---ADC

ADC 概念 众所周知&#xff0c;GPIO只能读入高电平或者低电平&#xff0c;那如果现有一个模拟量&#xff0c;该如何读取呢&#xff0c;比如电压的范围是0~3.3v&#xff0c;如何获取电压的值。就需要ADC&#xff08;Analog-Digital Converter&#xff09;了。ADC可以将引脚上连…

自动从Android上拉取指定文件

需求场景 利用Mac中的脚本编辑器实现从连接的Android设备中获取指定的文件。 环境 macOS Monterey 版本 12.7.1脚本编辑器adb环境&#xff08;如果没有的话&#xff0c;可以网上搜下Mac配置adb&#xff09; 实现方案 1、打开脚本编辑器&#xff1b; 2、新建一个脚本文件&…

视频编解码技术介绍 - 基本概念篇

第一章 视频编解码技术介绍 - 基本概念篇 文章目录 前言1. 我的疑问1.1 什么是视频编解码技术1.2 为什么会有视频编解码技术1.3 视频编解码中有哪些核心技术1.4 作为开发者需要重点了解视频编解码中的哪些技术 2. 视频编解码的历史3. 基本概念3.1 像素3.2 分辨率3.3 ppi(像素密…

详细讲解Xilinx DDR3 的MIG IP生成步骤及参数含义

前几篇文章讲解了SDRAM到DDR3各自的变化&#xff0c;本文讲解如何使用DDR3&#xff0c;在Altera的Cyclone IV开发板上一般会使用SDRAM作为存储数据的芯片&#xff0c;而Xilinx的S6和7000系列一般使用DDR3作为存储数据的芯片。 从SDRAM芯片内部结构分析其原理&#xff0c;从内部…

腾讯云8核16g服务器性能好不好?亲测并发数支持人数

腾讯云8核16G轻量服务器CPU性能如何&#xff1f;18M带宽支持多少人在线&#xff1f;轻量应用服务器具有100%CPU性能&#xff0c;18M带宽下载速度2304KB/秒&#xff0c;折合2.25M/s&#xff0c;系统盘为270GB SSD盘&#xff0c;月流量3500GB&#xff0c;折合每天116.6GB流量&…

AHU 人工智能实验-CCA

神经网络覆盖算法——CCA&#xff08;基于Ling Zhang 和Bo Zhang论文) Abstract 在这篇文章中我将介绍基于张铃和张钹学者提出的CCA算法&#xff0c;并实现代码复现&#xff0c;给出使用的数据集&#xff0c;以及实验结果对比。 1. Introduction 1.1 Background 我们知道自…

外包干了6天后悔了,技术明显进步。。。。。

先说一下自己的情况&#xff0c;本科生&#xff0c;19年通过校招进入广州某软件公司&#xff0c;干了接近3年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试…

[虚拟机保护逆向] [HGAME 2023 week4]vm

[虚拟机保护逆向] [HGAME 2023 week4]vm 虚拟机逆向的注意点&#xff1a;具体每个函数的功能&#xff0c;和其对应的硬件编码的*长度* 和 *含义*&#xff0c;都分析出来后就可以编写脚本将题目的opcode转化位vm实际执行的指令 &#xff1a;分析完成函数功能后就可以编写脚本输出…

跑马灯样式

这里的公告是要做成&#xff0c;跑马灯的样式&#xff0c;文字是会移动并且隐藏掉的。 HTML&#xff1a; <div class"notice"><div class"yrr"><img src"./img/ia_100000018.png" alt"" /></div><div …

循序渐进丨MogDB 数据库特性之动态数据脱敏机制

数据脱敏是行之有效的数据库隐私保护方案之一&#xff0c;可以在一定程度上限制非授权用户对隐私数据的窥探。动态数据脱敏机制是一种通过定制化脱敏策略来实现对隐私数据保护的技术&#xff0c;可以在保留原始数据的前提下有效地解决非授权用户对敏感信息访问的问题。当管理员…

Fastjson 1.2.24 反序列化导致任意命令执行漏洞复现(CVE-2017-18349)

写在前面 CVE-2017-18349 指的是 fastjson 1.2.24 及之前版本存在的反序列化漏洞&#xff0c;fastjson 于 1.2.24 版本后增加了反序列化白名单&#xff1b; 而在 2019 年&#xff0c;fastjson 又被爆出在 fastjson< 1.2.47 的版本中&#xff0c;攻击者可以利用特殊构造的 …