STM32 软件IIC 控制OLED 显示屏
1. 硬件IIC 实在是太难用了,各种卡死,各种发不出来数据,没那么多时间折腾了,还是用软件IIC 先吧,初始化
void OLED_Software_IIC_Init(void)
{GPIO_InitTypeDef GPIO_InitStruct;RCC_AHBPeriphClockCmd(OLED_SOFTWARE_IIC_PORT_B | OLED_SOFTWARE_IIC_AF_CLOCK, ENABLE);GPIO_InitStruct.GPIO_Pin = OLED_IIC_SDA_PIN_B11 | OLED_IIC_SCL_PIN_B10;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_40MHz;GPIO_Init(GPIOB, &GPIO_InitStruct); // PB11 - SDA, PB10 - SCLGPIO_SetBits(GPIOB, OLED_IIC_SDA_PIN_B11 | OLED_IIC_SCL_PIN_B10);OLED_IIC_Stop();
}
2. 一些宏定义,带FreeRTOS 实时操作系统,系统节拍设置为1ms,系统主频设置为32Mhz
#define OLED_USE_SOFTWARE_IIC#define OLED_SOFTWARE_IIC_PORT_B RCC_AHBPeriph_GPIOB // SCL - PB10, SDA -PB11
#define OLED_SOFTWARE_IIC_AF_CLOCK RCC_APB1Periph_I2C2#define IIC_TIMEOUT_COUNTER 0x2000 // iic transmit timeout#define OLED_IIC_SCL_PIN_B10 GPIO_Pin_10
#define OLED_IIC_SDA_PIN_B11 GPIO_Pin_11
#define OLED_SCL_H() GPIO_SetBits(GPIOB, OLED_IIC_SCL_PIN_B10)
#define OLED_SCL_L() GPIO_ResetBits(GPIOB, OLED_IIC_SCL_PIN_B10)#define OLED_ADDRESS 0x78 // 0x78: device address + write, 0x79 - device address + read
#define IIC_CMD_LEN 2#define OLED_SDA_H() GPIO_SetBits(GPIOB, OLED_IIC_SDA_PIN_B11)
#define OLED_SDA_L() GPIO_ResetBits(GPIOB, OLED_IIC_SDA_PIN_B11)#define OLED_SDA_READ() GPIO_ReadInputDataBit(GPIOB, OLED_IIC_SDA_PIN_B11)
3. 延时函数,CPU 阻塞,空转
static void IIC_Delay(void)
{uint8_t temp;for (temp = 0; temp < 10; temp++){// do nothing}
}
4. 起始信号
static void OLED_IIC_Start(void)
{OLED_SDA_H();OLED_SCL_H();IIC_Delay();OLED_SDA_L();IIC_Delay();OLED_SCL_L();IIC_Delay();
}
5. 停止信号
static void OLED_IIC_Stop(void)
{OLED_SDA_L();OLED_SCL_H();IIC_Delay();OLED_SDA_H();IIC_Delay();
}
6. 发送一个字节的数据
static void OLED_IIC_SendByte(uint8_t data)
{uint8_t index;GPIO_InitTypeDef GPIO_InitStruct;for (index = 0; index < 8; index++) // send one byte data, first send MSB (bit[7]), send LSB at the last (bit[0]){if (data & 0x80){OLED_SDA_H(); // send 1}else{OLED_SDA_L(); // send 0}IIC_Delay();OLED_SCL_H();IIC_Delay();OLED_SCL_L();data <<= 1; // send next bit (MSB -> LSB)IIC_Delay();}
// OLED_SDA_H();GPIO_InitStruct.GPIO_Pin = OLED_IIC_SDA_PIN_B11;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;GPIO_Init(GPIOB, &GPIO_InitStruct);IIC_Delay();
}
7. 发送一个字节数据后等待从机回复一个ACK 信号
uint8_t OLED_IIC_WaitAck(void)
{uint8_t ret;OLED_SCL_H();if (OLED_SDA_READ()){ret = 1; // not received ACK signal, wait fail}else{ret = 0; // received ACK signal, wait success}IIC_Delay();OLED_SCL_L();IIC_Delay();return ret;
}
8. GPIO 重新初始化
static void OLED_SoftwareIIC_SDA_Resume(void)
{GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Pin = OLED_IIC_SDA_PIN_B11;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_40MHz;GPIO_Init(GPIOB, &GPIO_InitStruct); // PB11 - SDA
}
9. 模仿HAL库写的一个自己的函数,实现功能,发送设备地址+读写控制,再发送0x00,表示发的是命令,再发一个字节数据,具体的内容,数据,共发了三个字节的数据,加了超时退出机制
/** imitate the stm32 HAL library, achieve myself's software i2c send function* deviceAddr: 0x78 - device address and write operation, 0x79 - device address and read operation*/
static void HAL_I2C_Master_Transmit(I2C_TypeDef *I2Cx, uint8_t deviceAddr, uint8_t buff[], uint16_t buffLen, uint32_t timeout)
{uint32_t temp;uint16_t index;temp = timeout;OLED_IIC_Start();IIC_Delay();OLED_IIC_SendByte(deviceAddr); // device address and write bitwhile (OLED_IIC_WaitAck()){temp--;if (0 == temp){return;}IIC_Delay();}OLED_SoftwareIIC_SDA_Resume();for (index = 0; index < buffLen; index++){OLED_IIC_SendByte(buff[index]);IIC_Delay();while (OLED_IIC_WaitAck()){temp--;if (0 == temp){return;}IIC_Delay();}OLED_SoftwareIIC_SDA_Resume();IIC_Delay();}OLED_IIC_Stop();
}
10. 向OLED 发送指令函数
static void OLED_SendCmd(uint8_t cmd)
{uint8_t sendBuff[2];sendBuff[0] = 0x00;sendBuff[1] = cmd;HAL_I2C_Master_Transmit(I2C2, OLED_ADDRESS, sendBuff, IIC_CMD_LEN, IIC_TIMEOUT_COUNTER);
}
11. OLED 初始化函数,OLED 用的龙科显示公式的产品,控制IC 用的是CH1116G,他们给我发是资料却是SH1106的
void OLED_Init(void)
{delay_xms(200); // oled startup slowly than stm32l151c8t6INFO_LOG("[OLED_Init] init start\r\n");OLED_SendCmd(0xAE); // display offOLED_SendCmd(0x02); // set colum start address, low 4-bitsOLED_SendCmd(0x10); // set colum end address, high 4-bitsOLED_SendCmd(0x40); // set start line (first row)OLED_SendCmd(0xB0); // set page addressdelay_xms(5);OLED_SendCmd(0x81); // set contrast ratio (对比度)delay_xms(5);OLED_SendCmd(0xCF); // 128delay_xms(5);OLED_SendCmd(0xA1); // set segment remapping, from right to leftOLED_SendCmd(0xA6); // forward display, normal or reverseOLED_SendCmd(0xA8); // multiple reuse rate, multiple ratio (多路复用率)OLED_SendCmd(0x3F); // duty = 1 / 64OLED_SendCmd(0xAD); // set charge pump enableOLED_SendCmd(0x8B); // enable DC-DCOLED_SendCmd(0x33); // set VPP = 10VOLED_SendCmd(0xC8); // set output scan direction, COM[N - 1] to COM[0], COM scan directionOLED_SendCmd(0xD3); // set display offsetOLED_SendCmd(0x00); // 0x00OLED_SendCmd(0xD5); // set internal clock frequence, set osc frequencyOLED_SendCmd(0xC0);OLED_SendCmd(0xD9); // set pre-charge periodOLED_SendCmd(0x1F); // 0x22OLED_SendCmd(0xDA); // set COM pins, pin layoutOLED_SendCmd(0x12);OLED_SendCmd(0xDB); // set electrical level, set VCOMHOLED_SendCmd(0x40);OLED_SendCmd(0xAF); // enable display, display onINFO_LOG("[OLED_Init][alfred01] init complete\r\n");INFO_LOG("[OLED_Init] init complete\r\n");
}
12. OLED 测试函数
void OLED_Test(void)
{OLED_SendCmd(0xB0); // page 0OLED_SendCmd(0x02); // colume 0, low 4-bitsOLED_SendCmd(0x10); // colume 0, high 4-bitsuint8_t sendBuff[] = {0x40, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA};HAL_I2C_Master_Transmit(I2C2, OLED_ADDRESS, sendBuff, sizeof(sendBuff), IIC_TIMEOUT_COUNTER);
}
13. OLED 初步显示效果,表示控制驱动是OK的了,其它的就是慢慢细调了

14. OLED 规格书,控制芯片用的CH1116G,这是硬件发给我,和厂家给的不一致,厂家说是兼容的,那我就直接上手调了

15. 看这三个引脚接的是高电平还是低电平,怎么组合的,就知道用的什么接口,需要看原理图了

需要看原理图了


16. 逻分仪抓的OLED 初始化时序图

相关文章:
STM32 软件IIC 控制OLED 显示屏
1. 硬件IIC 实在是太难用了,各种卡死,各种发不出来数据,没那么多时间折腾了,还是用软件IIC 先吧,初始化 void OLED_Software_IIC_Init(void) {GPIO_InitTypeDef GPIO_InitStruct;RCC_AHBPeriphClockCmd(OLED_SOFTWARE…...
【系统设计系列】 DNS和CDN
系统设计系列初衷 System Design Primer: 英文文档 GitHub - donnemartin/system-design-primer: Learn how to design large-scale systems. Prep for the system design interview. Includes Anki flashcards. 中文版: https://github.com/donnemarti…...
thinkphp中使用Elasticsearch 7.0进行多表的搜索
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、thinkphp中使用Elasticsearch 7.0进行多表的搜索二、使用步骤1.引入库2.读入数据 总结 前言 提示:thinkphp中使用Elasticsearch 7.0进行多表的…...
说说 TCP的粘包、拆包
分析&回答 拆包和粘包是在socket编程中经常出现的情况, 在socket通讯过程中,如果通讯的一端一次性连续发送多条数据包,tcp协议会将多个数据包打包成一个tcp报文发送出去,这就是所谓的粘包。如果通讯的一端发送的数据包超过一…...
PowerToys安装
PowerToys 是微软开发者开发的免费实用工具集,可以用于高级用户调整和简化 Windows 操作,以提高效率。 官网安装方法: https://learn.microsoft.com/zh-cn/windows/powertoys/install 目前安装文件路径: https://github.com/m…...
Unity——LitJSON的安装
一、LitJSON介绍 特点 LitJSON是一个轻量级的C# JSON库,用于在Unity游戏开发中进行JSON数据的序列化和反序列化操作。它提供了简单而高效的接口,帮助开发者处理JSON数据。 以下是LitJSON库的一些主要特点和功能: 1. 高性能:Lit…...
YOLOv5:对yolov5n模型进一步剪枝压缩
YOLOv5:对yolov5n模型进一步剪枝压缩 前言前提条件相关介绍具体步骤修改yolov5n.yaml配置文件单通道数据(黑白图片)修改models/yolo.py文件修改train.py文件 剪枝后模型大小 参考 前言 由于本人水平有限,难免出现错漏,…...
大数据(八):Pandas的基础应用详解(五)
专栏介绍 结合自身经验和内部资料总结的Python教程,每天3-5章,最短1个月就能全方位的完成Python的学习并进行实战开发,学完了定能成为大佬!加油吧!卷起来! 全部文章请访问专栏:《Python全栈教程(0基础)》 再推荐一下最近热更的:《大厂测试高频面试题详解》 该专栏对…...
【算法】归并排序 详解
归并排序 详解 归并排序代码实现1. 递归版本2. 非递归版本 排序: 排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。 稳定性: 假定在待排序的记录序列中,存在多个具有相…...
linux 进程隔离Namespace 学习
一、linux namespace 介绍 1.1、概念 Linux Namespace是Linux内核提供的一种机制,它用于隔离不同进程的资源视图,使得每个进程都拥有独立的资源空间,从而实现进程之间的隔离和资源管理。 Linux Namespace的设计目标是为了解决多个进程之间…...
【MySQL】事务 详解
事务 详解 一. 为什么使用事务二. 事务的概念三. 使用四. 事务的特性原子性(Atomicity)一致性(Consistency)隔离性(Isolation)持久性(Durability) 五. 事务并发所带来的问题脏读问题…...
爬虫到底难在哪里?
目录 爬虫到底难在哪里 怎么学习爬虫 注意事项 爬虫工具 总结 学习Python爬虫的难易程度因人而异,对于具备编程基础的人来说,学习Python爬虫并不困难。Python语言本身比较简单易学,适合初学者使用。 爬虫到底难在哪里 爬虫的难点主要包…...
linux常用命令行整理
1、linux的以及目录 bin 二进制可执行文件sbin 二进制可执行文件(root用户权限)etc 系统管理和配置文件,例如常见host文件home 用户文件的根目录usr 用户存放系统应用程序(共享系统资源)opt 可选的应用程序proc 虚拟文件系统root 超级用户dev 存放设备文件mnt 系统管理员安装临…...
python字符串相关
python字符串相关 一、reverse() 函数 只能反转 列表二、reversed() 反转元组字符串等等 返回迭代器三、join和reversed反转字符串四、join串联字符串(join连接对象仅限字符串、储存字符串的元组、列表、字典)数字对象可通过str()转化为字符串⭐对象为字…...
JavaScript学习笔记01
JavaScript笔记01 什么是 JavaScript JavaScript 是一门世界上最流行的脚本语言,它是一种弱类型的脚本语言,其代码不需要经过编译,而是由浏览器解释运行,用于控制网页的行为。 发展历史 参考:JavaScript的起源故事…...
golang 通用的 grpc http 基础开发框架
go-moda golang 通用的 grpc http 基础开发框架仓库地址: https://github.com/webws/go-moda仓库一直在更新,欢迎大家吐槽和指点 特性 transport: 集成 http(echo、gin)和 grpc。tracing: openTelemetry 实现微务链路追踪pprof: 分析性能config: 通用…...
FSK解调技术的FPGA实现
本原创文章由深圳市小眼睛科技有限公司创作,版权归本公司所有,如需转载,需授权并注明出处 一、FSK信号的解调原理 FSK信号的解调也有非相干和相干两种,FSK信号可以看作是用两个频率源交替传输得到的,所以FSK的接收机由…...
Matlab图像处理-高斯低通滤波器
高通滤波 图像的边缘、细节主要位于高频部分,而图像的模糊是由于高频成分比较弱产生的。高通滤波就是为了高消除模糊,突出边缘。因此采用高通滤波器让高频成分通过,消除低频噪声成分削弱,再经傅里叶逆变换得到边缘锐化的图像。 …...
文件上传之图片马混淆绕过与条件竞争
一、图片马混淆绕过 1.上传gif imagecreatefromxxxx函数把图片内容打散,,但是不会影响图片正常显示 $is_upload false; $msg null; if (isset($_POST[submit])){// 获得上传文件的基本信息,文件名,类型,大小&…...
代码随想录二刷day16
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、力扣104. 二叉树的最大深度二、力扣559. N 叉树的最大深度三、力扣111. 二叉树的最小深度三、力扣力扣222. 完全二叉树的节点个数 前言 一、力扣104. 二叉树…...
告别龟速采样!用DDIM加速你的扩散模型推理(附PyTorch代码)
加速扩散模型推理:DDIM核心原理与实战优化指南 在图像生成领域,扩散模型以其卓越的质量表现迅速成为研究热点,但传统DDPM(Denoising Diffusion Probabilistic Models)的致命缺陷在于其缓慢的采样速度——生成一张图片往…...
告别手改脚本!用CANoe Panel面板做个变量控制台,测试效率翻倍
告别手改脚本!用CANoe Panel面板打造智能变量控制台 在车载网络测试领域,效率提升往往隐藏在那些被忽视的日常操作细节中。当测试工程师频繁打开CAPL脚本修改超时阈值、调整诊断ID或切换测试模式时,不仅打断了工作流,更在团队协作…...
LearningX:构建结构化开发者知识体系,从基础到架构的实践指南
1. 项目概述:一个面向开发者的系统性学习仓库最近在GitHub上看到一个挺有意思的项目,叫“LearningX”。光看名字,你可能会觉得这又是一个普通的“Awesome-XXX”列表,或者是一堆学习资料的简单堆砌。但当我点进去,花了一…...
WandEnhancer技术解密:如何通过本地化增强重新定义游戏修改体验
WandEnhancer技术解密:如何通过本地化增强重新定义游戏修改体验 【免费下载链接】Wand-Enhancer Advanced UX and interoperability extension for Wand (WeMod) app 项目地址: https://gitcode.com/gh_mirrors/we/Wand-Enhancer 你是否曾经面对游戏修改工具…...
Mantic.sh:Bash脚本实现的终端命令自动化与效率提升工具
1. 项目概述:一个为开发者打造的终端效率工具如果你和我一样,每天有超过一半的工作时间是在终端(Terminal)里度过的,那你肯定对效率工具有着近乎偏执的追求。从cd到ls,从grep到awk,我们依赖这些…...
【限时解密】ElevenLabs未文档化的/v1/text-to-speech/{voice_id}/with-timing接口:获取逐词时间戳+音素级对齐数据(仅剩3个Beta白名单通道)
更多请点击: https://intelliparadigm.com 第一章:ElevenLabs英文语音生成的核心能力与技术定位 ElevenLabs 是当前业界领先的 AI 语音合成平台,其英文语音生成能力建立在自研的端到端神经声学模型(如 ElevenMultilingualV2&…...
会话管理封装实践:构建安全可扩展的分布式会话系统
1. 项目概述:一个被低估的会话管理利器如果你是一名开发者,尤其是经常需要处理用户登录、权限校验、状态保持这类“脏活累活”的后端或全栈开发者,那么你一定对“会话管理”这四个字又爱又恨。爱的是,它是构建安全、有状态应用的基…...
藏文语音生成准确率从61.2%跃升至94.8%:ElevenLabs Fine-tuning私有数据集构建全流程(含217小时母语者录音标注规范)
更多请点击: https://intelliparadigm.com 第一章:藏文语音生成技术演进与ElevenLabs适配挑战 藏文作为具有复杂音节结构、声调隐含性及丰富上下文依赖的黏着语系文字,其语音合成长期受限于高质量标注语料稀缺、音素-音节映射不唯一、以及缺…...
Python邮件自动化实战:基于mymailclaw的监控报警与Slack集成
1. 项目概述与核心价值最近在折腾邮件自动化处理的时候,发现了一个挺有意思的开源项目,叫psandis/mymailclaw。乍一看这个名字,你可能会联想到“邮件抓取”或者“邮件爬虫”。没错,它的核心定位就是一个用 Python 写的邮件客户端自…...
基于CircuitPython的Fruit Jam OS:在RP2350上构建复古微型计算机系统
1. 项目概述:当复古计算精神遇见现代微控制器如果你和我一样,对早期个人计算机那种开机即用、一切尽在掌控的纯粹体验抱有怀念,同时又痴迷于现代开源硬件带来的无限可能,那么Fruit Jam OS绝对是一个会让你眼前一亮的项目。它不是一…...
