【单片机】16-LCD1602和12864显示器

1.LCD显示器相关背景

1.LCD简介

(1)显示器,常见显示器:电视,电脑

(2)LCD(Liquid Crystal Display),液晶显示器,原理介绍

(3)LCD应用领域:手机,电脑

(4)将来取代LCD:LED,OLED【全面屏---软性】

2.电子显示器的原理

1.像素(分辨率)

显示单元【液晶分子】

但是实际上:像素!=分辨率

比如:出厂时电脑的像素已经确定,就是最大的显示【比如是1920*1080】,所以最大的分辨率是1920*1080,但是不能超过1920*1080,却可以小于1920*1080

2.显存

用来做显示的内存【电子显示效果跟内存有关】

找一块空间来存储像素和内存的对应关系。【将要显示的内容丢到显存中---存储的是要显示的内容与液晶分子的一一对应关系

3.字模

字的模型。表示将这个字如何对应到显示器中。【将“A“放入相同的分辨率的显示器上,会产生不同的字模】

4.字库

字模形成的库。

5.控制器(关键)和驱动器

LCD显示器中的2个器件

控制器:方向盘,挂挡---跟CPU对接---靠近软件

驱动器:马达,发动器---将要显示的东西打到液晶显示器上---靠近硬件

6.软件+硬件实现功能

2.LCD1602

1.简介

1.为什么叫1602

16*2--》显示器可以显示的字符【显示器可以显示2排,每排16个

能显示的字符数是32,但是像素数不是32,因为一个字符是由多个像素组成的。有可能一个字符是由5*7=35个像素组成的,也有可能是由6*8=48给像素组成的。但是我们不用去管,因为LCD1602内置了字库了。

2.带ASCII码字库,不能显示中文

当我们想要让LCD1602显示某一个ASCII码字符时候,只需要将这个字符对应的ASCII码发给LCD1602内部的控制器,控制器就会去查字库就得到字模,如何将字模发给内部的驱动器去驱动LCD做显示。

2.原理图和接线引脚

1.引脚分为:数据接口+控制接口

16根线:2根VCC,2根GND,1根VO(调节屏幕亮度),RS+RW+E(控制信号线),DB0-DB7(数据线)

2.并行接口

串行:就是数据线只有1根(I2C中的SDA),同时只能传输1个bit位,如果要传送多个bit位必须分时传输。

并行:就是数据线有很多根,每一根可以传输1个bit位,所以同时可以传输多个bit位。

如LCD1602有8根数据线,所以一次同时传输8bit位

3.背光调节

1根VO(调节屏幕亮度)

4.接线确认

3.数据手册

LCD1602数据手册速览 - 电子组培训文档

https://www.dfrobot.com.cn/image/data/DFR0063/CN/HD44780.pdf

1.LCM和LCD

LCM:就是lcd module(LCD模组)

2.主要技术参数解析

3.引脚定义(结合原理图来对照分析)

4.控制器接口说明(主要控制器型号)

RS=1时候,D0-D7上传输的是数据

RS=0时候,D0-D7上传输的是命令

RW=1时候,表示我们要读

RW=0时候,表示我们要写

E=1时候,表示使能        enable

E=0时候,表示禁止(禁能) disable

3.LCD1602控制器的底层时序

1.关键点

(1)时序走控制接口引脚

(2)指令码,状态字,数据,这三个走数据接口

(3)注意是并行的

2.控制器接口

3.读状态时序分析

判断当前LCD是否有在显示数据

对控制器每一次进行读写操作之前,都必须进行读写检测,确保bit7==0

状态字的解析方法

//基本操作时序:读状态:输入RS=0,RW=1,EN=1   输出:bit0-bit7--》状态 
void Read_Busy{     //忙检测函数,判断bit7是0:允许执行;1禁止unsigned char sta;     LCD1602_DB=0xff;LCD1602_RS=0;LCD1602_RW=1;do{LCD1602_EN=1;//使能sta=LCD1602_DB;//读取8个bit位的状态LCD1602_EN=0;//如果sta&0x80==1,表示sta的bit7为1,则表示禁止状态,还要继续循环}while(sta & 0x80);
}

4.写指令时序分析

void Lcd1602_Write_Cmd(unsigned char cmd){Read_Busy();LCD1602_RS=0;LCD1602_RW=0;LCD1602_DB=cmd; //写入bit0-bit7LCD1602_EN=1;LCD1602_EN=0;
}

5.读数据时序分析

读数据实际上是读”显存“

但是实际上我们不需要

6.写数据的时序分析

void Lcd1602_Write_Data(unsigned char dat){ //写数据Read_Busy();LCD1602_RS=0;LCD1602_RW=0;LCD1602_DB=dat; //将数据写入LCD1602_EN=1;LCD1602_EN=0;
}

注意点:

写指令-->RS=0

写数据-->RS=1

7.RAM地址映射图

芯片范围是0-39每行,但是实际只用了0-15每行

将”A“给00这个空间,这个00会自动查找该位

4.指令说明

1.显示模式设置

lcd1602_write_cmd(0x38);//设置16*2显示,数据总线8位,5*7点阵/字符

2.显示开/关及光标设置

//y=0是上面一行,y=1是下面一行
void LcdSetCursor(unsigned char x,unsigned char y){//坐标显示unsigned char addr;if(y==0)addr=0x00+x;elseaddr=0x40+x;Lcd1602_write_cmd(addr|0x80);
}

关闭显示:0000 1000   0x08

打开显示不显示光比 : 0000 1100   0x0c

打开显示并且显示光标且光标闪烁: 0000 1111   0x0f

地址指针自动+1,整体屏幕不移动 :0000 0110   0x06

3.数据控制

控制器内部设有一个数据地址指针,用户可以通过它们来访问内部的全部80字节RAM

1.数据指针设置

0x80+(0x00-0x0f)   第一行设置地址指针指令

0x80+(0x40-0x4f)   第二行设置地址指针指令

2.读数据

3.写数据

4.其他设置

0x01  显示清屏

0x02  显示回车

5.初始化过程

void lcd1602_init(void)
{lcd1602_write_cmd(0x28);//数据总线4位,显示2行,5*7点阵/字符lcd1602_write_cmd(0x08);//显示关闭【可以省略】lcd1602_write_cmd(0x01);//显示清屏【可以省略】lcd1602_write_cmd(0x0c);//显示功能开,无光标,光标闪烁lcd1602_write_cmd(0x06);//写入新数据后光标右移,显示屏不移动lcd1602_write_cmd(0x01);//清屏	
}

4.显示字符

/*******************************************************************************
* 函 数 名       : lcd1602_show_string
* 函数功能		 : LCD1602显示字符
* 输    入       : x,y:显示坐标,x=0~15,y=0~1;str:显示字符串
* 输    出    	 : 无
*******************************************************************************/
void lcd1602_show_string(u8 x,u8 y,u8 *str)
{u8 i=0;if(y>1||x>15)return;//行列参数不对则强制退出if(y<1)	//第1行显示{	while(*str!='\0')//字符串是以'\0'结尾,只要前面有内容就显示{if(i<16-x)//如果字符长度超过第一行显示范围,则在第二行继续显示{lcd1602_write_cmd(0x80+i+x);//第一行显示地址设置	}else{lcd1602_write_cmd(0x40+0x80+i+x-16);//第二行显示地址设置	}lcd1602_write_data(*str);//显示内容str++;//指针递增i++;	}	}else	//第2行显示{while(*str!='\0'){if(i<16-x) //如果字符长度超过第二行显示范围,则在第一行继续显示{lcd1602_write_cmd(0x80+0x40+i+x);	}else{lcd1602_write_cmd(0x80+i+x-16);	}lcd1602_write_data(*str);str++;i++;	}	}				
}

5.代码实现

lcd1602.c

#include <reg51.h>// 对LCD1602的底层以及高层时序做封装// IO接口定义
#define LCD1602_DB  P0      //data bus 数据总线
// 控制总线
sbit LCD1602_RS = P2^6;
sbit LCD1602_RW = P2^5;
sbit LCD1602_EN = P2^7;	/************ 低层时序 ********************************/
void Read_Busy()           //忙检测函数,判断bit7是0,允许执行;1禁止
{unsigned char sta;      //LCD1602_DB = 0xff;LCD1602_RS = 0;LCD1602_RW = 1;do{LCD1602_EN = 1;sta = LCD1602_DB;LCD1602_EN = 0;    //使能,用完就拉低,释放总线}while(sta & 0x80);
}void Lcd1602_Write_Cmd(unsigned char cmd)     //写命令
{Read_Busy();LCD1602_RS = 0;LCD1602_RW = 0;	LCD1602_DB = cmd;LCD1602_EN = 1;LCD1602_EN = 0;    
}void Lcd1602_Write_Data(unsigned char dat)   //写数据
{Read_Busy();LCD1602_RS = 1;LCD1602_RW = 0;LCD1602_DB = dat;LCD1602_EN = 1;LCD1602_EN = 0;
}/************* 高层时序 ******************************/
// 本函数用来设置当前光标位置,其实就是设置当前正在编辑的位置,
// 其实就是内部的数据地址指针,其实就是RAM显存的偏移量
// x范围是0-15,y=0表示上面一行,y=1表示下面一行
void LcdSetCursor(unsigned char x,unsigned char y)  //坐标显示
{unsigned char addr;if(y == 0)addr = 0x00 + x;elseaddr = 0x40 + x;Lcd1602_Write_Cmd(addr|0x80);
}// 函数功能是:从坐标(x,y)开始显示字符串str
// 注意这个函数不能跨行显示,因为显存地址是不连续的
// 其实我们可以封装出一个能够折行显示的函数的
void LcdShowStr(unsigned char x,unsigned char y,unsigned char *str)     //显示字符串
{LcdSetCursor(x,y);      //当前字符的坐标while(*str != '\0'){Lcd1602_Write_Data(*str++);}
}// 初始化LCD,使之能够开始正常工作
void InitLcd1602()              //1602初始化
{Lcd1602_Write_Cmd(0x38);    //打开,5*8,8位数据//Lcd1602_Write_Cmd(0x0c);	// 打开显示并且无光标Lcd1602_Write_Cmd(0x0f);	// 打开显示并且光标闪烁Lcd1602_Write_Cmd(0x06);Lcd1602_Write_Cmd(0x01);    //清屏   
}

lcd1602.h

#ifndef __lcd1602__H__
#define __lcd1602__H__#include<reg51.h>#define u8 unsigned char //只需要声明高层时序即可,而底层时序是不需要声明
//因为我们在头文件中声明这个函数,目的是为了让别的文件去包含这个
//从而调用这个头文件中声明的函数,所以我们只需要声明1602.c中将来
//会被外部.c文件调用的哪些函数即可,而且1602.c中自己使用的内部函数将来也
//不会被外部.c文件调用,因此就不用声明了。void LcdSetCursor(unsigned char x,unsigned char y);
void LcdShowStr(unsigned char x,unsigned char y,unsigned char *str);
void lcd1602_show_string(u8 x,u8 y,u8 *str);
void InitLcd1602();#endif

main.c

#include"lcd1602.h"void main(){InitLcd1602();LcdShowStr(0, 0, "nihao,xiaolin");
}

6.LCD12864

1.什么是LCD12864

(1)128p*64p,注意不是字符而是pixel【像素】

(2)没有内置字库,用户需要提供字模给LCD12864内部的控制器

(3)常见外观有2种

(4)可以显示文字(英文,中文或者其他文字),可以显示图片(点阵图)

2.原理图和数据手册和接线

1.接线确认

2.原理图(开发板底板,屏幕转接板)

3.数据手册(LCD12894,ST7565【内部控制器】)

https://www.dfrobot.com.cn/image/data/FIT0021/CN/LCD12864%20chinese%20char.pdf


 

http://pdf-html.ic37.com/pdf_file_A/20200531/pdf_pdf/pdf4/SITRONIX/ST756_datasheet_832636/135203/ST756_datasheet.pdf

7.LCD12864低层时序分析

1.学习方法

(1)找准数据手册中关键信息点,用来查而不是挨个看

(2)数据手册对照官方示例代码来参照对比

(3)要结合各部分原理图,各部分数据手册,实例代码来综合分析

(4)必要时做笔记

2.ST7565低层时序分析

由于我们找不到时序图所以只能通过引脚描述来进行分析

1.写指令

void LcdSt7565_WriteCmd(cmd){LCD12864_CS=0;    //chip select 打开片选LCD12864_RD=1;    //disable read 读失能LCD12864_RS=0;    //select command 悬着命令LCD12864_RW=0;    //slect write 选择写模式_nop_();_nop_();DATA_PORT = cmd; //put command,放置命令_nop_();_nop_();LCD12864_RW = 1;	   //command writing ,写入命令
}

2.写数据

void LcdSt7565_WriteData(dat)
{	LCD12864_CS = 0;	   //chip select,打开片选LCD12864_RD = 1;	   //disable read,读失能	LCD12864_RS = 1;       //select data,选择数据LCD12864_RW = 0;       //select write,选择写模式_nop_();_nop_();DATA_PORT = dat;       //put data,放置数据_nop_();_nop_();LCD12864_RW = 1;	   //data writing,写数据 
}

8.ST7565的指令集

1.高层时序分析

1.指令式交互系统

实际上我们是给CPU编程,控制ST7565

2.指令表是关键

操作手册

2.指令系统学习方法

(1)沿着数据手册顺序分析

(2)沿着示例代码按需分析

3.逐个分析

对应上面的P32页

1. 打开开关:Display ON/OFF

Display ON/OFF

                        1010 1111                0xaf    on

                        1010 1110                0xae    off

2.一行显示:Display Start Line Set

显示行号设置

        0x 0100 0000+(0-63)

        0x40+(0-63)                表示要将内容显示在第0-63行

实际上ST7565是65*132【多了一行没有显示】

3.页地址设置:Page Address Set

设置page address   

        1011 0000+(0-7)

        0xB0+(0-7)    表示设置page address

4.列地址设置Column Address Set

设置column address     

        一个完整指令是分为2条相连的指令合起来的。必须连发2个

        指令1:0001 0000+高4位        0x10+高4位

        指令2:0000 0000+低4位        0x00+低4位

5.设置从哪一个方向开始显示:ADC Select

设置ADC

        0xA0        normal                columu address 从左往后的

        0xa1         reverse               columu address 从右往左的

6.设置相反的显示:Display Normal/Reverse

该命令可以反转点亮和熄灭的显示,而不覆盖显示数据 RAM 的内容。 完成此操作后
显示数据 RAM 内容被保留。

7.软件复位:Reset

在初始化的时候,应该先硬件复位【LCD12864_RSET = 0】,在软件复位【LcdSt7565_WriteCmd(0xE2)】。

4.对照官方代码进行解析:初始化操作

初始化函数:

(1)第一类指令:时序需要

(2)第二类指令:硬件特性设置需要的(比如屏幕亮度,对比度之类)
(3)第三类指令:显示i参数相关的:A1/A0

/*******************************************************************************
* 函 数 名         : LCD12864_Init
* 函数功能		   : 初始化12864
* 输    入         : 无
* 输    出         : 无
* 说    明         : LCD12864的命令指令可以查看例程文件夹下的《ST7565p数据手册》
*                  * 的第51页的位置。
*******************************************************************************/void Lcd12864_Init()
{uchar i;LCD12864_RSET = 0;//硬件复位for (i=0; i<100; i++);//让内部进行复位LCD12864_CS = 0;//打开片选,选中芯片LCD12864_RSET = 1;//关闭复位//----------------Start Initial Sequence(时序)-------////------程序初始化设置,具体命令可以看文件夹下---////--软件初始化--//LcdSt7565_WriteCmd(0xE2);  //软件复位:resetfor (i=0; i<100; i++);	   //延时一下//--表格第8个命令,0xA0段(左右)方向选择正常方向(0xA1为反方向)--//// 0xA0对应0-127,0xA1对应4-131LcdSt7565_WriteCmd(0xA0);  //ADC select segment direction //--表格第15个命令,0xC8普通(上下)方向选择选择反向,0xC0为正常方向--// LcdSt7565_WriteCmd(0xC8);  //Common direction //--表格第9个命令,0xA6为设置字体为黑色,背景为白色---////--0xA7为设置字体为白色,背景为黑色---//LcdSt7565_WriteCmd(0xA6);  //reverse display//--表格第10个命令,0xA4像素正常显示,0xA5像素全开--//LcdSt7565_WriteCmd(0xA4);  //normal display//--表格第11个命令,0xA3偏压为1/7,0xA2偏压为1/9--//LcdSt7565_WriteCmd(0xA2);  //bias set 1/9//--表格第19个命令,这个是个双字节的命令,0xF800选择增压为4X;--////--0xF801,选择增压为5X,其实效果差不多--//	LcdSt7565_WriteCmd(0xF8);  //Boost ratio setLcdSt7565_WriteCmd(0x01);  //x4//--表格第18个命令,这个是个双字节命令,高字节为0X81,低字节可以--////--选择从0x00到0X3F。用来设置背景光对比度。---/LcdSt7565_WriteCmd(0x81);  //V0 a setLcdSt7565_WriteCmd(0x23);//--表格第17个命令,选择调节电阻率--//LcdSt7565_WriteCmd(0x25);  //Ra/Rb set//--表格第16个命令,电源设置。--//LcdSt7565_WriteCmd(0x2F);for (i=0; i<100; i++);//--表格第2个命令,设置显示开始位置--//LcdSt7565_WriteCmd(0x40);  //start line//--表格第1个命令,开启显示--//LcdSt7565_WriteCmd(0xAF);  // display onfor (i=0; i<100; i++);}

9.清屏操作

/*******************************************************************************
* 函 数 名         : LCD12864_ClearScreen
* 函数功能		   : 清屏12864
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/void Lcd12864_ClearScreen(void)
{uchar i, j;for(i=0; i<8; i++)//行--64行分为8页【8个bit位容易操作】{//--表格第3个命令,设置Y的坐标--////--Y轴有64个,一个坐标8位,也就是有8个坐标--////所以一般我们使用的也就是从0xB0到0x07【设置页地址0xB0+(0-7)】,就够了--//	LcdSt7565_WriteCmd(0xB0+i); //--表格第4个命令,设置X坐标--////--当你的段初始化为0xA1时【4-131】,X坐标从0x10,0x04到0x18,0x04,一共128位--////--当你的段初始化为0xA0时【0-127】,X坐标从0x10,0x00到0x18,0x00,一共128位--////--在写入数据之后X坐标的坐标是会自动加1的,我们初始化使用0xA1所以--////--我们的X坐标从0x10,0x00开始---//LcdSt7565_WriteCmd(0x10); LcdSt7565_WriteCmd(0x00);							   //--X轴有128位,就一共刷128次,X坐标会自动加1,所以我们不用再设置坐标--//for(j=0; j<128; j++){LcdSt7565_WriteData(0x00);  //如果设置背景为白色时,清屏选择0XFF}}
}

扩展

此时我们设置白背景,黑字

所以0x00显示白字,0xff显示黑字

下面我们设置0xf0【则在一页中,上面四行显示黑色,下面四行显示白色】

//--X轴有128位,就一共刷128次,X坐标会自动加1,所以我们不用再设置坐标--//for(j=0; j<128; j++){LcdSt7565_WriteData(0xf0);  //如果设置背景为白色时,清屏选择0XFF}

10.LCD12864显示文字

1.文字显示的原理

(1)字模

(2)像素&显存的对应关系:一一对应

(3)显示函数:将字模丢到正确的显存中去

2.字模的获取

(1)芯片自带字库

(2)网上下载字库

(3)字模生成软件自助生成

3.代码实战显示6*8ASCII码

1.先弄初始化函数和清屏函数

main.c
#include"st7565.h"void main(){Lcd12864_Init();Lcd12864_ClearScreen();while(1);
}
st7565.c
#include "st7565p.h"/*******************************************************************************
* 函 数 名         : LCD12864_WriteCmd
* 函数功能		   : 写入一个命令到12864
* 输    入         : cmd
* 输    出         : 无
*******************************************************************************/void LcdSt7565_WriteCmd(cmd)
{LCD12864_CS = 0;	   //chip select,打开片选LCD12864_RD = 1;	   //disable read,读失能	LCD12864_RS = 0;       //select command,选择命令LCD12864_RW = 0;       //select write,选择写模式_nop_();_nop_();DATA_PORT = cmd; //put command,放置命令_nop_();_nop_();LCD12864_RW = 1;	   //command writing ,写入命令
}/*******************************************************************************
* 函 数 名         : LcdSt7565_WriteData
* 函数功能		   : 写入一个数据到12864
* 输    入         : dat
* 输    出         : 无
*******************************************************************************/void LcdSt7565_WriteData(dat)
{	LCD12864_CS = 0;	   //chip select,打开片选LCD12864_RD = 1;	   //disable read,读失能	LCD12864_RS = 1;       //select data,选择数据LCD12864_RW = 0;       //select write,选择写模式_nop_();_nop_();DATA_PORT = dat;       //put data,放置数据_nop_();_nop_();LCD12864_RW = 1;	   //data writing,写数据 
}
/*******************************************************************************
* 函 数 名         : LCD12864_Init
* 函数功能		   : 初始化12864
* 输    入         : 无
* 输    出         : 无
* 说    明         : LCD12864的命令指令可以查看例程文件夹下的《ST7565p数据手册》
*                  * 的第51页的位置。
*******************************************************************************/void Lcd12864_Init()
{uchar i;LCD12864_RSET = 0;//硬件复位for (i=0; i<100; i++);//让内部进行复位LCD12864_CS = 0;//打开片选,选中芯片LCD12864_RSET = 1;//关闭复位//----------------Start Initial Sequence(时序)-------////------程序初始化设置,具体命令可以看文件夹下---////--软件初始化--//LcdSt7565_WriteCmd(0xE2);  //软件复位:resetfor (i=0; i<100; i++);	   //延时一下//--表格第8个命令,0xA0段(左右)方向选择正常方向(0xA1为反方向)--//// 0xA0对应0-127,0xA1对应4-131LcdSt7565_WriteCmd(0xA0);  //ADC select segment direction //--表格第15个命令,0xC8普通(上下)方向选择选择反向,0xC0为正常方向--// LcdSt7565_WriteCmd(0xC8);  //Common direction //--表格第9个命令,0xA6为设置字体为黑色,背景为白色---////--0xA7为设置字体为白色,背景为黑色---//LcdSt7565_WriteCmd(0xA6);  //reverse display//--表格第10个命令,0xA4像素正常显示,0xA5像素全开--//LcdSt7565_WriteCmd(0xA4);  //normal display//--表格第11个命令,0xA3偏压为1/7,0xA2偏压为1/9--//LcdSt7565_WriteCmd(0xA2);  //bias set 1/9//--表格第19个命令,这个是个双字节的命令,0xF800选择增压为4X;--////--0xF801,选择增压为5X,其实效果差不多--//	LcdSt7565_WriteCmd(0xF8);  //Boost ratio setLcdSt7565_WriteCmd(0x01);  //x4//--表格第18个命令,这个是个双字节命令,高字节为0X81,低字节可以--////--选择从0x00到0X3F。用来设置背景光对比度。---/LcdSt7565_WriteCmd(0x81);  //V0 a setLcdSt7565_WriteCmd(0x23);//--表格第17个命令,选择调节电阻率--//LcdSt7565_WriteCmd(0x25);  //Ra/Rb set//--表格第16个命令,电源设置。--//LcdSt7565_WriteCmd(0x2F);for (i=0; i<100; i++);//--表格第2个命令,设置显示开始位置--//LcdSt7565_WriteCmd(0x40);  //start line//--表格第1个命令,开启显示--//LcdSt7565_WriteCmd(0xAF);  // display onfor (i=0; i<100; i++);}/*******************************************************************************
* 函 数 名         : LCD12864_ClearScreen
* 函数功能		   : 清屏12864
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/void Lcd12864_ClearScreen(void)
{uchar i, j;for(i=0; i<8; i++)//行--64行分为8页【8个bit位容易操作】{//--表格第3个命令,设置Y的坐标--////--Y轴有64个,一个坐标8位,也就是有8个坐标--////所以一般我们使用的也就是从0xB0到0x07【设置页地址0xB0+(0-7)】,就够了--//	LcdSt7565_WriteCmd(0xB0+i); //--表格第4个命令,设置X坐标--////--当你的段初始化为0xA1时【4-131】,X坐标从0x10,0x04到0x18,0x04,一共128位--////--当你的段初始化为0xA0时【0-127】,X坐标从0x10,0x00到0x18,0x00,一共128位--////--在写入数据之后X坐标的坐标是会自动加1的,我们初始化使用0xA1所以--////--我们的X坐标从0x10,0x00开始---//LcdSt7565_WriteCmd(0x10); LcdSt7565_WriteCmd(0x00);							   //--X轴有128位,就一共刷128次,X坐标会自动加1,所以我们不用再设置坐标--//for(j=0; j<128; j++){LcdSt7565_WriteData(0x00);  //如果设置背景为白色时,清屏选择0XFF}}
}
st7565.h
#ifndef __ST7565_H
#define __ST7565_H#include<reg51.h>
#include<intrins.h>//---重定义关键词---//
#ifndef uchar
#define uchar unsigned char
#endif#ifndef uint 
#define uint unsigned int
#endif//--定时使用的IO口--//
#define DATA_PORT 	P0
sbit LCD12864_CS   	= P3^2;
sbit LCD12864_RSET 	= P3^3;
sbit LCD12864_RS   	= P2^6;
sbit LCD12864_RW   	= P2^7;
sbit LCD12864_RD   	= P2^5;//--定义全局函数--//
void LcdSt7565_WriteCmd(cmd);
void LcdSt7565_WriteData(dat);
void Lcd12864_Init();
void Lcd12864_ClearScreen(void);#endif

2.网上找到6*8ASCII码字库

nios ii 之5110液晶屏(6*8、8*16 ASCII字符,16*16 汉字,常用图标,图案,超全字库+函数代码)_6*8 ascii-CSDN博客

3.编写函数显示数值

我们在编写下面代码遇到的问题:

1)我们需要将模取高位和低位的时候需要分别使用一个变量组装起来

2)字库中对应的ASCII是十六进制,记得加上0x

3)当我们遇到问题的时候一个模块一个模块的检验

//在屏幕的(x,y)坐标处,显示c这个字符
//(x,y)表示像素点的坐标值,所以x范围是0-127,y的范围是0-63
//注意,因为显示文字是以整页为单位的,为了简单起见必须页对齐显示
//因此给的y值必须页首地址,就是0 8 16 24 等数值
void ascii_display(unsigned char x,unsigned char y,unsigned char c){unsigned char i=0;unsigned char x1,x2;//【第一步,设置显示的x和y坐标】//y坐标,其实就是page addressLcdst7565_WriteCmd(0xB0+y/8);//因为只能整页显示,所以我们要除8才能保证//x坐标,只要在范围内别超出就可以了x1=(x>>4) & 0x0f;   //显示高4位x2=x& 0x0f;    //显示低4位//因为我们要使用2次发送才可以将数据发出Lcdst5765_Write_Cmd(0x10+x1);Lcdst7565_Write_Cmd(0x00+x2);//【第二步,找到c对应的字模】//ASCII_6_8[x-20][0]      字模的第一个字节//【第三步,将字模丢到显存中去】for(i=0;i<6;i++){//因为我们字库是从“20”开始,所以要-20//注意点:我们是十六进制,所以是0x20Lcdst7565_Write_Cmd(ASCII_6_8[c-0x20][i]);}
遗留问题:

(1)初始化和字模不匹配,造成字是反的

(2)初始化不对,造成x坐标是从右往左的

4.解决遗留问题

1.修改初始化代码从左往右显示

(1)先修改初始化函数中的显示方向代码

	//--表格第8个命令,0xA0段(左右)方向选择正常方向(0xA1为反方向)--//// 0xA0对应0-127,0xA1对应4-131LcdSt7565_WriteCmd(0xA0);  //ADC select segment direction 

(2)修改清屏函数

		//--表格第4个命令,设置X坐标--////--当你的段初始化为0xA1时【4-131】,X坐标从0x10,0x04到0x18,0x04,一共128位--////--当你的段初始化为0xA0时【0-127】,X坐标从0x10,0x00到0x18,0x00,一共128位--////--在写入数据之后X坐标的坐标是会自动加1的,我们初始化使用0xA1所以--////--我们的X坐标从0x10,0x00开始---//LcdSt7565_WriteCmd(0x10); LcdSt7565_WriteCmd(0x00);

(3)修改显示数值的函数

4.显示跨页(16*16)

(1)超过8*8的字符如何显示

(2)常见汉字字模大小是16*16

zimo.h

#ifndef __ZIMO_H__
#define __ZIMO_H__unsigned char code zimo_zhu[] = 
{0x80,0xA0,0x90,0x8E,0x88,0x88,0x88,0xFF,0x88,0x88,0x88,0x88,0x88,0x80,0x80,0x00,
0x20,0x20,0x10,0x08,0x04,0x02,0x01,0xFF,0x01,0x02,0x04,0x08,0x10,0x20,0x20,0x00,};unsigned char code zimo_you[] = 
{0x04,0x04,0x04,0x84,0xE4,0x3C,0x27,0x24,0x24,0x24,0x24,0xE4,0x04,0x04,0x04,0x00,
0x04,0x02,0x01,0x00,0xFF,0x09,0x09,0x09,0x09,0x49,0x89,0x7F,0x00,0x00,0x00,0x00,};unsigned char code zimo_peng[] = 
{0x00,0xFE,0x22,0xFE,0x00,0xFE,0x22,0xFE,0x00,0xFC,0x16,0x25,0x84,0xFC,0x00,0x00,
0x60,0x1F,0x22,0xBF,0x40,0x3F,0x82,0xFF,0x00,0x13,0x12,0x12,0x52,0x82,0x7E,0x00,};#endif

自定义数值输出

void hanzi_display(unsigned char x,unsigned char y,unsigned char zimo[]){unsigned char i=0;unsigned char x1,x2;//先显示上面一半Lcdst7565_WriteCmd(0xB0+y/8);//x坐标,只要在范围内别超出即可x1=(x>>4)&0x0f;x2=x&0x0f;Lcdst7565_Write(0x10+x1);Lcdst7565_Write(0x00+x2);for(i=0;i<16;i++){  //因为我们是16*16,此时是显示第一页的0-15列Lcdst7565_WriteData(zimo[i]);}//在显示下面一半Lcdst7565_WriteCmd(0xB0+y/8+1);//x坐标,只要在范围内别超出即可x1=(x>>4)&0x0f;x2=x&0x0f;Lcdst7565_Write(0x10+x1);Lcdst7565_Write(0x00+x2);for(i=16;i<32;i++){Lcdst7565_WriteData(zimo[i]);}
}
    hanzi_display(0, 0, zimo_zhu);hanzi_display(16, 0, zimo_you);hanzi_display(32, 0, zimo_peng);

 

使用简单的方式

#ifndef __ZIMO_H__
#define __ZIMO_H__unsigned char code zimo_zhuyoupeng[3][32] = 
{
// 朱
{0x80,0xA0,0x90,0x8E,0x88,0x88,0x88,0xFF,0x88,0x88,0x88,0x88,0x88,0x80,0x80,0x00,
0x20,0x20,0x10,0x08,0x04,0x02,0x01,0xFF,0x01,0x02,0x04,0x08,0x10,0x20,0x20,0x00,},
// 有
{0x04,0x04,0x04,0x84,0xE4,0x3C,0x27,0x24,0x24,0x24,0x24,0xE4,0x04,0x04,0x04,0x00,
0x04,0x02,0x01,0x00,0xFF,0x09,0x09,0x09,0x09,0x49,0x89,0x7F,0x00,0x00,0x00,0x00,},
// 鹏
{0x00,0xFE,0x22,0xFE,0x00,0xFE,0x22,0xFE,0x00,0xFC,0x16,0x25,0x84,0xFC,0x00,0x00,
0x60,0x1F,0x22,0xBF,0x40,0x3F,0x82,0xFF,0x00,0x13,0x12,0x12,0x52,0x82,0x7E,0x00,},
};#endif
hanzi_display(16*0, 16, zimo_zhuyoupeng[0]);hanzi_display(16*1, 16, zimo_zhuyoupeng[1]);hanzi_display(16*2, 16, zimo_zhuyoupeng[2]);

11.LCD12864显示图片

1.思路分析

通过取字模软件将图片翻译为一个十六进制的数组

2.图片数据获取

1)取模软件,转换为bmp

2)查看像素

3)调节分辨率---》画图工具

3.写显示函数

// 在屏幕上显示一个图片,从屏幕左上角开始显示
//因为是整个屏幕显示,所以跟清屏函数差不多
void pic_display(unsigned char pic[])
{uchar i, j;uint k = 0;//遍历数组,128*64/8=1024for(i=0; i<8; i++)//每一个page{	LcdSt7565_WriteCmd(0xB0+i); //y轴LcdSt7565_WriteCmd(0x10); //高4位LcdSt7565_WriteCmd(0x00);//低4位							   //--X轴有128位,就一共刷128次,X坐标会自动加1,所以我们不用再设置坐标--//for(j=0; j<128; j++){LcdSt7565_WriteData(pic[k++]);  //如果设置背景为白色时,清屏选择0XFF}}
}

4.调试

pic_display(pic);

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【分布式计算】二、架构 Architectures

1.中心化架构&#xff08;Centralized Architectures&#xff09; 1.1.经典C/S模型 服务器&#xff1a;一个或多个进程提供服务 客户端&#xff1a;一个或多个进程使用服务 客户端和服务器可以在不同的机器上 客户端遵循请求/回复模型 1.2.传统三层视图 用户界面层&#x…

JUC中的设计模式

文章目录 1. 终止模式之两阶段终止模式 1. 终止模式之两阶段终止模式 需求&#xff1a;用一个线程每两秒检测***状态&#xff0c;当不想检测时&#xff0c;用另一个线程将其停止 在一个线程 T1 中如何“优雅”终止线程 T2&#xff1f;这里的【优雅】指的是给 T2 一个料理后事…

910数据结构(2019年真题)

算法设计题 问题1 有一种排序算法叫做计数排序。这种排序算法对一个待排序的表&#xff08;采用顺序存储&#xff09;进行排序&#xff0c;并将排序结果存放到另一个新的表中。必须注意的是&#xff0c;表中所有待排序的关键字互不相同&#xff0c;计数排序算法针对表中的每个…

【AI处理器组合】python实现-附ChatGPT解析

1.题目 AI处理器组合 知识点数组 时间限制:1s 空间限制: 256MB 限定语言:不限 题目描述: 某公司研发了一款高性能AI处理器。每台物理设备具备8颗AI处理器,编号分别为0、1、2、3、4、5、6、7。编号0-3的处理器处于同一个链路中,编号4-7的处理器处于另外一个链路中,不通链路中…

10.03

代码 #include <iostream>using namespace std; class cz { private:int num1; //实部int num2; //虚部 public:cz(){}cz(int a,int b):num1(a),num2(b){}cz(const cz &other):num1(other.num1),num2(other.num2){}~cz(){}const cz operator(const cz &othe…

HTML5 跨屏前端框架 Amaze UI

Amaze UI采用国际最前沿的“组件式开发”以及“移动优先”的设计理念&#xff0c;基于其丰富的组件&#xff0c;开发者可通过简单拼装即可快速构建出HTML5网页应用&#xff0c;上线仅半年&#xff0c;Amaze UI就成为了国内最流行的前端框架&#xff0c;目前在Github上收获Star数…

Java开源工具库使用之Lombok

文章目录 前言一、常用注解1.1 AllArgsConstructor/NoArgsConstructor/RequiredArgsConstructor1.2 Builder1.3 Data1.4 EqualsAndHashCode1.5 Getter/Setter1.6 Slf4j/Log4j/Log4j2/Log1.7 ToString 二、踩坑2.1 Getter/Setter 方法名不一样2.2 Builder 不会生成无参构造方法2…

互联网Java工程师面试题·ZooKeeper 篇·第一弹

目录 1. ZooKeeper 面试题&#xff1f; 2. ZooKeeper 提供了什么&#xff1f; 3. Zookeeper 文件系统 4. ZAB 协议&#xff1f; 5. 四种类型的数据节点 Znode 6. Zookeeper Watcher 机制 -- 数据变更通知 7. 客户端注册 Watcher 实现 8. 服务端处理 Watcher 实现 9. 客…

第10章 MySQL(一)

10.1 谈谈MySQL的架构 难度:★★ 重点:★ 白话解析 要想彻底的理解MySQL,它的架构一定要先弄清楚,当Java程序员通过JDBC或者Mybatis去执行一条SQL的时候,到底经历了什么。下边先看一幅图: 户端:Java程序员通过JDBC或者Mybatis去拿MySQL的驱动程序,实际上就是拿客户端。…

oracle分组合并数值带顺序

比如&#xff1a;有如下一张设备电子围栏位置坐标的表&#xff08;tb_equ_point&#xff09;。 equ_name:设备电子围栏名称 point_id:点位坐标id point_x:点位x坐标 point_y:点位y坐标。 附数据&#xff1a; INSERT INTO "tb_equ_point" ("EQU_NAME",…

Linux系统编程基础:进程控制

文章目录 一.子进程的创建操作系统内核视角下的父子进程存在形式验证子进程对父进程数据的写时拷贝 二.进程等待进程非阻塞等待示例: 三.进程替换内核视角下的进程替换过程:综合利用进程控制系统接口实现简单的shell进程 进程控制主要分为三个方面,分别是:子进程的创建,进程等待…

html 边缘融合加载

html 代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>边缘融合加载</title><style>* {margin: 0;padding: 0;box-sizing: border-box;}body {height: 100vh;padding-bottom: 80px;b…

【Java每日一题】— —第二十题:杨辉三角(直角三角形)。(2023.10.04)

&#x1f578;️Hollow&#xff0c;各位小伙伴&#xff0c;今天我们要做的是第二十题。 &#x1f3af;问题&#xff1a; 杨辉三角&#xff08;直角三角形&#xff09;。 解法1 第一步:动态初始化 第二步:为主对角线及第一列的元素赋值1 第三…

用于工业物联网和自动化的 Apache Kafka、KSQL 和 Apache PLC4

由于单一系统和专有协议&#xff0c;数据集成和处理是工业物联网&#xff08;IIoT&#xff0c;又名工业 4.0 或自动化工业&#xff09;中的巨大挑战。Apache Kafka、其生态系统&#xff08;Kafka Connect、KSQL&#xff09;和 Apache PLC4X 是以可扩展、可靠和灵活的方式实现端…

【数据科学】Scikit-learn[Scikit-learn、加载数据、训练集与测试集数据、创建模型、模型拟合、拟合数据与模型、评估模型性能、模型调整]

这里写目录标题 一、Scikit-learn二、加载数据三、训练集与测试集数据四、创建模型4.1 有监督学习评估器4.1.1 线性回归4.1.2 支持向量机(SVM)4.1.3 朴素贝叶斯4.1.4 KNN 4.2 无监督学习评估器4.2.1 主成分分析(PCA)4.2.2 K Means 五、模型拟合5.1 有监督学习5.2 无监督学习 六…

行高的继承和消除内外边距

行高的继承性 <style>div {font: 12px/1.5 Microsoft yahei;} ​p {font-size: 14px;}</style> <body><div><p>苏丹红事件</p></div> <body> 12px这里没有行高没有写单位&#xff0c;子类继承父类的1.5倍&#xff0c;就是14*…

毅速3D打印:深骨位零件制造首选3D打印

在模具制造领域&#xff0c;深骨位零件由于其复杂形状和结构&#xff0c;传统的加工方法往往难以满足生产要求&#xff0c;导致产品不良问题频繁出现。而如今&#xff0c;随着3D打印技术的普及&#xff0c;深骨位零件在3D打印面前变得不再困难。 3D打印是一种快速成型技术&…

王杰国庆作业day6

服务器 #include <stdio.h> #include <string.h> #include <stdlib.h> #include <my_head.h> #define PORT 2324 //端口号 #define IP "192.168.10.107" //本机IP int main(int argc, const char *argv[]) {sqlite3* d…

C++标准模板(STL)- 类型支持 ()

对象、引用、函数&#xff08;包括函数模板特化&#xff09;和表达式具有称为类型的性质&#xff0c;它限制了对这些实体所容许的操作&#xff0c;并给原本寻常的位序列提供了语义含义。 附加性基本类型及宏 实现定义的空指针常量 NULL 定义于头文件 <clocale> 定义于…

linux——信号

✅<1>主页&#xff1a;&#xff1a;我的代码爱吃辣 &#x1f4c3;<2>知识讲解&#xff1a;Linux——进程等待 ☂️<3>开发环境&#xff1a;Centos7 &#x1f4ac;<4>前言&#xff1a;生活中处处有信号&#xff0c;linux中也有很多信号&#xff0c;OS使…