STM32V107VCT6,基于HAL库的用IO口模拟I2C的0.96寸OLED驱动

本文介绍如何使用STM32F107VCT6单片机,基于HAL库通过IO口模拟I2C方式驱动0.96寸OLED显示屏。文中详细阐述了所需的开发环境、配置步骤,以及关键代码示例,包括OLED初始化、数据写入等函数实现。

前言

作为一个初学者,当然希望有比较好的范例可以学习,但在优快云和众多家的单片机学习网站,没发现现成的I2C模拟接口的HAL库的0.96寸的OLED驱动,经过努力,把这个代码调试出来,为此,基于技术共享的前提以及给后来者多个参考,把代码发表出来,大家互相学习指正。

在这里插入图片描述


一、相应的环境

单片机:STM32F107VCT6
开发环境:MDKV5.28
库函数:HAL库
开发板:Kicad自画开发板一块
OLED模块:PDD购买,7脚,用I2C接口。注意:RES需要上拉 ,DC/CS需要接地。否则不显示。

二、使用步骤

1.参考资料

基于普中开发板的扩展实验 ,点亮OLED的显示实验(基于标准库,4线SPI的模式,OLED的驱动部分大部分都是直接用的);基于STEVE大神的硬件I2C的OLED的HAL库代码(帮助不算特别大,大致可以看看结构,理解下);基于investspace的”STM32f429使用0.96 oled“,参考了I2C模拟口的写函数(数据和命令),最终实现了。

2.代码示例

代码如下(示例):


oled.h


#ifndef _oled_H
#define _oled_H

#include “system.h”
#include “stdlib.h”
#include “i2c.h”

//OLED模式设置
//0:4线串行模式
//1:并行8080模式
//2:IIC模式
#define OLED_MODE 2

#define SIZE 16
#define XLevelL 0x00
#define XLevelH 0x10
#define Max_Column 128
#define Max_Row 64
#define Brightness 0xFF
#define X_WIDTH 128
#define Y_WIDTH 64

#if OLED_MODE==0
//OLDE-SPI4线控制管脚定义
#define OLED_CS PDout(3)
#define OLED_RST PDout(4)
#define OLED_DC PDout(5)
#define OLED_SCL PDout(6)
#define OLED_SDA PDout(7)
#endif

#if OLED_MODE==1
//OLDE-8080总线控制管脚定义
#define OLED_CS PDout(3)
#define OLED_RST PDout(4)
#define OLED_DC PDout(5)
#define OLED_WR PDout(6)
#define OLED_RD PDout(7)

#define OLED_DATA_OUT(x) GPIO_Write(GPIOC,x);//输出
#endif

#if OLED_MODE==2
//OLDE-IIC总线控制管脚定义
void Write_IIC_Command(unsigned char IIC_Command); /写命令/
void Write_IIC_Data(unsigned char IIC_Data); /写数据/

#endif

#define OLED_CMD 0 //写命令
#define OLED_DATA 1 //写数据

//OLED控制用函数
void OLED_WR_Byte(u8 dat,u8 cmd);
void OLED_Display_On(void);
void OLED_Display_Off(void);
void OLED_Set_Pos(unsigned char x, unsigned char y);
void OLED_Init(void);
void OLED_Refresh_Gram(void);
void OLED_Clear(void);
void OLED_DrawPoint(u8 x,u8 y,u8 t);
void OLED_Fill(u8 x1,u8 y1,u8 x2,u8 y2,u8 dot);
void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 size,u8 mode);
void OLED_ShowNum(

### 使用HAL通过模拟I2C驱动OLED的相关代码 #### 初始化配置 为了实现STM32 HAL下的模拟I2C功能,通常需要在`oled.h`中定义相关的宏来操作GPIO引脚的状态。以下是具体的初始化和相关函数的实现: ```c // oled.h 文件中的 GPIO 宏定义 #define OLED_SCL_Clr() HAL_GPIO_WritePin(GPIOF, GPIO_PIN_0, GPIO_PIN_RESET) // SCL 清零 #define OLED_SCL_Set() HAL_GPIO_WritePin(GPIOF, GPIO_PIN_0, GPIO_PIN_SET) // SCL 设置高电平 #define OLED_SDA_Clr() HAL_GPIO_WritePin(GPIOF, GPIO_PIN_1, GPIO_PIN_RESET) // SDA 清零 #define OLED_SDA_Set() HAL_GPIO_WritePin(GPIOF, GPIO_PIN_1, GPIO_PIN_SET) // SDA 设置高电平 ``` 上述宏用于控制SCL和SDA线的状态,从而完成I2C协议所需的信号传输。 --- #### 延时与基础I2C函数 在`oled.c`文件中,需提供一些基本的功能函数以支持I2C通信过程中的延迟、启动条件、停止条件以及数据发送等功能。 ```c #include "oled.h" // 延时函数 void IIC_delay(void) { for (volatile int i = 0; i < 50; i++); // 软件延时 } // I2C 启动信号 void I2C_Start(void) { OLED_SDA_Set(); // 将 SDA 线置为高电平 OLED_SCL_Set(); IIC_delay(); OLED_SDA_Clr(); // 下拉 SDA 线至低电平 IIC_delay(); OLED_SCL_Clr(); // 下拉 SCL 线至低电平 } // I2C 结束信号 void I2C_Stop(void) { OLED_SDA_Clr(); // 将 SDA 线保持为低电平 OLED_SCL_Set(); // 上拉 SCL 线至高电平 IIC_delay(); OLED_SDA_Set(); // 上拉 SDA 线至高电平 } // 发送一个字节的数据 void Send_Byte(u8 dat) { u8 ack; u8 i; for (i = 0; i < 8; i++) { // 循环发送每一位数据 if ((dat & 0x80) >> 7) { OLED_SDA_Set(); // 如果当前位为1,则上拉SDA } else { OLED_SDA_Clr(); // 如果当前位为0,则下拉SDA } dat <<= 1; // 左移一位准备下一个bit OLED_SCL_Set(); // 拉高SCL使能数据传输 IIC_delay(); OLED_SCL_Clr(); // 拉低SCL等待下一周期 } OLED_SDA_Set(); // 松开SDA总线以便接收ACK/NACK OLED_SCL_Set(); // 拉高SCL检测ACK响应 IIC_delay(); ack = HAL_GPIO_ReadPin(GPIOF, GPIO_PIN_1); // 读取SDA状态判断是否收到ACK OLED_SCL_Clr(); // 拉低SCL结束本次传输 } ``` 以上实现了I2C的基础功能模块,包括启动信号、停止信号以及单字节数据的发送[^2]。 --- #### 数据写入OLED显示屏 针对OLED的具体应用需求,在`oled.c`中还需进一步封装向OLED设备写入命令或数据的操作逻辑。 ```c // 写入一个字节到OLED void OLED_WR_Byte(u8 dat, u8 mode) { switch (mode) { case 0: // 控制模式(Command) I2C_Start(); Send_Byte(OLED_ADDRESS << 1 | 0); // 设备地址左移并附加写标志 Send_Byte(0x00); // Co=0, D/C#=0 表明后续为指令 Send_Byte(dat); break; case 1: // 数据模式(Data) I2C_Start(); Send_Byte(OLED_ADDRESS << 1 | 0); // 设备地址左移并附加写标志 Send_Byte(0x40); // Co=0, D/C#=1 表明后续为数据 Send_Byte(dat); break; } I2C_Stop(); } ``` 此函数区分了两种不同的写入模式:一种是写入控制命令;另一种则是写入实际显示数据[^4]。 --- #### 主程序调用示例 最后,在主程序`main.c`中可以通过简单的API调用来完成OLED屏幕的初始化及文字显示工作。 ```c #include "oled.h" int main(void) { HAL_Init(); // 初始化HAL SystemClock_Config(); // 配置系统时钟 OLED_Init(); // 初始化OLED屏幕 OLED_ShowString(1, 1, "Hello World!!!"); // 显示字符串 while (1) {} } ``` 该部分展示了如何利用前述构建好的底层驱动框架快速搭建出一个能够正常工作的项目实例[^1]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

springdong1978

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值