stm32f407硬件IIC/I2C驱动OLED屏幕(标准库 | 代码经测试可用)

注:本文仅是记录学习。我也会在下文中分享一下心得。

一,概述

OLED驱动方式有8080、6800、3线/4线SPI以及IIC,能够显示字符、汉字的图片,无字库需通过取模软件获取显示内容数组。本次实验使用的是硬件IIC通信协议,SSD1306驱动芯片的OLED    

二,实验材料

1,0.96寸OLED屏幕(四针IIC驱动)

2,stm32f407vet6主控

3,杜邦线

三,接线

接线说明
stm32f407vet6OLED屏幕
VCCVCC
SCLSCL
SDASDA
GNDGND

四,代码讲解

IO引脚配置

这里使用的stm32f4的IIC2,这里与F1系列不同是F4需要使用GPIO_PinAFConfig函数!

void IIC_init(void)//PB10-->SCL || PB11-->SDA
{
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);

	GPIO_InitTypeDef IIC1_IO;
	IIC1_IO.GPIO_Mode = GPIO_Mode_AF;
	IIC1_IO.GPIO_PuPd = GPIO_PuPd_NOPULL; 
	IIC1_IO.GPIO_OType = GPIO_OType_OD;
	IIC1_IO.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
	IIC1_IO.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &IIC1_IO);

	GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_I2C2);	//这里就是F1和F4的不同!!!
	GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_I2C2);
	
	I2C_InitTypeDef IIC1;
	IIC1.I2C_Ack = I2C_Ack_Enable;	//回复应答
	IIC1.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;	//作为从机时,自己的地址位数
	IIC1.I2C_ClockSpeed = 100*1000;	//IIC速率:0-400Khz(限制IIC速率的原因是弱上拉,因为高电平是读取数据,当弱上拉回调不及时则会影响数据的读取)
	IIC1.I2C_DutyCycle = I2C_DutyCycle_2;	//如果上面参数速率在100khz-400khz,则这里要必须要选
	IIC1.I2C_Mode = I2C_Mode_I2C;  //选择IIC模式
	IIC1.I2C_OwnAddress1 = 0x00;	//作为从机的地址
	I2C_Init(I2C2, &IIC1);

	I2C_Cmd(I2C2, ENABLE);
}

写命令函数

void OLED_WriteCommand(uint8_t cmmand)  //在控制位选项上,选择不连续模式,并且片选为命令(DC为0)
{
	while(SET == I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY));	//是否忙碌
	
	I2C_GenerateSTART(I2C2, ENABLE);	//起始位
	while(I2C_CheckEvent(I2C2 , I2C_EVENT_MASTER_MODE_SELECT) != SUCCESS);
	
	
	I2C_Send7bitAddress(I2C2, 0x78, I2C_Direction_Transmitter); //发送地址
	while(I2C_CheckEvent(I2C2 , I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) != SUCCESS);
	
	
	I2C_SendData(I2C2, 0x00);	//发送控制位
	while(I2C_CheckEvent(I2C2 , I2C_EVENT_MASTER_BYTE_TRANSMITTING) != SUCCESS);
	

	I2C_SendData(I2C2, cmmand);	//发送数据
	while(I2C_CheckEvent(I2C2 , I2C_EVENT_MASTER_BYTE_TRANSMITTED) != SUCCESS);
	
	
	I2C_GenerateSTOP(I2C2 , ENABLE);
}

写数据函数

void OLED_WriteData(uint8_t Data)  //在控制位选项上,选择不连续模式,并且片选为数据(DC为1)
{
	while(SET == I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY));	//是否忙碌
	I2C_GenerateSTART(I2C2, ENABLE);	//起始位
	while(I2C_CheckEvent(I2C2 , I2C_EVENT_MASTER_MODE_SELECT) != SUCCESS);
	
	
	I2C_Send7bitAddress(I2C2, 0x78, I2C_Direction_Transmitter); //发送地址
	while(I2C_CheckEvent(I2C2 , I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) != SUCCESS);
	
	
	I2C_SendData(I2C2, 0x40);	//发送控制位
	while(I2C_CheckEvent(I2C2 , I2C_EVENT_MASTER_BYTE_TRANSMITTING) != SUCCESS);
	

	I2C_SendData(I2C2, Data);	//发送数据
	while(I2C_CheckEvent(I2C2 , I2C_EVENT_MASTER_BYTE_TRANSMITTED) != SUCCESS);
	
	
	I2C_GenerateSTOP(I2C2 , ENABLE);

}

主函数

记得调用更新函数,否则不会显示!!

int main(void)
{
	OLED_init();
	OLED_Clear();
	OLED_Printf(0,0,"%s","hello world!");
	OLED_Printf(0,16,"%s","1234567890");
	OLED_Update();
	while(1);
}	

硬件IIC的使用就是上面的代码,后续代码都是基于上面两个命令代码,源码在文末链接。

五,实验效果

本文是基于江科大stm32F1系列的模拟IIC驱动OLED屏幕仿写的STM32F4的硬件IIC驱动OLED屏幕,取模以及基本的函数使用说明可以借鉴江科大OLED库的使用方法。

江科大B站直达:http://【[模块教程] 第1期 0.96寸OLED显示屏】 https://www.bilibili.com/video/BV1EN41177Pc/?share_source=copy_web&vd_source=6294aa5a8922169865879dd832a253c2

OLED源码
链接:https://pan.baidu.com/s/12CIHm-Ti0XE0pLBTOt7XHg 
提取码:2486 

### STM32F407OLED相关的标准库开源项目资源 对于STM32F407微控制器与OLED显示屏的相关开发,可以利用已有的开源项目来快速搭建环境并完成功能验证。以下是几个推荐的资源及其特点: #### 1. **基于STM32固件库的标准库移植** - zzwei 的开源项目提供了针对STM32系列的OLED驱动支持,特别是适配了SSD1306驱动芯片的128×64分辨率OLED屏[^1]。 - 此项目的重点在于GUI库的移植,能够满足基本的图形绘制需求。 - 如果目标硬件使用的是I2C接口连接OLED,则可以直接参考其初始化代码以及通信协议实现。 #### 2. **Gitee上的模板工程** - Gitee上有一个名为`STM32F407_LVGL_Template_MSP3526`的开源项目[^2]。 - 这个项目虽然主要面向LVGL图形界面库的应用场景,但也包含了部分基础组件的支持,比如OLED屏幕的基础驱动逻辑。 - 用户可以通过研究此项目中的外设配置方法,学习如何将类似的显示模块集成至自己的应用框架之中。 #### 3. **HAL库为基础的空间人与时钟演示案例** - 另一开源实例展示了通过HAL库控制OLED屏幕渲染空间人物像及时钟的功能[^3]。 - 尽管它是围绕STM32F103设计的,但由于两者均属于STMicroelectronics家族成员,在寄存器定义等方面存在较高兼容度。 - 对于希望采用更现代化API风格的人来说,这是一个不错的起点;不过需要注意调整GPIO映射关系以匹配具体板卡布局。 #### 4. **易用性强的整体解决方案** - 文档提到此类方案具备良好可扩展性的特性[^4]。 - 开发者仅需复制必要文件夹进入既有工程项目目录下,并按照指示修改少量参数设定项即可启动服务端口监听等功能单元测试流程。 #### 5. **关于I²C通讯细节补充说明** - 在实际编码过程中还需要特别留意有关I²C总线的操作规范[^5]: ```c void I2C_Start(void){ SDA_OUT(); //设置SDA为输出模式 SCL_High(); delay_us(4); SDA_High(); delay_us(4); SDA_Low(); while(SCL_Read()==LOW); } uint8_t I2C_Send_Byte(uint8_t byte){ uint8_t i,ack; for(i=0;i<8;i++){ (byte&0x80)?SDA_High():SDA_Low(); byte<<=1; SCL_Toggle(); } SCL_Low(); ack=SDA_Read(); SCL_High(); return ack; } void I2C_Stop(void){ SDA_LOW(); delay_us(4); SCL_HIGH(); delay_us(4); SDA_HIGH(); } ``` 上述片段体现了典型的主控节点向从属设备发起对话序列所遵循的一般步骤。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值