STM32编写OLED显示屏驱动

news2024/9/23 3:33:07

文章目录

  • 前言
  • 一、OLED的器件地址
  • 二、编写写数据和写命令函数
  • 三、编写初始化OLED屏幕函数
  • 四、其他功能函数编写
  • 五、显示字符和数字函数编写
  • 总结


前言

这篇文章将带大家学习如何编写OLED显示屏的驱动程序。这里我使用的是HAL库的硬件IIC,OLED屏幕使用的是SSD1306的。
这里需要参考SSD1306的数据手册来编写驱动程序。
手册位置:

一、OLED的器件地址

OLED的器件地址由8个位组成,分别是011110SA0 R/W#。
在这里插入图片描述
数据手册有这样一段话:
D/C# pin acts as SA0 for slave address selection
根据这段话可以得知D/C#这个引脚被作为了SA0。
根据OLED的原理图我们可以得知D/C接到了GND所以SA0 = 0。
在这里插入图片描述
R/W位:当要写数据时这一位是0,当要读数据时这一位是1。
所以可以得出OLED的器件地址:
写地址:0x78
读地址:0x79

二、编写写数据和写命令函数

写命令函数
这里调用了HAL库自带的HAL_I2C_Mem_Write函数来写命令和写数据。
我们需要参照数据手册中的I2C-bus Write data这一小节来编写函数。

根据数据手册可知:
第一步先发送器件地址(这里是写数据也就是0x78)。
第二步发送控制字节:
控制字节由Co位和D/C位决定

在这里插入图片描述
当发送的是命令的时候D/C和Co都为0。
当发送的是数据的时候D/C为1和Co为0。
所以发送命令时控制字节为0x00,发送数据时控制字节为0x40。
在这里插入图片描述
第三步发送数据字节也就是下面函数中的uint8_t data和uint8_t cmd这两个参数。
在这里插入图片描述

void OLED_WR_CMD(uint8_t cmd)
{
	HAL_I2C_Mem_Write(&hi2c1, 0x78, 0x00, I2C_MEMADD_SIZE_8BIT, &cmd, 1, 0x100);
}

写数据函数

void OLED_WR_DATA(uint8_t data)
{
	HAL_I2C_Mem_Write(&hi2c1, 0x78, 0x40, I2C_MEMADD_SIZE_8BIT, &data, 1, 0x100);
}

三、编写初始化OLED屏幕函数

下面是OLED显示屏初始化的步骤。
在这里插入图片描述
这些要设置的参数都放入了CMD_Data数组中。

uint8_t CMD_Data[] = {
0xAE, 0x00, 0x10, 0x40, 0xB0, 0x81, 0xFF, 0xA1, 0xA6, 0xA8, 0x3F,

0xC8, 0xD3, 0x00, 0xD5, 0x80, 0xD8, 0x05, 0xD9, 0xF1, 0xDA, 0x12,

0xD8, 0x30, 0x8D, 0x14, 0xAF };      //初始化命令

这里使用for循环将参数写入。

void WriteCmd(void)
{
	uint8_t i = 0;
	for (i = 0; i < 27; i++)
	{
		HAL_I2C_Mem_Write(&hi2c1, 0x78, 0x00, I2C_MEMADD_SIZE_8BIT, CMD_Data + i, 1, 0x100);
	}
}

//初始化oled屏幕
void OLED_Init(void)
{
	HAL_Delay(200);

	WriteCmd();
}

四、其他功能函数编写

清屏函数

//清屏
void OLED_Clear(void)
{
	uint8_t i, n;
	for (i = 0; i < 8; i++)
	{
		OLED_WR_CMD(0xb0 + i);
		OLED_WR_CMD(0x00);
		OLED_WR_CMD(0x10);
		for (n = 0; n < 128; n++)
			OLED_WR_DATA(0);
	}
}

开启OLED显示和关闭OLED显示函数
在这里插入图片描述

//开启OLED显示    
void OLED_Display_On(void)
{
	OLED_WR_CMD(0X8D);  //SET DCDC命令
	OLED_WR_CMD(0X14);  //DCDC ON
	OLED_WR_CMD(0XAF);  //DISPLAY ON
}
//关闭OLED显示     
void OLED_Display_Off(void)
{
	OLED_WR_CMD(0X8D);  //SET DCDC命令
	OLED_WR_CMD(0X10);  //DCDC OFF
	OLED_WR_CMD(0XAE);  //DISPLAY OFF
}

设置坐标函数
这里OLED被设置为了页地址模式,地址范围是0xb0-0xb7。也就是y的范围是0-7。
x的范围就是0-127

void OLED_Set_Pos(uint8_t x, uint8_t y)
{
	OLED_WR_CMD(0xb0 + y);
	OLED_WR_CMD(((x & 0xf0) >> 4) | 0x10);
	OLED_WR_CMD(x & 0x0f);
}

五、显示字符和数字函数编写

//显示2个数字
//x,y :起点坐标	 
//len :数字的位数
//size:字体大小
//mode:模式	0,填充模式;1,叠加模式
//num:数值(0~4294967295);	 		  
void OLED_ShowNum(uint8_t x, uint8_t y, unsigned int num, uint8_t len, uint8_t size2)
{
	uint8_t t, temp;
	uint8_t enshow = 0;
	for (t = 0; t < len; t++)
	{
		temp = (num / oled_pow(10, len - t - 1)) % 10;
		if (enshow == 0 && t < (len - 1))
		{
			if (temp == 0)
			{
				OLED_ShowChar(x + (size2 / 2)*t, y, ' ', size2);
				continue;
			}
			else enshow = 1;

		}
		OLED_ShowChar(x + (size2 / 2)*t, y, temp + '0', size2);
	}
}
//在指定位置显示一个字符,包括部分字符
//x:0~127
//y:0~63
//mode:0,反白显示;1,正常显示				 
//size:选择字体 16/12 
void OLED_ShowChar(uint8_t x, uint8_t y, uint8_t chr, uint8_t Char_Size)
{
	unsigned char c = 0, i = 0;
	c = chr - ' ';//得到偏移后的值			
	if (x > 128 - 1) { x = 0; y = y + 2; }
	if (Char_Size == 16)
	{
		OLED_Set_Pos(x, y);
		for (i = 0; i < 8; i++)
			OLED_WR_DATA(F8X16[c * 16 + i]);
		OLED_Set_Pos(x, y + 1);
		for (i = 0; i < 8; i++)
			OLED_WR_DATA(F8X16[c * 16 + i + 8]);
	}
	else {
		OLED_Set_Pos(x, y);
		for (i = 0; i < 6; i++)
			OLED_WR_DATA(F6x8[c][i]);

	}
}

//显示一个字符号串
void OLED_ShowString(uint8_t x, uint8_t y, uint8_t *chr, uint8_t Char_Size)
{
	unsigned char j = 0;
	while (chr[j] != '\0')
	{
		OLED_ShowChar(x, y, chr[j], Char_Size);
		x += 8;
		if (x > 120) { x = 0; y += 2; }
		j++;
	}
}
//显示汉字
//hzk 用取模软件得出的数组
void OLED_ShowCHinese(uint8_t x, uint8_t y, uint8_t no)
{
	uint8_t t, adder = 0;
	OLED_Set_Pos(x, y);
	for (t = 0; t < 16; t++)
	{
		OLED_WR_DATA(Hzk[2 * no][t]);
		adder += 1;
	}
	OLED_Set_Pos(x, y + 1);
	for (t = 0; t < 16; t++)
	{
		OLED_WR_DATA(Hzk[2 * no + 1][t]);
		adder += 1;
	}
}

总结

这篇文章主要就是讲解了如何编写OLED的驱动程序。

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

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

相关文章

sbt编程语言scala的构建工具配置及项目构建(附带网盘下载)

SBT简介 SBT 是 Scala 的构建工具&#xff0c;全称是 Simple Build Tool&#xff0c; 类似 Maven 或 Gradle。 Java可以用Maven快速构建项目&#xff0c;scala用SBT快速构建一个Scala项目。 sbt下载官网 百度网盘链接&#xff1a;https://pan.baidu.com/s/1eJkdWndZ0izcd3w…

Elasticsearch7.8.0版本高级查询——桶聚合查询文档

目录一、初始化文档数据二、桶聚合查询文档2.1、概述2.2、terms 聚合&#xff0c;分组统计的示例2.3、在 terms 分组下再进行聚合的示例一、初始化文档数据 在 Postman 中&#xff0c;向 ES 服务器发 POST 请求 &#xff1a;http://localhost:9200/user/_doc/1&#xff0c;请求…

Yolo系列理论

参考文章&#xff1a;AI菌的YOLO系列 目标检测-Yolo系列发展Anchors Base原理Anchors Free原理YOLO v1Yolov1网络结构Yolov1实现方法Yolov1损失函数Yolov1总结YOLO v2Yolov2网络结构Yolov2改进细节Yolov2总结YOLO V3Yolov3网络结构YOLO V4Yolov4网络结构YOLOv4 BackBone训练策略…

数据库搏击

1. Mysql入门 1.1 Mysql5.7 安装配置 1.2 命令行连接到Mysql 1.3 图形化软件 1.3.1 Navicat SQLyog 1.4 数据库三层结构 所有安装Mysql数据库&#xff0c;就是在主机安装一个数据库管理系统(DBMS)&#xff0c;这个管理程序可以管理多个数据库。DBMS(database mana…

设计模式 - 六大设计原则之LSP(里氏替换)

文章目录概述里氏替换原则问题由来里氏替换的原则里氏替换原则的作用CaseBad ImplBetter Impl抽象银行卡类储蓄卡实现类信用卡实现类单元测试小结概述 里氏替换原则&#xff08;Liskov Substitution Principle , LSP&#xff09; 由麻省理工学院计算机科学西教授 Barbara Lisk…

MySQL两种引擎的索引

推荐看看这个视频&#xff0c;将两种引擎实现的索引原理说的比较清楚 4-2 索引概述 本文转载&#xff1a;想飞的盗版鱼的博客​​​​​​ mysql5.5之后都是用idb了 补充一个主键和索引的关系&#xff1a;Are You OK&#xff1f;主键就是聚集索引吗&#xff1f; 索引类型…

五个简单常用的系统命令

一、文件扫描修复 以管理员身份进入命令提示符&#xff0c;输入Sfc空格/scannow 二、使用Check disk命令检查并修复磁盘错误 1、开机时连续不断的点击F11键&#xff0c;选择&#xff08;疑难解答&#xff09;-选择&#xff08;高级选项&#xff09;-选择&#xff08;命令提示…

virtualbox运行Ubuntu系统

virtualbox安装 下载virtualbox VirtualBox 7.0.6版本下载 安装virtualbox 点击执行VirtualBox-7.0.6-155176-Win.exe即可&#xff0c; 直接点击"下一步" 直到 “完成” 导入以有的ova虚拟机文件 1&#xff09;点击导入 2&#xff09;选择下载的ova文件 3&a…

GD32F4——定时器(TIMERx)

一、概述 定时器的主要功能是用来计时&#xff0c;时间到达之后可以产生中断&#xff0c;提醒计时时间到&#xff0c;然后可以在中断函数中去执行功能。 GD32F450ZGT6共14个定时器&#xff0c;分别为 &#xff08;1&#xff09;高级定时器&#xff08;TIMERx&#xff0c;x0,…

LightGBM介绍

LightGBM介绍 GBDT是机器学习中一个长盛不衰的模型&#xff0c;其主要思想是利用弱分类器&#xff08;决策树&#xff09;迭代训练以得到最优模型&#xff0c;该模型具有训练效果好&#xff0c;不易过拟合等优点。GBDT不仅在工业界应用广泛&#xff0c;通常被应用于多分类、点…

【ONE·C || 数据存储】

总言 C语言&#xff1a;数据存储相关介绍。 文章目录总言1、基本数据类型介绍1.1、整体介绍1.2、各数据类型分别说明&#xff08;整型、浮点型、构造、指针、空&#xff09;2、整型在内存中的存储2.1、原码、反码、补码2.1.1、总体介绍2.1.2、char、short类型在内存中的存储范围…

顺序表的具体使用方法.数据解构(二)

前言 提示&#xff1a;文本为数据解构(一)后续补充文&#xff1a; 本文具体讲解顺序表的具体使用方法 提示&#xff1a;以下是本篇文 系列文章目录 第一章 数据解构(一) 文章目录 前言 系列文章目录 一、静态的使用方式 二、动态的使用方式 1.定义一个结构体 2.初始化 3.扩容…

【ArcGIS微课1000例】0060:ArcGIS打开las格式点云数据的方法

文章目录 1. 使用上下文菜单创建 LAS 数据集2. 使用地理处理工具创建 LAS 数据集3. 显示LAS数据集LAS 数据集是位于文件夹中的独立文件,并且引用 LAS 格式的激光雷达数据和用于定义表面特征的可选表面约束要素。ArcGIS中,可使用创建 LAS 数据集工具或 ArcCatalog 中文件夹的上…

23种设计模式(二十)——责任链模式【数据结构】

文章目录 意图什么时候使用责任链真实世界类比责任链模式的实现责任链模式的优缺点亦称:职责链模式、命令链、CoR、Chain of Command、Chain of Responsibility 意图 将链中的每一个节点看作是一个对象,每个节点处理的请求不同,且内部自动维护一个下一节点对象。当一个请求…

【OpenGL学习】camera and camera control

摄像机 游戏中的相机可以理解为与现实中的相机类似&#xff0c;可以捕获对应的游戏画面。Camera在游戏引擎中一般也会展示为现实中相机的模型&#xff0c;使用时有两种实现方式&#xff0c;一种以组件形式挂载在Character上&#xff0c;一种则是单独存在。通常来讲&#xff0c…

Flutter 基础-下

一、shared_preferences shared_preferences 是一个本地数据缓存库&#xff08;类似 AsyncStorage&#xff09; https://pub.dev/packages/shared_preferences 使用步骤 在 pubsepc.yaml 中添加 shared_preferences 依赖安装依赖&#xff08;pub get | flutter packages get |…

Git使用Merge和Rebase区别及心得技巧

git rebase命令常常因为江湖上关于它是一种Git魔法命令的名声而导致Git新手对它敬而远之&#xff0c;但是事实上如果一个团队能够正确使用的话&#xff0c;它确实可以让生活变得更简单。在这篇文章中我们会比较git rebase和经常与之相提并论的git merge命令&#xff0c;并且在真…

【回望2022,走向2023】一个双非二本非科班的学生的旅途

目录 1.自我介绍 2.高考与暑假 梦想 幻灭 决心 暑假 3.大一上学期 4.奋进之路 5.展望未来 1.自我介绍 我是一个双非本科的大一学生&#xff0c;在2023年的新春之际&#xff0c;借着CSDN的这次年度总结活动&#xff0c;来好好回顾一下&#xff0c;2022这个平凡却又不乏…

css 2D转换

文章目录一、什么是2D转换二、rotate() 方法&#xff08;旋转&#xff09;三、translate() 方法&#xff08;位移&#xff09;四、scale() 方法&#xff08;缩放&#xff09;五、skew() 方法 &#xff08;倾斜&#xff09;一、什么是2D转换 在二维空间下对元素进行移动、缩放、…

面试官问我有没有分布式系统开发经验,我一脸懵圈…

目录 从单块系统说起团队越来越大&#xff0c;业务越来越复杂分布式出现&#xff1a;庞大系统分而治之分布式系统所带来的技术问题一句话总结&#xff1a;什么是分布式系统设计和开发经验补充说明&#xff1a;中间件系统及大数据系统 前言 现在有很多Java技术方向的同学在找工…