【STM32】 硬件IIC 驱动SSD1306(0.96 OLED模块) -- 1/4 库函数 学习

这篇具有很好参考价值的文章主要介绍了【STM32】 硬件IIC 驱动SSD1306(0.96 OLED模块) -- 1/4 库函数 学习。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

为什么写本章节

经过了对于STM32的学习,但是大多数时候都还是以移植别人的历程然后修修改改为主。为了更好的巩固自己的学习能力。

所以此篇文章将会以记录我个人学习硬件IIC为案例,学习驱动IIC总线设备的能力。

首先第一步(准备)

1.《STM32F10x-中文参考手册》
2.《SSD1306芯片手册》

了解 硬件IIC 的工作原理

《STM32F10x-中文参考手册》—书签第24章
IIC的基本参数本章节暂时不做过多的描述,参考手册的24.1-24.3都有详细的讲解。
其中我们需要了解的是

  1.  ●I2C主设备功能
     ─ 产生时钟
     ─ 产生起始和停止信号
    
  2.  ●I2C从设备功能
     ─ 可编程的I2C地址检测
     ─ 可响应2个从地址的双地址能力
     ─ 停止位检测
    
  3.  ●支持不同的通讯速度
     ─ 标准速度(高达100 kHz)
     ─ 快速(高达400 kHz)
    
  4.  ●2个中断向量
     ─ 1个中断用于地址/数据通讯成功
     ─ 1个中断用于错误
    

IIC通讯的基本框图

【STM32】 硬件IIC 驱动SSD1306(0.96 OLED模块) -- 1/4 库函数 学习

【STM32】 硬件IIC 驱动SSD1306(0.96 OLED模块) -- 1/4 库函数 学习
IIC默认是工作在从模式的。从从模式切换到主模式,需要产生一个其实条件,为了产生正确的时序必须在I2C_CR2寄存器中设定该模块的输入时钟

  • 标准模式下为:2MHz
  • 快速模式下为:4MHz

一旦检测到起始条件,在SDA线上接收到的地址被送到移位寄存器

讲了这么多,那么STM32的标准库函数需要怎样写呢?

首先就是认识硬件IIC在STM32的寄存器是什么

寄存器 名称 寄存器的缩写
控制寄存器1 I2C_CR1
控制寄存器2 I2C_CE2
自身地址寄存器1 I2C_OAR1
自身地址寄存器2 I2C_OAR2
数据寄存器 I2C_DR
状态寄存器1 I2C_SR1
状态寄存器2 I2C_SR2
时钟控制寄存器 I2C_CCR
TRISE寄存器 I2C_TRISE

【STM32】 硬件IIC 驱动SSD1306(0.96 OLED模块) -- 1/4 库函数 学习
小贴士:就是寄存器的保留地址是不需要我们去理会的,每个寄存器的位,就相当于一个功能开关,我们需要什么功能。通过位操作打开/关闭就可以了

接下来就是在KEIL软件上的操作了

因为文章篇幅问题,创建工程、创建文件夹就忽略啦!需要的可以网络搜索教程/移植一个空白工程就可以了。

需要的头文件

头文件 名称
stm32f10x.h 标准库函数
stm32f10x_i2c.h 标准库函数
delay.h SysTick定时器编写的延时函数

学过STM32库函数工程,我们肯定是需要向初始化GPIO、时钟总线什么的。那我们此时应该先创建一个初始化的函数

Void I2C_Configuration(void)
{
		//创建GPIO,I2C1的结构体
		GPIO_InitTypeDef GPIO_InitStructure;				
		I2C_InitTypeDef I2C_InitStructure;				
		
		//使能挂载时钟总线
		RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
		
		//PB6——SCL PB7——SDA
		//配置GPIO的引脚模式、引脚脚位、引脚速度
		GPIO_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的结构体
		GPIO_Init(GPIOB, &GPIO_InitStructure);
		
		//初始化I2C1的寄存器默认数值
		I2C_DeInit(I2C1);
		//使能 I2C_Ack
		//指定地址位数为7bit/10bit
		//I2C的时钟速度
		//I2C的时钟占空比,一般为1/2 或者 9/16
		//IIC的模式
		//IIC设备自身地址,用于当从机的时候的访问地址
		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;
		
		//初始化I2C1结构体
		I2C_Init(I2C1, &I2C_InitStructure);
		//使能I2C1
		I2C_Cmd(I2C1, ENABLE);
}

至此,I2C1的初始化函数就写好了。那么我们要怎样通过IIC来和写数据呢?
因为OLED主要为显示输出,所以本章节以写入数据为案例;

在写IIC写函数的时候,我们需要先了解 stm32f10x_i2c.h的库函数里面有什么函数!

stm32f10x_i2c.h 函数表

函数名称 函数作用
void I2C_DeInit(I2C_TypeDef* I2Cx); 初始化I2C寄存器的默认值
void I2C_Init(I2C_TypeDef* I2Cx, I2C_InitTypeDef* I2C_InitStruct); 初始化I2C的GPIO结构体
void I2C_StructInit(I2C_InitTypeDef* I2C_InitStruct) 用默认值填充I2Cx的结构体
void I2C_Cmd(I2C_TypeDef* I2Cx, FunctionalState NewState); 启用/禁用I2Cx
void I2C_DMACmd(I2C_TypeDef* I2Cx, FunctionalState NewState); 启用/禁用I2Cx的DMA通道
void I2C_DMALastTransferCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); 指定下一个DMA传输是否为最后一个
void I2C_GenerateSTART(I2C_TypeDef* I2Cx, FunctionalState NewState); 生成I2Cx通讯开始条件
void I2C_GenerateSTOP(I2C_TypeDef* I2Cx, FunctionalState NewState); 生成I2Cx通讯停止条件
void I2C_AcknowledgeConfig(I2C_TypeDef* I2Cx, FunctionalState NewState); 开启/关闭I2C的应答特性
void I2C_OwnAddress2Config(I2C_TypeDef* I2Cx, uint8_t Address); 配置I2C的自身地址2
void I2C_DualAddressCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); 启用/禁止I2Cx双寻址模式
void I2C_GeneralCallCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); 启用/禁止I2Cx通用呼叫模式
void I2C_ITConfig(I2C_TypeDef* I2Cx, uint16_t I2C_IT, FunctionalState NewState); 启用/禁止指定I2C中断
void I2C_SendData(I2C_TypeDef* I2Cx, uint8_t Data); 通过I2Cx外设发送1字节的数据
uint8_t I2C_ReceiveData(I2C_TypeDef* I2Cx); 返回I2Cx外设最近接收到的数据
void I2C_Send7bitAddress(I2C_TypeDef* I2Cx, uint8_t Address, uint8_t I2C_Direction); 传输地址字节以选择从设备
uint16_t I2C_ReadRegister(I2C_TypeDef* I2Cx, uint8_t I2C_Register); 读取指定的I2C寄存器并返回它的值
void I2C_SoftwareResetCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); 指定I2C软件复位开关
void I2C_NACKPositionConfig(I2C_TypeDef* I2Cx, uint16_t I2C_NACKPosition); 选择主接收模式下指定的I2C NACK位置。*此功能在I2C主接收模式下有用
void I2C_SMBusAlertConfig(I2C_TypeDef* I2Cx, uint16_t I2C_SMBusAlert); 驱动SMBusAlert引脚为指定的I2C高或低
void I2C_TransmitPEC(I2C_TypeDef* I2Cx, FunctionalState NewState); 启用或禁用指定的I2C PEC传输
void I2C_PECPositionConfig(I2C_TypeDef* I2Cx, uint16_t I2C_PECPosition); 选择指定的I2C PEC位置
void I2C_CalculatePEC(I2C_TypeDef* I2Cx, FunctionalState NewState); 启用或禁用传输字节的PEC值计算
uint8_t I2C_GetPEC(I2C_TypeDef* I2Cx); 返回指定I2C的PEC值
void I2C_ARPCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); 启用/禁用指定I2C ARP
void I2C_StretchClockCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); 启用或禁用指定的I2C时钟拉伸功能
void I2C_FastModeDutyCycleConfig(I2C_TypeDef* I2Cx, uint16_t I2C_DutyCycle); 选择指定的I2C快模式占空比

当然,这些函数并不是需要全部应用在硬件IIC写函数上的,更重要的是

I2C State Monitoring Functions
只有知道I2C的状态,我们才能掌握I2C的运行的状态。
库函数的状态访问函数主要为三种,主要为

  1.  基本状态监视 Basic state monitoring
     ErrorStatus I2C_CheckEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT);					//	检查事件标志位
    
事件缩写 事件名称
I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED 从机发射地址匹配
I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED 从机接收地址匹配
I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED 从机发射第二地址匹配
I2C_EVENT_SLAVE_RECEIVER_SECONDADDRESS_MATCHED 从机接收第二地址匹配
I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED 从机通用呼叫匹配
I2C_EVENT_SLAVE_BYTE_RECEIVED 从机字节数据接收
I2C_EVENT_SLAVE_BYTE_RECEIVE 、I2C_FLAG_DUALF 从机字节数据接收 DUAL
I2C_EVENT_SLAVE_BYTE_RECEIVED 、I2C_FLAG_GENCALL 从机字节数据接收通用传呼标志位
I2C_EVENT_SLAVE_BYTE_TRANSMITTED 从机发送字节
I2C_EVENT_SLAVE_BYTE_TRANSMITTED 、 I2C_FLAG_DUALF 从机发送字节 DUAL
I2C_EVENT_SLAVE_BYTE_TRANSMITTED 、I2C_FLAG_GENCALL 从机字节发送 通用传呼
I2C_EVENT_SLAVE_ACK_FAILURE 从机应答失败
I2C_EVENT_SLAVE_STOP_DETECTED 从机停止信号检测
I2C_EVENT_MASTER_MODE_SELECT 主机模式选择
I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED 主机发送模式选择
I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED 主机接收模式选择
I2C_EVENT_MASTER_BYTE_RECEIVED 主机字节接收
I2C_EVENT_MASTER_BYTE_TRANSMITTING 主机字节数据发送时
I2C_EVENT_MASTER_BYTE_TRANSMITTED 主机字节数据发送以后
I2C_EVENT_MASTER_MODE_ADDRESS10 主机模式地址
  1.  高级状态监视 Advanced state monitoring
     uint32_t I2C_GetLastEvent(I2C_TypeDef* I2Cx); 								 //获取IIC总线的上一个事件
    
  2.   标志位状态监视 Flag-based state monitoring
     FlagStatus I2C_GetFlagStatus(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG);		//获取状态标志位
    

检查指定的I2C标志位是否设置。

FlagStatus I2C_GetFlagStatus(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG)
标志位 含义
I2C_FLAG_DUALF 双标志(从模式)
I2C_FLAG_SMBHOST SMBus主机头(从模式)
I2C_FLAG_SMBDEFAULT SMBus默认报头(从模式)
I2C_FLAG_GENCAL 通用调用头标志(从模式)
I2C_FLAG_TRA 发射机/接收机的标志
I2C_FLAG_BUSY 总线繁忙的标志
I2C_FLAG_MSL 主从标志
I2C_FLAG_SMBALERT SMBus警告标志
I2C_FLAG_TIMEOUT 超时或Tlow错误标志
I2C_FLAG_PECERR 接收标志中的PEC错误
I2C_FLAG_OVR 过载/不足标志(从模式)
I2C_FLAG_AF 应答错误警告
I2C_FLAG_ARLO 仲裁丢失标志(主模式)
I2C_FLAG_BERR 总线错误标志
I2C_FLAG_TXE 数据寄存器空标志(发射机)
I2C_FLAG_RXNE 数据寄存器不为空(接收器)标志
I2C_FLAG_STOPF 停止检测标志(从模式)
I2C_FLAG_ADD10 10位头发送标志(主模式)
I2C_FLAG_BTF 字节传输完成标志
I2C_FLAG_ADDR 地址发送标志(主模式)
I2C_FLAG_SB 开始位标志(主模式)

清除I2Cx的挂起标志。

void I2C_ClearFlag(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG))
缩写 标志
I2C_FLAG_SMBALERT SMBus警告标志
I2C_FLAG_TIMEOUT 超时或Tlow错误标志
I2C_FLAG_PECERR 接收标志中的PEC错误
I2C_FLAG_OVR 过载/不足标志(从模式)
I2C_FLAG_AF 应答失败标志
I2C_FLAG_ARLO 仲裁丢失标志(主模式)
I2C_FLAG_BERR 总线错误标志

获取中断源

ITStatus I2C_GetITStatus(I2C_TypeDef* I2Cx, uint32_t I2C_IT)
中断源 含义
I2C_IT_SMBALERT SMBus警告标志
I2C_IT_TIMEOUT 超时或Tlow错误标志
I2C_IT_PECERR 接收标志中的PEC错误
I2C_IT_OVR 过载/不足标志(从模式)
I2C_IT_AF 应答失败的标志
I2C_IT_ARLO 仲裁丢失标志(主模式)
I2C_IT_BERR 总线错误标志
I2C_IT_TXE 数据寄存器空标志(发射机)
I2C_IT_RXNE 数据寄存器不为空(接收器)标志
I2C_IT_STOPF 停止检测标志(从模式)
I2C_IT_ADD10 10位头发送标志(主模式)
I2C_IT_BTF 字节传输完成标志
I2C_IT_ADDR 地址发送标志(主模式)“ADSL” 地址匹配标志(从模式)“ENDAD”
I2C_IT_SB 开始位标志(主模式)

清除中断标志位

void I2C_ClearITPendingBit(I2C_TypeDef* I2Cx, uint32_t I2C_IT)
标志位 含义
I2C_IT_SMBALERT SMBus警报中断
I2C_IT_TIMEOUT 超时或Tlow错误中断
I2C_IT_PECERR 接收中断中的PEC错误
I2C_IT_OVR 溢出/不足运行中断(从模式)
I2C_IT_AF 应答失败中断
I2C_IT_ARLO 仲裁丢失中断(主模式)
I2C_IT_BERR 总线错误中断
IIC发送数据8步曲

1.判断IIC总线是否忙
	👇
2.产生IIC的开始信号
	👇
3.判断主机\从机模式
	👇
4.发送地址
	👇
5.判断地址数据是否传输完成
	👇
6.发送数据
	👇
7.判断发送数据是否完成
	👇
8.发送停止信号
void I2C_WriteByte(uint8_t addr,uint8_t data)
{
	//检测IIC的总线忙,如果忙则阻止程序运行
	while( I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY) );
	//产生IIC启动信号
    I2C_GenerateSTART(I2C1, ENABLE);
	//检查主机模式是否选择完成
	while( !I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT) );
	//发送8位数据, 向I2C1发送oled地址,主从模式
    I2C_Send7bitAddress(I2C1, OLED_ADDRESS, I2C_Direction_Transmitter);	
	 //检查主机发送字节是否结束
	while( !I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) );
	//发送addr 寄存器的地址
	I2C_SendData(I2C1, addr);													
	//检查主机字节发送是否结束
	while( !I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTING) );		
	//通过IICx发送数据	
	I2C_SendData(I2C1, data);													
	//检查字节发送是否结束
	while( !I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED) );
	//停止信号结束		
	I2C_GenerateSTOP(I2C1, ENABLE);												
}

备注文章来源地址https://www.toymoban.com/news/detail-427366.html

  1. 本文章是学习记录,如有不足之处或者错误之处欢迎各位指正批评😀;
  2. 部分文章内容来源于手册和网络,如有侵权请联系我删除。

到了这里,关于【STM32】 硬件IIC 驱动SSD1306(0.96 OLED模块) -- 1/4 库函数 学习的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

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

    IIC是常用的协议之一,它通过不同的地址来区分设备,并且端口需要是开漏模式,并且需要接上拉电阻  要使用IIC驱动OLED,首先要配置IIC 然后编写写入函数 ErrorStatus I2C_CheckEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT) 为判断事件的函数 有以下多种事件 OLED初始化 上图分别为 (起始位

    2024年02月03日
    浏览(17)
  • STM32F103硬件IIC控制4针0.96寸OLED显示屏

    OLED使用的0.96寸四针屏幕,以下直接看实际操作。 使用PCtoLCD2002软件提取OLED字模。 注意红色方框的选项内容,不要选错了,选错会导致烧录程序后无法显示。 此为硬件IIC,如果使用过我的模拟IIC控制程序可直接看 void OLED_Write_Command(unsigned char IIC_Command); void OLED_Write_Data(unsig

    2024年02月02日
    浏览(22)
  • STM32配合CubeMX硬件SPI驱动0.96寸OLED

    目录 一、简单介绍 1.1 OLED 1.2 SPI协议 接口 优点 缺点 数据传输 二、实战 2.1 工程配置 2.2 测试工程 2.3 波形分析 三、驱动OLED 3.1 初始化代码 3.2 清屏函数 3.3 设置坐标函数 3.4 显示字符函数 3.5 显示字符串函数 3.6 显示图片函数 附录 驱动代码文件 oled.c oled.h f6x8.h 1.1 OLED 有机发

    2024年02月02日
    浏览(16)
  • STM32配合cubeMX硬件I2C驱动0.96寸OLED

    目录 一、简单介绍 1.1   OLED 1.2   I2C协议 二、实战 2.1 工程配置 2.2 测试工程 2.3 波形分析 三、驱动OLED 3.1 初始化代码 3.2 清屏函数 3.3 设置坐标函数 3.4 显示字符函数 3.5 显示字符串函数 3.6 显示图片函数 附录 驱动代码文件 oled.c oled.h f6x8.h 有机发光二极管 (英语:Organic

    2024年02月08日
    浏览(17)
  • 0.96寸OLED(SSD1306)屏幕显示(二)——超长文字水平滚动

    (一)基础功能介绍 (二)超长文字水平滚动 (三)屏幕垂直水平滚动 文章目录 前言 一、内置水平滚动方法 二、自定义水平滚动方法 总结 最近,我突发奇想去翻阅了一些我本科期间所做的一些小项目,发现都挺有意思的!当年做这些项目的时候可走了很多弯路,所以想

    2023年04月08日
    浏览(16)
  • stm32使用模拟IIC控制四针0.96寸OLED

    STM32系列模拟IIC控制0.96寸OLED方法 首先说为什么要采用模拟IIC来控制OLED,采用STM32系列单片机硬件IIC时有可能出现程序死掉的情况,我遇到的情况是与程序while的使用有关(听说原因很随机)。这个时候我们可以采用两个GPIO来模拟IIC通信控制OLED屏幕。顺带说一下OLED的使用原理

    2024年02月14日
    浏览(33)
  • 0.96OLED 4针IIC STM32-HAL库版本(附源码)

    OLED源码放在文章末,有需要自己下滑取用即可。关于如何移植到自己定义的引脚上也做了说明。 另外,本人在代码中封装了一个OLED显示的接口,方便开发者对字符显示位置的快速定位,以及像C语言printf()函数一样在屏幕上进行int,float,char等变量的格式化输出。非常方便实用

    2023年04月26日
    浏览(66)
  • 【正点原子STM32】OLED实验(OLED显示屏、ATK_OLED模块,OLED驱动原理、SSD1306工作时序(8080时序),OLED驱动芯片,字符显示原理、字模生成软件,OLED基本驱动步骤)

    一、OLED显示屏介绍 1.1、ATK_OLED模块介绍 1.2、ATK_OLED模块引脚说明(8080并口模式) 1.3、OLED模块硬件连接 二、OLED驱动原理 2.1、SSD1306工作时序(8080时序) 2.2、SSD1306工作时序(8080时序)–写时序 三、OLED驱动芯片简介 3.1、什么是GRAM? 3.2、什么是页地址模式? 3.3、解决显示覆盖问题

    2024年03月13日
    浏览(23)
  • STM32F103模拟IIC控制4针0.96寸OLED显示屏

    OLED,即有机发光二极管(Organic Light-Emitting Diode),又称为有机电激光显示(Organic Electroluminesence Display, OELD)。OLED由于同时具备自发光,不需背光源、对比度高、厚度薄、视角广、反应速度快、可用于挠曲性面板、使用温度范围广、构造及制程较简单等优异之特性,被认为

    2023年04月24日
    浏览(18)
  • 0.96OLED STM32 SPI驱动(一)

    闲来无聊,翻出了一个OLED,本来想串流做个小显示器用,感觉难度太大。将就变成了下面这 个样子,姑且叫火柴人大乱斗之OLED。 火柴人之OLED 分两步走,先驱动OLED能显示一副图片,本篇讲述此内容。 第二步显示动画,放在下一篇中讲。 查资料得到此OLED为SPI通信,SCL对应连

    2024年02月06日
    浏览(20)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包