5_1_2_首页信息展示屏_OLED 开发与体验|学习笔记

简介: 快速学习5_1_2_首页信息展示屏_OLED 开发与体验。

开发者学堂课程【HaaS 物联网应用开发课程5_1_2_首页信息展示屏_OLED 开发与体验】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址:https://developer.aliyun.com/learning/course/801/detail/13843


5_1_2_首页信息展示屏_OLED 开发与体验

 

内容介绍:

一、OLED开 发与体验

1.OLED 显示屏

2. OLED 硬件

3.OLED 扫描模式

4.SH1106扫描方式

5.SH1106刷新整个屏幕的 sample code

6.SH1106画点原理

7.SH1106画点代码

8.SH1106驱动代码路径:

9. HaaS EDU K1 homepage 页面的代码

 

一、OLED 开发与体验

1.OLED 显示屏

OLED ( Organic Light-Emitting Diode )有机电激光显示

也称为有机发光半导体,属于一种电流型的有机发光器件,是通过载流子的注入和复合而致发光的现象,发光强度与注入的电流成正比。

image.png

如图所示,上面阳极,下面是金属阴极,阳极表面会形成空穴传输层,阴极表面会形成电子传输层,通电之后,OLED在电场的作用下,阳极产生的空穴和阴极产生的电子就会发生移动,分别向空穴传输层和电子传输层注入,迁移到发光层。当二者在发光层相遇时,产生能量激子,从而激发发光分子最终产生可见光。

OLED 屏幕上有些区域变亮,有些区域不亮就形成我们所看到的图案。

2. OLED 硬件

HaaS EDU K1内置了一块单色 OLED 屏

驱动芯片

SH1106

使用接口

SPI

分辨率

132×64

显示尺寸

0.96寸

显示颜色

白色

工作电压

3.3V/ 5V

OLED 屏幕的驱动芯片是 SH1106

SH1106和 HaaS1000主芯片之间是通过 SPIO 接口进行通信

image.png

上图是 SH1106和 HaaS1000主芯片的电路连线图,除了 OLED 模块的最小电路之外,和 HaaS1000的连线有四根,分别是 RES、D/C、SCLKSDIN 

器件引脚

引脚功能

对应原理图引脚名

RES

data/cmd

OLED_RST

D/C

此引脚拉高时传输数据,拉低时传输指令

SPI_DIO

SCLK

数据时钟

SPIO_CLK

SDIN

接收串行数据

SPIO_DIO

一个 SPI 接口一般有4根引脚:

主设备输出(MOSI/Master Out Slave In)

主设备输入(MISO/ Master In Slave Out)

数据时钟(SCLK)

片选(CS / Chip Select)

image.png

一条 spi 总线上面支持一个主设备和多个从设备,主设备是怎样决定当前 spi 通信是和哪个设备进行通信的?是通过CS 片选信号进行选择,在 SPI 传输之前会先将从设备的 SPI 设置成有效状态,对应的从设备便知道接下来的 SPI 通信是自己要参与的,又因为在原理图当中,OLED 对应的 CS 引脚是直接经过一个十倍的电阻连接到地上的,这是因为在设计过程中,将 SPI0作为专门控制 OLED 的通道,因此又可以省掉一根 CS 引脚。

SH1106上面的 D/C 引脚是 Data、Command 控制信号的意思。引脚拉高时,SPI 的 MOSI 上的数据代表的是实际的数据信息,D/C 引脚拉低时,MOSI 上传输的信息是控制指令,SCLK 就是S PI 的时钟信号,SDIN 就是 MOSI 的引脚。

3.OLED 扫描模式

接下来讲述 OLED 显示数据的模式。前面说到 OLED 的屏幕分辨率是132乘64,每个像素点占用数据的一个 bit,一般的数据传输是以字节(byte)为单位进行传输的。

也就是说传输一个字节的数据可以控制8个像素点的量,在收到一个 bit 之后,OLED 屏幕可以先刷新一行或一列,按照刷新模式的不同,OLED 共有四种刷新模式:第一种是逐行扫描,在这种模式下面,收到第一个 byte 之后,会先刷新第一行的前八个像素接下来第二个 byte 刷新第一行的第9到第16个像素收到后面的数据,以此类推,先把第一行的所有像素刷新完成之后再一次刷新第二行、第三行,直到刷新完整个屏幕。

image.png

第二种是逐列式,收到第一个 byte 之后它会先把第一列的前八个像素点刷新上去然后再收到第二 个byte,则会把第一列的第9到第16个像素点刷新上去收到后面的数据则以此类推先把第一列的所有像素更新完,然后再更新第二列,直到把整个屏幕都更新完成。

第三种是行列式,行列式是收到第一个 byte 之后,先刷新第一行的前八个像素点然后收到第二个 byte,刷新第二行的前八个像素点以此类推,刷新第三行的前八个像素点,把第N行的前八个像素点全刷新,完成之后才刷新第一行的第九到第16个 byte,第二行的第九到第16个呗。然后以此类推,把整个屏幕都刷新完成

image.png

最后一种就是列行式。列行式是在收到第一个 byte 之后,先刷新第一列的前八个像素,然后接下来的第二个 byte 刷新第二列前八个像素。

之后以此类推,在刷新完所有列的前八个像素之后,再从第一列的第九到第16个像素开始刷新,直到刷新完整个屏幕

4.SH1106扫描方式

image.png

在它的 data sheet 当中提到屏幕从上到下,共8个 page;屏幕从左到右,共 O0H-83H , 132列;每个 page 中的每—列都是一个完整的 Byte (下一页),刷新时会逐个配置进行刷新,也就是先刷新 page0的第一列,再刷新第二列,一直刷新到第132列再刷新 page1的第一列第二列,直到最后把 page7的132列全刷新完成。按照上一个知识点的定义,我们可以看到 SH1106采用的是列行式的刷新方式。

在代码中用一个二维数组代表整个屏幕的所有数据信息,数组为:

uint8_t OLED_GRAM[8][132];它可以代表// 8bit*132列*8页

下图为 data sheet 中描述的填充数据的标准操作流程:

image.png

通过设置 Page 地址和 Column 地址,我们可以确定整个 RAM 中的唯一一处 Byte。每个 Page 包含了8行*132列,而每输入一个 Byte,其实是纵向填充每页中的一列。例如,Byte1的位置对应了 Page 0的 Column 1。

每个显示数据读/写命令都会使指定的 Column 地址递增(+1)。这样可以连续访问 MPU 显示数据。由于列地址与页面地址无关。因此,例如,当从页面0列83H,移至页面1列00H 时,必须重新指定页面地址和列地址。

通过持续写入数据和变换页地址,我们就能够将整个屏幕填充为我们想要的图像。

设置 Page 地址及 Column 地址的指令

image.png

其中,列地址的高四个 byte 和低四个 byte 需要分别用两条指令来进行设定,配置地址则可以通过一条指令设定完成。比如说,要向 page1的第0列写入一个数据的时,则需要一次发送(0XB10X100X00给 SH1006。

5.SH1106刷新整个屏幕的 sample code

根据前面的描述,如果要画一个点到屏幕上,只需要将对应像素点所在字节中的正确的 bit 进行修改,然后将OLED_GRAM 整个结构体的数据刷新到屏幕上。

下面是刷新屏幕的三步 code:

uint8_t OLED_GRAM[8] [132];         l / 8bit*132列*8页

void OLED_Refresh_GRAM( void)

{

uint8_t i,j;

for (i = 0; i < 8; i++)

{

/*设置显示的起始地址*/

write_command ( 0xB0 + i);            //设置页地址(行)

write_command ( 0x00 ) ;             //设置列地址的低四位

write_command (0x10);               /设置列地址的高四位

write_data_page(OLED_GRAM [i],132);

}

因为 SH1106是列行式的刷新模式,所以在写入数据的时,需要先设定操作的行数然后依次写入132个 byte,就可以将配置地址为 i 的这一整行都进行刷新,然后循环八次就可以把 page0到 page7整个屏幕刷新一遍。

6.SH1106画点原理

由于前面实现了向 OLED 填充整个帧的方法,因此我们所有的操作只需要在 OLED_GRAM 上进行即可。

计算像素点三元素:Page 地址Column 地址当前位置的数据( byte )

image.png

设屏幕的左上角为原点,对于一个像素点( x,y ),可以知道:

Page 地址: y/8     Column 地址:x

目标 Byte:在原有数据的基础上进行 bit 与、或及异或操作

计算 bit 的偏移量: bit_offset = y%8

进行位操作

将某个比特置0熄灭像素): byte &= ~(0x01 << bit_offset) 

将某个比特置1(点亮像素): byte |=(0x01<< bit_offset)

将某个比特置反(翻转像素):byte ^ =(0x01 << bit_offset)

7.SH1106画点代码

void OLED_DrawPoint(int16_t x, int16_t y, uint8_t mode)

{

if ((x > (131)) (y > 63)lx <0 ly < 0)

return;              //如果坐标超出范围则不显示

uint8_t page = y / 8;   //计算页数例如像素点(7,13)则 page = 13/8 = 1该像素点所在位置为 PAGE1的第7列

uint8_t bit_offset = y % 8;  //计算像素点 bit 在对应 Byte 中的偏移例如像素点(7,13)则 bit_offset = 13%8 = 5 该像素点在该 PAGE 的第5行

uint8_t mask = 0x01 << bit_offset;   //生成一个像素点 例如像素点(7,13) 则 mask = 0b 0010 0000它正好遮罩了目标像素点

if (mode == 0)      // mode = 0时反显

OLED_GRAM[page] [x] &= ~mask;  //该像素点位置 置0

if (mode == 1)         // mode = 1 时正显

OLED_GRAM[page] [x] |= mask;     //该像素点位置 置1

1if (mode == 2)       // mode = 2时翻转

OLED_GRAM[page] [x] ^= mask;v       //该像素点位置翻转

}

有了最基本的像素绘制后,我们就可以进行各种图案的绘制。目前支持的绘画直线、矩形、圆形等多种方式,都是基于画点来实现。

8.SH1106驱动代码路径:

Application\example\edk_demo\sensors\oled\lsh1106.c

Application\example\edk_demo\sensors\oled\sh1106.h

Application\example\edk_demo\sensors\oled\font.h(写入字符的时候需要查询此表,此表提供了画圆、线、字符、字串等API)

void oLED_Refresh_GRAM(void) ;

void OLED_Clear(void);

void OLED_Full(void);

void OLED_DrawPoint(int16_t x,int16_t y,uint8_t mode);

void OLED_DrawLine(int16_t x0,int16_t y0,int16_t x1,int16_t y1,uint8_t mode);

void OLED_DrawVerticalLine(uint8_t x,uint8_t y,uint8_t length,uint8_t mode);

void OLED_DrawHorizontalLine(uint8_t x,uint8_t y,uint8_t length,uint8_t mode);

void OLED_DrawRect(uint8_t x,uint8_t y,uint8_t width,uint8_t height,uint8_t mode);

void OLED_FillRect(uint8_t xMove,uint8_t yMove,uint8_t width,uint8_t height,uint8_t mode);

void OLED_DrawCircle(uint8_t x0,uint8_t y0,uint8_t radius,uint8_t width,uint8_t mode);

void OLED_FillCircle(uint8_t x0,uint8_t y0,uint8_t r,uint8_t mode);

void OLED_Show_Char(uint8_t x,uint8_t y,uint8_t chr,uint8_t size,uint8_t mode);

void OLED_Show_String(uint8_t x,uint8_t y, const uint8_t *p,uint8_t size,uint8_t mode);

void OLED_Icon_Draw(int16_t x, int16_t y, icon_t *icon,uint8_t mode);

void OLED_test(int flag);

9. HaaS EDU K1 homepage 页面的代码

接下来讲述首页信息屏的部分代码:

application/example/edu_demo/k1_apps/homepage/homepage.c

void homepage_task(void)

{

unsigned char c = 0;

struct tm*info;

struct timespec tv;

uint8_t image_version[22];

uint8_t tmp[22];

netmgr_stats_t stats;

while (1)

{

OLED_Clear(;

/*获取GMT时间*/    清空屏幕

clock_gettime(CLOCK_REALTIME,&tv);

// printf("\r\n=====timespec is : %d===\r\n", tv);  获取系统时间

info = gmtime(&tv);

生成时间字串

snprintf(tmp,21,"%2d:%02d",(info->tm_hour) % 24, info--tmmin2Y;

OLED_Show_String(0,12* 0, tmp,12,1);  将时间字串显示在屏幕上

if (wifi_connected)

{

如果Wi-Fi连线成功  

OLED_Icon_Draw(86,0,&icon_wifi_on_12_12,0);    则将Wi-Fi图标显示在屏幕上行

}

相关文章
|
移动开发 前端开发
前端(十八):移动端H5调用摄像头拍照旋转解决方案
移动端H5调用摄像头拍照旋转解决方案
346 0
|
3月前
|
搜索推荐 前端开发 JavaScript
源码分享:HTML+CSS动画打造个性化登录页!
源码分享:HTML+CSS动画打造个性化登录页!
源码分享:HTML+CSS动画打造个性化登录页!
|
5月前
|
PHP
驾校在线考试系统源码 手机+PC+平板自适应
Thinkphp在线考题源码 驾校在线考试系统 手机+PC+平板 自适应,机动车驾驶培训学校驾校类网站源码带手机端 运行环境:php+mysql
180 11
驾校在线考试系统源码 手机+PC+平板自适应
|
4月前
|
小程序 定位技术 API
uniapp 开发微信小程序 --【地图】打开地图选择位置,打开地图显示位置(可开启导航)
uniapp 开发微信小程序 --【地图】打开地图选择位置,打开地图显示位置(可开启导航)
350 0
|
5月前
|
测试技术 PHP
大屏幕互动系统PHP源码 附动态背景图和配乐素材 含搭建教程
最新大屏幕互动系统PHP源码 附动态背景图和配乐素材 含搭建教程
56 0
|
6月前
|
vr&ar C# 图形学
【Unity 3D】VR飞机动态拆装及引擎开关控制案例(附源码和演示视频 超详细)
【Unity 3D】VR飞机动态拆装及引擎开关控制案例(附源码和演示视频 超详细)
108 0
|
移动开发 定位技术 API
手机端H5地图调起开发实战案例解析(百度高德腾讯地图调起、底部弹出层、提示安装地图导航APP)
手机端H5地图调起开发实战案例解析(百度高德腾讯地图调起、底部弹出层、提示安装地图导航APP)
555 0
|
小程序 JavaScript 前端开发
微信小程序 地图选点 获取用户选择的定位信息 wx.chooseLocation
微信小程序 地图选点 获取用户选择的定位信息 wx.chooseLocation
593 0
|
小程序 搜索推荐 定位技术
微信小程序插入个性化地图
微信小程序插入个性化地图
128 0
|
传感器 网络协议 物联网
5_1_1_首页信息展示屏_整体介绍_技术点及获取电池电量|学习笔记
快速学习5_1_1_首页信息展示屏_整体介绍_技术点及获取电池电量。
315 0
5_1_1_首页信息展示屏_整体介绍_技术点及获取电池电量|学习笔记
下一篇
无影云桌面