STM32F103-OLED使用教程

目录

  • 1. OLED屏介绍
  • 2. OLED如何显示一个点
  • 3. 配置OLED屏幕
  • 4. OLED显示字符串和汉字
  • 5. OLED屏幕显示图片
  • 6. 总结

1. OLED屏介绍

  • OLED(Organic Light Emitting Diode):有机发光二极管
  • OLED显示屏:性能优异的新型显示屏,具有功耗低、相应速度快、宽视角、轻薄柔韧等特点
    本文使用的是0.96寸OLED模块,小巧玲珑、占用接口少、简单易用,是电子设计中非常常见的显示屏模块。

OLED屏幕特点

供电:3~5.5V
通信协议:I2C/SPI
分辨率:128*64

OLED屏分两种,一种是4针OLED,通过IIC总线通信,另一种是7针OLED,通过SPI总线通信如下图所示:

本文使用的为4针OLED屏,接线说明如下:

在这里插入图片描述

OLED屏幕显存

在这里插入图片描述
OLED本身是没有显存的,他的现存是依赖SSD1306提供的,而SSD1306提供一块显存。
SSD1306显存总共为128*64bit大小,SSD1306将这些显存分成了8页。每页包含了128个字节。

OLED屏幕原理

STM32内部建立一个缓存(共128*8个字节),每次修改的时候,只是修改STM32上的缓存(实际上就是SRAM),修改完后一次性把STM32上的缓存数据写入到OLED的GRAM。这个方法也有坏处,对于SRAM很小的单片机(51系列)就比较麻烦。

OLED屏幕常用指令

在这里插入图片描述

  • 0X81: 设置对比度。包含两个字节,第一个0X81为命令,随后方法是的一个字节要设置这个对比度,值越大屏幕越亮。

  • 0XAE/0XAF: 0XAE为关闭显示命令,0XAF为开启显示命令。

  • 0X8D: 电荷泵设置,包含两个字节,第一个为命令字,第二个为设置值,第二个字节的BIT2表示电荷泵的开关状态,该位为1开启电荷泵,为0则关闭。模块初始化的时候,这个必须要开启,否则看不到屏幕显示。

  • 0XB0~B7:用于设置页地址,其低三位的值对应GRAM页地址。

  • 0X00~0X0F:用于设置显示时的起始列地址低四位。

  • 0X10~0X1F: 用于设置显示时的起始列地址高四位。

2. OLED如何显示一个点

OLED屏幕分为页寻址模式,水平地址模式,垂直地址模式。
本文主要介绍用的最多的页寻址模式,页寻址模式如下图:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

首先把整个OLED屏幕分成八页,也就是把OLED的屏幕把宽平均分成了八份。
比如,想在第3行第0列的开头显示一个点,那就是按位来配置,0000 1000(0x08)。

3. 配置OLED屏幕

我们配置硬件IIC的步骤就是根据下面这张时序图,发送一次数据后不断获取不同的应答即可。
在这里插入图片描述

硬件IIC配置:

#include "stm32f10x.h"
#include "oled.h"void IIC_Configuration(void)
{GPIO_InitTypeDef  GPIO_InitStructure;I2C_InitTypeDef   I2C_InitStructure;RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE	);RCC_APB1PeriphClockCmd( RCC_APB1Periph_I2C1, ENABLE	);//PB6--SCL   PB7--SDLGPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);I2C_DeInit(I2C1);I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;I2C_InitStructure.I2C_ClockSpeed = 400000;I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;I2C_InitStructure.I2C_OwnAddress1 = 0x30;I2C_Init(I2C1, &I2C_InitStructure);I2C_Cmd(I2C1, ENABLE);}void I2C_WriteByte(uint8_t addr,uint8_t data)
{while( I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)); //检查IIC总线是否繁忙I2C_GenerateSTART(I2C1, ENABLE);  //开启IIC,发送起始信号while(!I2C_CheckEvent(I2C1,  I2C_EVENT_MASTER_MODE_SELECT)); //EV5主模式I2C_Send7bitAddress(I2C1, OLED_ADDRESS ,  I2C_Direction_Transmitter);  //发送OLED地址while(!I2C_CheckEvent(I2C1,  I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); //检查EV6I2C_SendData(I2C1, addr); //发送寄存器地址while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTING));I2C_SendData(I2C1, data); //发送数据while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTING));I2C_GenerateSTOP(I2C1, ENABLE);
}

写命令函数&写数据函数:

void WriteCmd(unsigned char IIC_Command)  //写命令
{I2C_WriteByte(0x00,IIC_Command);
}void WriteDat(unsigned char IIC_Data)  //写数据
{I2C_WriteByte(0x40,IIC_Data);
}

OLED初始化:

void OLED_Init(void) //OELD屏幕初始化
{delay_ms(100);WriteCmd(0xAE); //display offWriteCmd(0x20);	//Set Memory Addressing Mode	WriteCmd(0x10);	//00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,InvalidWriteCmd(0xb0);	//Set Page Start Address for Page Addressing Mode,0-7WriteCmd(0xc8);	//Set COM Output Scan DirectionWriteCmd(0x00); //---set low column addressWriteCmd(0x10); //---set high column addressWriteCmd(0x40); //--set start line addressWriteCmd(0x81); //--set contrast control registerWriteCmd(0xff); //ÁÁ¶Èµ÷½Ú 0x00~0xffWriteCmd(0xa1); //--set segment re-map 0 to 127WriteCmd(0xa6); //--set normal displayWriteCmd(0xa8); //--set multiplex ratio(1 to 64)WriteCmd(0x3F); //WriteCmd(0xa4); //0xa4,Output follows RAM content;0xa5,Output ignores RAM contentWriteCmd(0xd3); //-set display offsetWriteCmd(0x00); //-not offsetWriteCmd(0xd5); //--set display clock divide ratio/oscillator frequencyWriteCmd(0xf0); //--set divide ratioWriteCmd(0xd9); //--set pre-charge periodWriteCmd(0x22); //WriteCmd(0xda); //--set com pins hardware configurationWriteCmd(0x12);WriteCmd(0xdb); //--set vcomhWriteCmd(0x20); //0x20,0.77xVccWriteCmd(0x8d); //--set DC-DC enableWriteCmd(0x14); //WriteCmd(0xaf); //--turn on oled panel
}

设置起点坐标:

void SetPos(unsigned char x,unsigned char y)  //设置起点坐标
{WriteCmd(0xb0+y);WriteCmd((x&0xf0)>>4|0x10); //取高位WriteCmd((x&0x0f)|0x01);    //取低位

全屏填充(可以全屏填充,也可用于清屏):

void OLED_Fill(unsigned char Fill_Data)  //全屏填充
{unsigned char m,n;for(m=0;m<8;m++){WriteCmd(0xb0+m);WriteCmd(0x00);WriteCmd(0x10);for(n=0;n<128;n++){WriteDat(Fill_Data);}}
}

清屏:

void OLED_Clean(void)  //清屏
{OLED_Fill(0x00);
}

打开/关闭OLED:

void OLED_ON(void)   //打开OLED
{WriteCmd(0X8D);   //设置电荷泵WriteCmd(0X14);   //开启电荷泵WriteCmd(0XAF);   //OLED唤醒
}void OLED_OFF(void)  //关闭OLED
{WriteCmd(0X8D);   //设置电荷泵WriteCmd(0X10);   //关闭电荷泵WriteCmd(0XAE);   //关闭OLED
}

4. OLED显示字符串和汉字

OLED显示字符串:

//显示字符串
void OLED_ShowStr(unsigned char x,unsigned char y,unsigned char ch[],unsigned TextSize)
{unsigned char c = 0,i = 0,j = 0;switch(TextSize){case 1:   //8*16模式{while(ch[j] != '\0'){c = ch[j] - 32;if(x>126){x= 0;y++;					}OLED_SetPos(x,y);for(i=0;i<6;i++)WriteDat( F6x8[c][i] );x+=6 ;j++;				}}break;case 2:    //16*16模式{while(ch[j] !='\0'){c= ch[j] - 32;if(x >120){x = 0;y++ ;}OLED_SetPos(x,y);for(i = 0;i<8;i++)WriteDat( F8X16[c*16+i] );OLED_SetPos(x,y+1);for(i = 0;i<8;i++)WriteDat( F8X16[c*16+i+8] );x+=8;j++;}	 }break;}
}	

OLED显示汉字:

//显示汉字 (x:横坐标  y:纵坐标  N:字数)
void OLED_ShowCN(unsigned char x,unsigned char y,unsigned char N)
{unsigned char wm=0;unsigned int addr = 32*N;OLED_SetPos(x,y);for(wm=0;wm<16;wm++){WriteDat( F16X16[addr]);addr +=1;	}OLED_SetPos(x,y+1);for(wm=0;wm<16;wm++){WriteDat( F16X16[addr]);addr +=1;	}}

然后通过取字模软件(PCtoLCD2002),输入我们想显示的汉字和大小,通过软件生成字库,再添加到我们代码中的字库文件里。

以我自己的工程为例,如下:
在这里插入图片描述

5. OLED屏幕显示图片

//显示图片
//x0:横坐标;y0:纵坐标;x1:图片起点;y1:所占页数;BMP[]:选用的结构体名称
void OLED_DrawBMP(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char BMP[])
{unsigned int j=0;unsigned char x,y;if(y1%8 == 0)y = y1/8;elsey = y1/8 +1;for(y=y0;y<y1;y++){OLED_SetPos(x0,y);for(x=x0;x<x1;x++){	WriteDat(BMP[j++]);}		}
}

步骤:

  1. 选一张照片,保存格式改为.png
  2. 将大小调整为跟我们的屏幕一样的分辨率(128*64)
  3. 改完大小之后再保存为BMP格式。
  4. 打开我们的取模软件(Image2Lcd v2.9),生成一个文档。
  5. 然后把数组里面的内容粘贴到BMP1的数组里面。

最终效果:在这里插入图片描述

6. 总结

本文使用的是4针OLED屏,是通过硬件IIC驱动,当然大家也可以通过软件IIC实现,使用引脚更加灵活。同时大家也可以使用7针的OLED屏,通过SPI进行驱动。
文献:https://blog.csdn.net/aaaaaaaa123345/article/details/124350330

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Jay17 2023.8.14日报 即 留校集训阶段性总结

8.14 打了moeCTF&#xff0c;还剩一题ak Web。 Jay17-集训结束阶段性总结&#xff1a; 集训产出&#xff1a; 自集训开始以来一个半月&#xff0c;最主要做的事情有三。 一是跟课程&#xff0c;复习学过的知识&#xff0c;学习新的知识&#xff1b;目前课程已大体听完&…

HTML+JavaScript构建一个将C/C++定义的ANSI字符串转换为MASM32定义的DWUniCode字符串的工具

公文一键排版系统基本完成&#xff0c;准备继续完善SysInfo&#xff0c;增加用户帐户信息&#xff0c;其中涉及到Win32_Account结构&#xff0c;其C定义如下&#xff1a; [Dynamic, Provider("CIMWin32"), UUID("{8502C4CC-5FBB-11D2-AAC1-006008C78BC7}"…

H13-922题库 HCIP-GaussDB-OLAP V1.5

**H13-922 V1.5 GaussDB(DWS) OLAP题库 华为认证GaussDB OLAP数据库高级工程师HCIP-GaussDB-OLAP V1.0自2019年10月18日起&#xff0c;正式在中国区发布。当前版本V1.5 考试前提&#xff1a; 掌握基本的数据库基础知识、掌握数据仓库运维的基础知识、掌握基本Linux运维知识、…

idea打jar包

目录 1、打包设置 2、打包介绍 3、开始打包 1、打包设置 先设置要打包的模块信息&#xff0c;即打包进去的内容。如下图所示&#xff1a;File --> Project Structure --> Artifacts&#xff0c;点击&#xff0b;号完成模块创建&#xff0c;其中有两种方式&#xff1a;…

SpringBoot整合、SpringBoot与异步任务

目录 一、背景描述二、简单使用方法三、原理五、使用自定义线程池1、默认使用2、如何使用自定义线程池 六、Async失效情况1、同一个类中&#xff0c;一个方法调用 Async标注的方法 一、背景描述 java 的代码是同步顺序执行&#xff0c;当我们需要执行异步操作时我们通常会去创…

Vue 批量注册组件

全局组件 在components文件夹下新建一个Gloabl文件夹&#xff08;可以自行命名&#xff09; 在目录下新建index.js import Vue from vue// require.context(路径, 是否遍历子目录, 匹配规则) const requireComponents require.context(./, true, /\.vue/)requireComponents.k…

【TypeScript】基础类型

安装 Node.js 环境 https://nodejs.org/en 终端中可以查到版本号即安装成功。 然后&#xff0c;终端执行npm i typescript -g安装 TypeScript 。 查到版本号即安装成功。 字符串类型 let str:string "Hello"; console.log(str);终端中先执行tsc --init&#xf…

uni-app 集成推送

研究了几天&#xff0c;终于是打通了uni-app的推送&#xff0c;本文主要针对的是App端的推送开发过程&#xff0c;分为在线推送和离线推送。我们使用uni-app官方推荐的uni-push2.0。官方文档 准备工作&#xff1a;开通uni-push功能 勾选uniPush2.0点击"配置"填写表单…

日常BUG——普通页面跳转tabbar页面报错

&#x1f61c;作 者&#xff1a;是江迪呀✒️本文关键词&#xff1a;日常BUG、BUG、问题分析☀️每日 一言 &#xff1a;存在错误说明你在进步&#xff01; 一、问题描述 微信小程序页面跳转的时候出现下面的问题&#xff1a; wx.redirectTo({url: /pages/index/i…

matlab使用教程(16)—图论中图的定义与修改

1.修改现有图的节点和边 此示例演示如何使用 addedge 、 rmedge 、 addnode 、 rmnode 、 findedge 、 findnode 及 subgraph 函数访问和修改 graph 或 digraph 对象中的节点和/或边。 1.1 添加节点 创建一个包含四个节点和四条边的图。s 和 t 中的对应元素用于指定每条…

SSL握手协议相关概念

下图为握手协议的流程图&#xff0c;具体的解释参考博客&#xff1a; 【下】安全HTTPS-全面详解对称加密&#xff0c;非对称加密&#xff0c;数字签名&#xff0c;数字证书和HTTPS_tenfyguo的博客-CSDN博客 下面梳理一下SSL协议中的一些细节。首先是相关名词&#xff1a;证书、…

SpringBoot中的可扩展接口

目录 # 背景 # 可扩展的接口启动调用顺序图 # ApplicationContextInitializer # BeanDefinitionRegistryPostProcessor # BeanFactoryPostProcessor # InstantiationAwareBeanPostProcessor # SmartInstantiationAwareBeanPostProcessor # BeanFactoryAware # Applicati…

npm install 中 --save 和 --save-dev 是什么?

npm&#xff0c;全名 Node Package Manager&#xff0c;套件管理工具&#xff0c;package.json 会记下你在项目中安装的所有套件。 假设在项目中安装 lodash npm i --save lodash这样在 dependencies 中会出现&#xff1a; 如果修改了导入方式&#xff1a; npm i --save-dev …

使用python读Excel文件并写入另一个xls模版

效果如下&#xff1a; 原文件内容 转化后的内容 大致代码如下&#xff1a; 1. load_it.py #!/usr/bin/env python import re from datetime import datetime from io import BytesIO from pathlib import Path from typing import List, Unionfrom fastapi import HTTPExcep…

Dedecms V110最新版RCE---Tricks

前言 刚发现Dedecms更新了发布版本&#xff0c;顺便测试一下之前的day有没有修复&#xff0c;突然想到了新的tricks去实现RCE。 文章发布的时候估计比较晚了&#xff0c;一直没时间写了。 利用 /uploads/dede/article_string_mix.php /uploads/dede/article_template_rand.…

Spring Boot 项目应用消息服务器RabbitMQ(简单介绍)

一、背景 本章讲述的是在用户下单环节&#xff0c;消息服务器RabbitMQ 的应用 1.1 消息服务器的应用 在写一个电商项目的小demo&#xff0c;在电商项目中&#xff0c;消息服务器的应用&#xff1a; 1、订单状态通知&#xff1a;当用户下单、支付成功、订单发货、订单完成等…

如何使用CSS实现一个模态框(Modal)效果?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 使用CSS实现模态框&#xff08;Modal&#xff09;效果⭐ HTML 结构⭐ CSS 样式⭐ JavaScript⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎…

在 React+Typescript 项目环境中创建并使用组件

上文 ReactTypescript清理项目环境 我们将自己创建的项目环境 好好清理了一下 下面 我们来看组件的创建 组件化在这种数据响应式开发中肯定是非常重要的。 我们现在src下创建一个文件夹 叫 components 就用他专门来处理组件业务 然后 我们在下面创建一个 hello.tsx 注意 是t…

【Linux命令详解 | du命令】 du命令用于查看文件或目录的磁盘使用情况,帮助管理存储空间。

文章标题 简介一&#xff0c;参数列表二&#xff0c;使用介绍1. 基本用法2. 以人类可读的格式显示大小3. 显示总计磁盘使用量4. 包括每个文件的大小5. 限制显示的目录深度6. 排除特定文件或目录7. 指定块大小总结 简介 在Linux操作系统中&#xff0c;存储空间管理是至关重要的…

【C++深入浅出】初识C++上篇(关键字,命名空间,输入输出,缺省参数,函数重载)

目录 一. 前言 二. 什么是C 三. C关键字初探 四. 命名空间 4.1 为什么要引入命名空间 4.2 命名空间的定义 4.3 命名空间使用 五. C的输入输出 六. 缺省参数 6.1 缺省参数的概念 6.2 缺省参数的分类 七. 函数重载 7.1 函数重载的概念 7.2 函数重载的条件 7.3 C支…