STM32使用IIC协议驱动0.96寸OLED屏

2023-11-12

IIC是常用的协议之一,它通过不同的地址来区分设备,并且端口需要是开漏模式,并且需要接上拉电阻

 要使用IIC驱动OLED,首先要配置IIC

void I2C_Configuration(void)
{
	I2C_InitTypeDef I2C_InitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	I2C_InitStructure.I2C_ClockSpeed = 100000;  
    I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
    I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
    I2C_InitStructure.I2C_OwnAddress1 = 0x22;
    I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; 
	I2C_Init(I2C1,&I2C_InitStructure);
	I2C_Cmd(I2C1, ENABLE);
	
}

然后编写写入函数

void OLED_CMD(unsigned char cmd)
{
		I2C_GenerateSTART(I2C1, ENABLE);
		while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT)==ERROR);
	
		I2C_Send7bitAddress(I2C1, 0x78, I2C_Direction_Transmitter);
		while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)==ERROR);
		
		I2C_SendData(I2C1,0x00);
		while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED)==ERROR);
	
		I2C_SendData(I2C1,cmd);
		while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED)==ERROR);
	
		I2C_GenerateSTOP(I2C1, ENABLE);
		
}

void OLED_DATA(unsigned char dat)
{
		I2C_GenerateSTART(I2C1, ENABLE);
		while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT)==ERROR);
	
		I2C_Send7bitAddress(I2C1, 0x78, I2C_Direction_Transmitter);
		while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)==ERROR);
		
		I2C_SendData(I2C1,0x40);
		while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED)==ERROR);
	
		I2C_SendData(I2C1,dat);
		while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED)==ERROR);
	
		I2C_GenerateSTOP(I2C1, ENABLE);
}

ErrorStatus I2C_CheckEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT)为判断事件的函数

有以下多种事件

//从机发送地址匹配
I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED           : EV1
//从机接受地址匹配
I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED              : EV1

//从机发送第二次地址匹配
I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED     : EV1
//从机接收第二次地址匹配
I2C_EVENT_SLAVE_RECEIVER_SECONDADDRESS_MATCHED        : EV1

//从机通用呼叫地址匹配
I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED            : EV1

//从机字节接收
I2C_EVENT_SLAVE_BYTE_RECEIVED                         : EV2

(I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_DUALF)      : EV2
(I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_GENCALL)    : EV2

//从机字节发送
I2C_EVENT_SLAVE_BYTE_TRANSMITTED                      : EV3
(I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_DUALF)   : EV3
(I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_GENCALL) : EV3

//从机应答
I2C_EVENT_SLAVE_ACK_FAILURE                           : EV3_2

//从机停止位
I2C_EVENT_SLAVE_STOP_DETECTED                         : EV4

//主机模式选择
I2C_EVENT_MASTER_MODE_SELECT                          : EV5

//主机发送模式选择
I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED            : EV6 

//主机接收模式选择
I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED               : EV6

//主机字节接收
I2C_EVENT_MASTER_BYTE_RECEIVED                        : EV7

//主机字节发送中
I2C_EVENT_MASTER_BYTE_TRANSMITTING                    : EV8

//主机字节发送结束
I2C_EVENT_MASTER_BYTE_TRANSMITTED                     : EV8_2

//主机10位地址模式
I2C_EVENT_MASTER_MODE_ADDRESS10                       : EV9

OLED初始化

void OLED_init(void)
{
	OLED_CMD(0xAE);//--display off                关显示
	
	OLED_CMD(0x00);//---set low column address    设置在哪里开始写GDDRAM在某个地方开始读的内容
	OLED_CMD(0x10);//---set high column address
	OLED_CMD(0x40);//--set display start address  从GDDRAM的某个地方开始读,显示在所设置的开始高低列地址中
	OLED_CMD(0xB0);//--set page address           页地址模式,选择开始地址
	
  OLED_CMD(0x81); // contract control           进入对比度设置模式
	OLED_CMD(0xFF);//--256                        输入对比度数值范围是0x00-0xFF
	
	OLED_CMD(0xA1);//set segment remap            列地址127被映射到SEG0,可以利用该命令实现整体图片正反转(0xA0-0xA1),带显示屏30pin管脚的那边的左边为列地址0
	
	OLED_CMD(0xA6);//--normal / reverse           正相显示(0xA7为反相显示)
	
	OLED_CMD(0xA8);//--set multiplex ratio(16 to 64) 设置多路复用比率
	OLED_CMD(0x3F);//--1/64 duty占空比(最大屏幕利用率)
	
	OLED_CMD(0xC8);//Com scan direction           Com扫描方向,可理解为行地址映射,0xC8为从行地址63到0显示,0xC0为从行地址0到63显示,带显示屏30pin管脚的那边为行地址0
	
	OLED_CMD(0xD3);//-set display offset          设置显示偏移
	OLED_CMD(0x00);//                             行偏移
	
	OLED_CMD(0xD5);//set osc division             设置内部振荡器
	OLED_CMD(0x80);//                             Fosc通过高四位修改,值越大频率越高,低四位通过外部SCL获得频率然后分频获得显示时钟频率(慢,不常用,设置为0)默认为0x80
	
	OLED_CMD(0xD8);//set area color mode off      
	OLED_CMD(0x05);//
	
	OLED_CMD(0xD9);//Set Pre-Charge Period        预充电时间设置
	OLED_CMD(0xF1);//                             
	
	OLED_CMD(0xDA);//set com pin configuartion    设置引脚配置
	OLED_CMD(0x12);//
	
	OLED_CMD(0xDB);//set Vcomh                    设置引脚电压等级
	OLED_CMD(0x30);//
	
	OLED_CMD(0x8D);//set charge pump enable       将电荷泵设置为启用
	OLED_CMD(0x14);//                             0x14为打开使能,0x10为关闭使能
	
	OLED_CMD(0xAF);//--turn on oled panel         开显示
}

上图分别为(起始位-数据-结束位)(起始位-数据-应答位-结束位)两种帧类型,本文采用的是(起始位-数据-结束位)这种类型。若使用(起始位-数据-应答位-结束位),则可以在应答位后面继续写数据。

IIC通信时每个字节位宽为8位,数据先传送最高位,后传送最低位

(起始位-数据-应答位-数据-应答位-数据-应答位-……数据-应答位-结束位)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32使用IIC协议驱动0.96寸OLED屏 的相关文章

  • 为什么无符号类型在arm cpu中效率更高?

    我正在阅读手臂手册并提出这个建议 但没有提到原因 为什么无符号类型更快 在 ARMv4 之前 ARM 没有对加载半字和有符号字节的本机支持 要加载有符号的字节 你必须LDRB然后对值进行符号扩展 LSL那就起来吧ASR它回落 这很痛苦所以c
  • ARM NEON:如何实现 256 字节查找表

    我正在使用内联汇编将我编写的一些代码移植到 NEON 我需要的一件事是将范围 0 128 的字节值转换为表中采用完整范围 0 255 的其他字节值 该表很短 但其背后的数学并不容易 因此我认为不值得每次 即时 计算它 所以我想尝试查找表 我
  • 使用 GCC 编译器为代码的特定部分保留寄存器

    是否可以为 C 代码的特定部分保留寄存器 ffixed reg 选项或声明全局寄存器变量不是我正在寻找的答案 我想保留特定范围 比如说特定函数 的寄存器值 使用局部寄存器变量是不可能的 因为它不能保证在整个范围内保留寄存器的值 我正在寻找类
  • GNU Arm Cortex m4 上的 C++ 异常处理程序与 freertos

    2016 年 12 月更新现在还有一个关于此行为的最小示例 https community nxp com message 862676 https community nxp com message 862676 我正在使用带有 free
  • ARM 9处理器的opencv交叉编译

    我需要为 ARM 9 处理器交叉编译 opencv 我有处理器的工具链 但不知道如何交叉编译 请告诉我为arm板交叉编译的过程 谢谢大家 看这个参考 http www airs com ian configure configure 5 h
  • STM32F0、ST-link v2、OpenOCD 0.9.0:打开失败

    我在用着发射台 http www ti com ww en launchpad about htmlgcc arm none eabi 4 9 2015q2 为 STM32F0 进行编译 现在我想使用该集合中的 arm none eabi
  • ARM 汇编分支到寄存器或内存内部的地址

    我想知道在 ARM 汇编中我可以使用哪条指令分支到存储在某个内存地址中的地址或标签 例如 我们可以使用B LABEL来跳转到LABEL 但现在目的地只能在运行时知道 并且它存储在某个已知的内存位置 是否有类似 B 地址 的东西 Thanks
  • 哪些变量类型/大小在 STM32 微控制器上是原子的?

    以下是 STM32 微控制器上的数据类型 http www keil com support man docs armcc armcc chr1359125009502 htm http www keil com support man d
  • 在嵌入式设备上使用new或malloc引起的段错误[关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 我正在尝试
  • 源和目标具有不同的 EABI 版本

    我正在尝试使用 ARM 工具链编译 so 文件 但是我不断收到这个错误 错误 源对象的 EABI 版本为 0 但目标对象的 EABI 版本为 5 我无法更改工具链中的任何内容 因为我必须使用给定的工具链 我以前从未见过这个错误 我使用了这个
  • 当端点和 PMA 地址均更改时,CubeMX 生成的 USB HID 设备发送错误数据

    我正在调试我正在创建的复合设备的问题 并在新生成的仅 CubeMX 代码中重新创建了该问题 以使其更容易解决 我添加了少量代码main 让我发送 USB HID 鼠标点击 并在按下蓝色按钮时使 LED 闪烁 uint8 t click re
  • 为 ARM 交叉编译 zlib

    我尝试为arm poky linux gnueabi交叉编译zlib 但启动 make 时出现错误 zlib 1 2 11 AR HOST ar CC HOST gcc RANLIB HOST ranlib configure prefix
  • 交叉编译 Qt 4.7 时出现“非法指令”

    我已经在这个问题上苦苦挣扎了一个多星期了 但仍然找不到解决方案 我正在尝试为 ARM 设备交叉编译 Qt 4 7 嵌入式开源版本 构建过程本身可以顺利完成 但生成的二进制文件似乎包含处理器无法理解的指令 构建主机是 i386 上的 Debi
  • 产生并处理软件中断

    有人可以告诉我如何在Linux下生成软件中断然后用request irq处理它吗 或者也许这是不可能的 您可以使用软中断来代替 您可以通过编辑 include linux interrupt h 来定义您的 sofirq 然后使用函数 ra
  • 使用 Android NDK 使用 -fsigned-char 进行构建安全吗?

    为了与其他平台保持一致 我需要使用signed char在我正在处理的一些本机代码中 但默认情况下在Android NDK上char类型是unsigned 我尝试明确使用signed char类型 但它生成太多警告differ in sig
  • 了解 ctags 文件格式

    我使用 Exhuberant ctags 来索引我的 c 项目中的所有标签 c project 是 Cortex M7 微控制器的嵌入式软件 结果是一个标签文件 我正在尝试阅读该文件并理解所写的内容 根据我找到的 ctags 和 Exhub
  • 在 Intel 机器上构建 Apple Silicon 二进制文件

    如何在 macOS 11 Intel 上编译 C 项目以在 Silicon 上运行 我当前的构建脚本很简单 configure make sudo make install 我尝试过使用 host and target标志与aarch64
  • 使用 NEON 优化 Cortex-A8 颜色转换

    我目前正在执行颜色转换例程 以便从 YUY2 转换为 NV12 我有一个相当快的函数 但没有我预期的那么快 主要是由于缓存未命中 void convert hd uint8 t orig uint8 t result uint32 t wi
  • 了解 U-Boot 内存占用

    我不明白加载 U Boot 时 RAM 中发生了什么 我正在开发 Xilinx Zynq ZC702 评估套件 并尝试使用 U Boot 在其上加载 Linux 内核 于是我使用Xilinx工具Vivado和SDK生成了一个BOOT bin
  • ARM Chromebook 上的 Android 开发环境?

    我尝试了多次安装和使用安卓工作室 https developer android com studio index html on an ARM Chromebook C100P https archlinuxarm org platfor

随机推荐

  • c++文件读取、容器(vector、map)、迭代(iterator)、排序(sort)综合案例

    1 案例一 获取数据 处理数据是工作中必不可少的 本题通过少量数据主要考察大家对STL容器和迭代器 排序算法 以及文件操作等相关知识 编程实现以下功能 1 t1 txt文件中保存某柜台一年中不同商品的销售情况 2 读取文件中的数据 要求使用
  • 【onnx】——pytorch转onnx 手动添加不支持的算子

    onnx pytorch
  • c++中模板与重载

    include
  • 常见的Linux高危端口有哪些

    一些常见的 Linux 高危端口 SSH 端口 22 SSH 虽然是一种安全的远程登录协议 但默认端口号 22 却经常成为黑客攻击的目标 因此 建议将 SSH 服务的端口号修改为一个不易被猜测的端口号 以增强系统安全性 Telnet 端口
  • 使用Go Hijack和jQuery轻松实现异步推送服务

    使用Go Hijack和jQuery轻松实现异步推送服务 首先要说明的是 这里实现的异步推送服务采用的是Long Polling方式 并不是Comet 如果想用Comet来实现的话 可以参考这个开源项目 http cometd org 不过
  • stm32通过esp8266实现温湿度实时监控和控制灯光

    stm32通过esp8266实现温湿度实时监控和控制灯光 前言 准备材料 一 硬件方面 二 软件方面 三 建立工程 1 工程创建 2 代码编写 三 关于一些C语言函数运用 结果演示 视频演示 前言 WiFi具有两种功能模式 一种叫 AP A
  • VMware Workstation 不可恢复错误: (vcpu-0) vcpu-0:VERIFY vmcore/vmm/main/cpuid.c:376 bugNr=1036521

    这个问题的原因有几个 第一个原因就是网上说的要开启BIOS的Interl virtual technology 而我当时开启了之后依然报错 最后找到问题的原因在VMWare Workstation 右键我们的虚拟机 选择最下面的设置 然后注
  • 梁山派GD32F470 CMSIS-DAPv1驱动错误

    请先参考嘉立创提供的解决方法 https dri8c0qdfb feishu cn wiki wikcnsGSBwwp15hr9dqRqbiKqxe 我的错误出现情况非常特别 仅供参考 本人电脑 2021拯救者r9000p win11 串口
  • 遗传算法--旅行商问题(TSP问题)-Matlab

    1 问题 2 仿真过程 3 代码实现 1 旅行商问题 TSP问题 假设有一个旅行商人要拜访全国31个省会城市 它需要选择所要走的路径 路径的限制是每个城市只能拜访一次 而且最后要回到原来出发的城市 对路径选择的要求是 所选路径的路成为所有路
  • QT笔记-PDF阅读器(附带完整源码)- 导入PDF文件,在窗体上显示,并提取PDF的文字内容

    环境搭建 1 mupdf 1 17 0 source库 mupdf 1 17 0 source默认是VS2019的工程 由于示例用的是VS2017 所以需要用VS2017重新编译mupdf 1 17 0 source工程 生成LIB库文件
  • k8s部署redis一主两从三哨兵

    目录 一 部署思路 二 部署 1 编写namespace脚本 2 编写configmap脚本 3 编写secret脚本 4 编写StorageClass脚本 1 编写ServiceAccount ClusterRole ClusterRol
  • 建站心得之discuz门户程序相比ZBLOG具有哪些优势[图]

    以前我是采用discuz门户程序建站的 因为个人觉得 这套程序确实不错 而门户discuz门户也可以生成纯静态HTML文件 这对于我们有特殊要求的站长来说 非常重要 因为纯静态不仅可以提升网页的访问速度 还可以节省服务器成本 因为我们都知道
  • Java异步执行方法

    一 利用多线程 直接new线程 Thread t new Thread Override public void run longTimeMethod 使用线程池 private ExecutorService executor Execu
  • 机器学习实验1---决策树预测泰坦尼克数据集

    泰坦尼克号乘客数据集分析 ID3算法决策树 泰坦尼克问题是一个比较经典的案例 此次实验的目的在于用决策树进行乘客的生存预测 数据集中的具体字段为 数据 含义 PassengerId 乘客编号 Survived 是否幸存 Pclass 船票等
  • 为什么要做一款ERP软件——开源软件诞生7

    技术之外的探讨 第7篇 用日志记录 开源软件 的诞生 赤龙ERP开源地址 点亮星标 感谢支持 与开发者交流 kzca2000 码云 https gitee com redragon redragon erp GitHub https git
  • 微搭低代码学习之销售员销售目标采集系统开发

    四月二十三 春意渐浓 草木抽出新枝 鸟儿唱响欢融 花开满园 香气袭人 阳光明媚 人们心情舒畅 愿这美好的日子 伴随你一生 使用Notion AI提问 写一首关于4月23日的诗 文章目录 前言 一 销售员销售目标采集系统需求分析 一 需求背景
  • Matplotlib绘制混淆矩阵及colorbar标签设置

    本文提供一种通过Matplotlib绘制混淆矩阵并调整colorbar标签的程序 直接上程序 from sklearn metrics import confusion matrix import matplotlib pyplot as
  • JS从编译到运行代码的过程

    js运行分为两个阶段 具体AST树以及bytecode等名词看我上一篇文章 浏览器工作原理 1 编译阶段 js代码 gt AST树 代码被解析的过程 v8引擎内部会在堆内存帮助我们创建一个对象 GlobalObject gt GO 简称GO
  • JS闭包理解

    JS闭包 1 闭包 每次看到jQuery的时候 首先想到的就是闭包 这是个常谈的问题了 今天重新回忆了一下闭包 什么是闭包 当有一个函数想要访问另一个函数内部的变量 这个是访问不了的 所有我们要用闭包来访问 所以简单的来说 闭包就是连接函数
  • STM32使用IIC协议驱动0.96寸OLED屏

    IIC是常用的协议之一 它通过不同的地址来区分设备 并且端口需要是开漏模式 并且需要接上拉电阻 要使用IIC驱动OLED 首先要配置IIC void I2C Configuration void I2C InitTypeDef I2C In