沈阳企业网站开发定制,搜狗输入法下载安装,网站建设明薇通网络不错,北海网站开发#x1f680;write in front#x1f680; #x1f50e;大家好#xff0c;我是黄桃罐头#xff0c;希望你看完之后#xff0c;能对你有所帮助#xff0c;不足请指正#xff01;共同学习交流 #x1f381;欢迎各位→点赞#x1f44d; 收藏⭐️ 留言#x1f4dd;… write in front 大家好我是黄桃罐头希望你看完之后能对你有所帮助不足请指正共同学习交流 欢迎各位→点赞 收藏⭐️ 留言 本系列哔哩哔哩江科大51单片机的视频为主以及自己的总结梳理 前言
本文是根据哔哩哔哩网站上“江协科技51单片机”视频的学习笔记在这里会记录下江协科技51单片机开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了江协科技51单片机教学视频和链接中的内容。
引用
51单片机入门教程-2020版 程序全程纯手打 从零开始入门_哔哩哔哩_bilibili
江科大51单片机入门学习笔记合集_51单片机江科大教程下载-CSDN博客
【51单片机系列】LCD1602液晶模块_lcd1602液晶显示模块-CSDN博客
江科大51单片机入门学习笔记合集_51单片机江科大教程下载-CSDN博客
2302_80796399-CSDN博客
51单片机学习笔记14 LCD1602显示屏使用-CSDN博客
CZU23Yz-CSDN博客
灰海宽松-CSDN博客 正文
0. 概述
在淘宝上购买了江协科技51单片机开发板套件普中科技STC51单片机A2型号就上在上一篇博文里说的自己计划学习下江协科技51单片机开发教程通过STC51单片机这种MCU这种贴近于裸机的开发来增加对于系统硬件层面知识的了解和掌握。
术语和缩略语
缩写全称说明LCDLiquid Crystal Display 液晶显示屏
1. LCD1602液晶显示屏介绍
liquid crystal display 液晶显示屏一种字符型液晶显示模块可以显示 16*2 个字符每个字符是 5*7 点阵。
LCD1602实物如下 LCD1602背面自带两个黑色圆圆的牛屎封装芯片里面封装的是LCD1602液晶显示屏的芯片HD44780它里面带有字模和控制扫描控制电路它会自动扫描LCD1602液晶显示屏的点阵显示我们直接将数据发送给LCD1602显示即可即使我们不用像数码管显示一样需要我们单片机不停地进行扫描显示。 LCD1602看到16个管脚孔从左至右管脚编号顺序是1-16管脚功能定义如下表 管脚编号符号管脚说明1VSS电源地2VDD电源正极4.5~5.5V3VLVO液晶显示偏压信号调节LCD显示对比度4RS数据/命令选择端 H/L1为数据0为指令5R/W读/写选择端 H/L1为读0为写6E使能信号1为数据有效下降沿执行命令7~14D0~D7Data I/O15BLA背光源正极16BLK背光源负极 LCD1602时序逻辑里使能信号E高电平有效在下降沿执行命令。所以LCD1602驱动写数据/指令的时序可以是 E为低电平在D0~D7数据线上准备好要写的数据/指令E置为高电平在高电平时LCD1602采样数据然后E置位低电平产生下降沿LCD1602在下降沿执行指令。 E使能信号1为数据有效下降沿执行命令 LCD1602背面的液晶LCD显示驱动芯片一般是LCD1602 驱动芯片内部功能框图如下江协科技老师自己画的框图 CGRAM和CGROM内部的一个字模库CG: character Generator就像数码管显示一样当我们想让数码管显示数字1的时候并不是直接写1的而是要输出一个‘1’的字模就是需要一个译码的过程LCD1602液晶屏显示字符也是需要这样一个译码得到字符对应的字模的过程其中字模就存在LCD1602的GCRAMGCROM字模库里。 其中GCRAM是可写的可以存样用户自定义的一些字符的字模。 GCROM是出厂写死的其中存放预先定义好的字符字模。DDRAM数据显示区40*2Data Display RAM区DDRAM大小为每行40个字符乘以2行其中GC1602只能在每行显示16个字符DDRAM的大小要比GC1602显示的区域要长。用户写到DDRAM存储区域的指令将会映射显示到LCD1602的前16个字符。 为什么驱动芯片是40*2个字符大小的因为这个驱动芯片是通用的支持每行40个字符第二是可以通过移屏指令将DDRAM中的数据进行移屏并且移屏是循环移屏的移动到最左侧之外的数据将移回到最右侧这样配合GC1602的移屏指令就可是实现LCD1602屏幕的滚动显示。控制器屏幕16*2AC光标位置: DDRAM数据显示区
LCD1602的DDRAMDisplay Data RAM是用于存储显示数据的内存区域它是LCD控制器内部的一部分。DDRAM可以存储LCD屏幕上每个字符的数据包括字符形状和位置信息。通过修改DDRAM中的数据可以实现LCD屏幕上的文本显示。
以下是LCD1602的DDRAM地址与屏幕字符位置的对应关系表 CGRAMCGROM字模库
CGROM/CGRAM里存放的是LCD1602液晶显示屏的字母库其中CGROM中存放的不可修改的预先定义好的字符的子模子模的地址排布如下图 0x30~0x39 是数字0~9的字模对应则会ASCII码中的0~9字符的编码这是在定义CGROM子模的地址的时候特意设计的。0x41~0x5A对应大写字母 A~Z0x61~0x7A对应消息字母a~z这也是在定义CGROM子模的地址的时候特意设计的。CGRAM的可以存放用户自定义字符地址为1~8虽然下图里显示了1~8显示了两次但实际它们是重复的CGRAM自定义字符就是8个。 2. LCD1602的时序
LCD1602的写数据/指令时序图如下 LCD1602的写数据的操作时序如下 RS 数据/指令选择位设置为高电平表示写数据R/W读/写选择位设置为低电平表示写在时序图中DB0~DB7时序图交叉的地方表示写数据所以在DB0~DB7数据引脚准本好要写的数据。E 使能引脚先设置为电平数据有效持续一段时间再设置为低电平 时序参数时序的时间最短时间 3. LCD1602的指令集
LCD1602的指令集如下图 清屏指令0x1 清除DDRAM内容结果是清屏。清除AC的值结果是AC光标复位 清屏指令0x01用于清除LCD屏幕上的所有字符及光标位置并将光标移至起始位置0行0列。
Bit 0用于启动清屏指令的执行。其他位暂时保留一般不使用。
BitRSR/W76543210作用0000000001 光标(AC)归位指令0x02
光标归位指令0x02用于将LCD光标移回起始位置0行0列、同时把地址计数器AC值设置为0。 X表示该位不关心为0或者为1都不影响。 BitRSR/W76543210作用000000001X 数据写入方式指令 写入模式设置指令用于配置LCD的文本显示模式包括光标移动方向和字符显示是否移位等参数
BitRSR/W76543210作用00000001I/DS 显示开关控制指令 D 0显示功能关1显示功能开C 0无光标 1有光标B 0光标闪烁1光标不闪烁。 BitRSR/W76543210作用0000001DCB 功能设置指令 功能设置指令选择数据接口是4位还是8位选择单行显示还是两汉显示选择点阵的高度。 我们一般使用的是GC1602的的指令字0x38即8位数据几口两行显示5*7点阵。 设定DDRAM地址指令 设定下一个要存入数据的DDRAM地址 读取忙信号或AC地址指令 一般不用我们不从GC1602读取数据 4. LCD1602操作流程
LCD1602操作流程如下
LCD1602初始化 初始化 发送指令0x38 //8位数据几口两行显示5*7点阵发送指令0x0C //显示开光标关闪烁关发送指令0x06 //数据读写操作后光标自动加1画面不动发送指令0x01 //清屏 显示字符 显示字符 发送指令 0x80 | AC //设置光标位置DDRAM写入的地址发送数据 //发送想要显示的字符数据发送数据 //发送想要显示的字符数据 为什么第一步这里要将要设置的光标位置也就是DDRAM的写入地址或上 0x80哪我们注意到LCD1602指令集里从上到下通过最高位的1来标识属于那种指令“DDRAM地址设置”指令的最高位DB7固定为1所以要将光标AC位置的指令或上与最高位的1也就是或上0x80. 5. 编写LCD1602液晶显示屏驱动函数
编写我们自己LCD1602液晶显示屏驱动函数这里将会写如下这些函数方便我们自己在实验中打印在LCD1602液晶显示屏上打印信息。
LCD1602.c
#include REGX52.H
#include INTRINS.H
#include LCD1602.hsbit LCD_RSP2^6; //LCD1602 RS 数据/指令选择
sbit LCD_RWP2^5; //LCD1602 RW 读/写选择
sbit LCD_ENP2^7; //LCD1602 EN 使能 #define LCD_DataPort P0 //LCD1602 D0~D7 数据端口/*** brief LCD1602延时函数12MHz调用可延时1ms* param 无* retval 无*/
void LCD_Delay() //11.0592MHz 1ms
{unsigned char i, j;_nop_();i 2;j 199;do{while (--j);} while (--i);
}/*** brief LCD1602写命令* param Command 要写入的命令* retval 无*/
void LCD_WriteCommand(unsigned Command)
{LCD_RS 0; //LCD1602指令LCD_RW 0; //LCD1602写LCD_DataPort Command; //写指令LCD_EN 1; //LCD1602 EN使能为高LCD_Delay(); //delay 1ms防止时序太快LCD1602来不及执行LCD_EN 0; //LCD1602 EN使能为低LCD_Delay(); //delay 1ms
}/*** brief LCD1602写数据* param Data 要写入的数据* retval 无*/
void LCD_WriteData(unsigned Data)
{LCD_RS 1; //LCD1602数据LCD_RW 0; //LCD1602写LCD_DataPort Data; //写数据LCD_EN 1; //LCD1602 EN使能为高LCD_Delay(); //delay 1ms防止时序太快LCD1602来不及执行LCD_EN 0; //LCD1602 EN使能为低LCD_Delay(); //delay 1ms
}/*** brief LCD1602初始化函数* param 无* retval 无*/
void LCD_Init(void)
{LCD_WriteCommand(0x38); //8位数据接口两行显示5*7点阵LCD_WriteCommand(0x0c); //显示开光标关闪烁关 LCD_WriteCommand(0x06); //数据读写操作后光标自动加1画面不动LCD_WriteCommand(0x01); //清屏
}/*** brief LCD1602设置光标位置* param Line 行位置范围1~2* param Column 列位置范围1~16* retval 无*/
void LCD_SetCursor(unsigned char Line, unsigned char Column)
{unsigned char AC_DDRAM 0;/* 计算写入到DDRAM显示区的光标AC的位置 */if(Line 1){AC_DDRAM 0x00 (Column - 1);AC_DDRAM | 0x80;}else if(Line 2){AC_DDRAM 0x40 (Column - 1);AC_DDRAM | 0x80;}LCD_WriteCommand(AC_DDRAM); //设置光标地址
}/*** 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 Char 要显示的字符* retval 无*/
void LCD_ShowString(unsigned char Line, unsigned char Column, char *String)
{unsigned char i 0;LCD_SetCursor(Line, Column); //设置光标位置/* 打印字符串 */i 0;while(String[i] ! \0){LCD_WriteData(String[i]); //光标AC每次自动加1i;}
}/*** brief 返回值X的Y次方*/
signed int LCD_Power(int x, int y)
{int result 1;while(y 0){result * x;y--;}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 Num, unsigned char Length)
{unsigned char i 0;unsigned char Chr;LCD_SetCursor(Line, Column); //设置光标位置for(iLength; i0; i--){Chr Num/LCD_Power(10,i-1)%10;if(Chr 0 Chr 9){Chr 0x30;}LCD_WriteData(Chr);}
}/*** 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 Num, unsigned char Length)
{unsigned char i 0;unsigned char SingleNum;unsigned char Number1;LCD_SetCursor(Line, Column); //设置光标位置if(Num0){LCD_WriteData();Number1 Num;}else{LCD_WriteData(-);Number1 -Num; //-32768 转为32768之后可能会溢出}for(iLength; i0; i--){SingleNum Number1/LCD_Power(10,i-1)%10;if(SingleNum 0 SingleNum 9){SingleNum 0x30;}LCD_WriteData(SingleNum);}
}/*** 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 Num, unsigned char Length)
{unsigned char i 0;unsigned char SingleNum;LCD_SetCursor(Line, Column); //设置光标位置for(iLength; i0; i--){SingleNum Num/LCD_Power(16,i-1)%16;if(SingleNum 0 SingleNum 9){SingleNum 0x30; }else if(SingleNum 10 SingleNum 15){SingleNum SingleNum - 10 A; //16进制A,B,C,D,E,F}LCD_WriteData(SingleNum);}
}/*** brief 在LCD1602指定位置开始以二进制显示所给数字* param Line 起始行位置范围1~2* param Column 起始列位置范围1~16* param Number 要显示的数字范围0~1111 1111 1111 1111* param Length 要显示数字的长度范围1~16* retval 无*/
void LCD_ShowBinaryNum(unsigned char Line, unsigned char Column, unsigned int Num, unsigned char Length)
{unsigned char i 0;unsigned char SingleNum;LCD_SetCursor(Line, Column); //设置光标位置for(iLength; i0; i--){SingleNum Num/LCD_Power(2,i-1)%2;SingleNum 0x30;LCD_WriteData(SingleNum);}
}LCD1602.h
#ifndef __LCD1602_H__
#define __LCD1602_H__void LCD_Init(void);
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 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_ShowBinaryNum(unsigned char Line, unsigned char Column, unsigned int Num, unsigned char Length);
#endif
main.c
#include REGX52.H
#include INTRINS.H
#include LCD1602.hvoid main()
{LCD_Init();LCD_ShowChar(1, 1, A);LCD_ShowChar(1, 2, H);LCD_ShowChar(2, 3, B);LCD_ShowChar(2, 4, C);LCD_ShowChar(1, 1, A);LCD_ShowString(1, 1, Hello LCD1602);LCD_ShowNum(2, 1, 187, 3);LCD_Init();LCD_ShowHexNum(2, 1, 0x88FA, 4);LCD_ShowSignedNum(2, 7, -88, 2);LCD_ShowBinaryNum(1, 1, 0xAB, 8);while(1){}
}6. LCD1602液晶显示屏实验效果
实验1-LCD1602显示字符串 实验2 -LCD1602显示16进制和2进制数字
#include REGX52.H
#include INTRINS.H
#include LCD1602.h
#include Delay.hvoid main()
{LCD_Init();LCD_ShowChar(1, 1, A);LCD_ShowChar(1, 2, H);LCD_ShowChar(2, 3, B);LCD_ShowChar(2, 4, C);LCD_ShowChar(1, 1, A);LCD_ShowString(1, 1, Hello LCD1602);LCD_ShowNum(2, 1, 187, 3);LCD_Init();LCD_ShowHexNum(2, 1, 0x88FA, 4);LCD_ShowSignedNum(2, 7, -88, 2);LCD_ShowBinaryNum(1, 1, 0xAB, 8);while(1){}
}实验3-LCD1602显示屏滚动显示
在Main.c中增加LCD1602移屏指令这样LCD1602 DDRAM县市区一行40个字符的后面字符就可以滚动的显示出来LCD1602移屏显示指令每次向左移动时最左面移出的字符会回到最右边这样就可以在LCD1602循环显示。 #include REGX52.H
#include INTRINS.H
#include LCD1602.h
#include Delay.hvoid main()
{LCD_Init();LCD_ShowString(1, 1, MAGA 2024! Trump);LCD_ShowString(2, 1, Make Amerigan Gream Again, 2024 MAGA);while(1){Delay(500);LCD_WriteCommand(0x18);}
}