【蓝桥杯——物联网设计与开发】Part2:OLED

目录

一、OLED

(1)资源介绍

🔅原理图

🔅驱动原理

[(2)STM32CubeMX 软件配置](#(2)STM32CubeMX 软件配置)

(3)代码编写

(4)实验现象

二、OLED接口函数封装

[🟡️OLED_Write 函数代码实现](#🟡️OLED_Write 函数代码实现)

[🟡️OLED_Init 函数代码补全](#🟡️OLED_Init 函数代码补全)

三、踩坑日记

[(1)OLED 显示问题](#(1)OLED 显示问题)

(2)显示对齐问题


一、OLED

(1)资源介绍

🔅原理图

新版蓝桥杯物联网竞赛实训平台中,有一块 0.91 寸的 OLED;

🟢️OLED原理图如图1所示:
图1 OLED电路原理图

通过电路图连接可知,引脚资源配置情况为:

OLED MCU
SCL PB6
SDA PB7
[表1 引脚资源配置情况]

🔅驱动原理

在原理图中,模块已板载 SCLSDA 线的上拉电阻MCU 的引脚只需配置为开漏输出模式,即可接入模块。当有其他 I2C 从机接入同一 I2C 总线时,由于这里已经带有上拉电阻,所以无需另行外接 I2C 总线的上拉电阻,(在下一章的AT24C02中会提到)简化了系统的硬件连接复杂度。

模块作为 I2C 从机,其地址编码为:0111 10 [SA0] [RW] 。其中,SA0 属于硬件地址选择位,其电平状态直接决定地址编码中的 SA0 取值。当 SA0 引脚外接高电平时,地址中的 SA0 即为 1 ;反之,若 SA0 引脚外接低电平时,地址中的 SA0 则为 0 。模块出厂时,默认 SA0 引脚接低电平,用户如有需求,可自行通过调整模块背面的电阻连接,将 SA0 置为高电平。如此一来,基于地址编码的唯一性限制,++同一 I2C 总线最多能够同时挂接 2 个该型号的 OLED模块++,用户在进行系统扩展时需留意这一特性。

因此,使用 I2C 驱动 OLED时:

  • **写地址:**0x78;
  • **读地址:**0x79;

⚠️在赛点资源包中,官方提供了 OLED的底层驱动代码,这里不再赘述;但函数

**void OLED_Write(uint8_t ucType, uint8_t ucData)**需要自行补充编写;

驱动原理部分内容参考博客:

0.96寸与0.91寸OLED显示屏详解与驱动编程指南-CSDN博客

(2)STM32CubeMX 软件配置

🔅"工程建立、时钟树配置、Debug 串行线配置、代码生成配置" 在下文中有讲解,这里不再赘述❗️

【蓝桥杯------物联网设计与开发】Part1:GPIO-CSDN博客https://blog.csdn.net/m0_63116406/article/details/144894900?sharetype=blogdetail&sharerId=144894900&sharerefer=PC&sharesource=m0_63116406&spm=1011.2480.3001.8118

1️⃣点击左侧 "Connectivity" → 选择 "I2C1" → 模式选择 "I2C"I2C总线模式);

⚠️此处模式参数默认,请根据题意或项目需求进行修改;
图2 I2C配置

2️⃣生成代码;

3️⃣将赛点资源数据包中的参考代码:"font.h""oled.h""oled.c""i2c.h" 添加到工程;

(3)代码编写

🟢️main 函数

cpp 复制代码
/* USER CODE BEGIN Includes */
#include <stdio.h>
#include "oled.h"
/* USER CODE END Includes */
/* USER CODE BEGIN PV */
uint8_t puc_oled[17];	// OLED 显示存储区
/* USER CODE END PV */
/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_I2C1_Init();
  /* USER CODE BEGIN 2 */
	OLED_Init();	// OLED 初始化
	OLED_Clear();	// OLED 清屏,去除初始噪点
	sprintf((char*)puc_oled, "123456789ABCDEFG");	// 将需要显示的字符串格式化到显示存储区
	OLED_ShowString(0, 0, puc_oled, 16);					// 第0行显示
	sprintf((char*)puc_oled, "  Hello World!  ");
	OLED_ShowString(0, 2, puc_oled, 16);					// 第2行显示
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

(4)实验现象

OLED 一共显示两行,第一行显示字符串 "123456789ABCDEFG" ,第二行显示 "Hello World!"


二、OLED接口函数封装

🟡️OLED_Write函数代码实现

cpp 复制代码
void OLED_Write(uint8_t ucType, uint8_t ucData)
{
	uint8_t pData[2];		// 定义数组存储传输的数据
	pData[0] = ucType;	// 数据类型:数据 或者 命令
	pData[1] = ucData;	// 数据本身
	HAL_I2C_Master_Transmit(&hi2c1, 0x78, pData, 2, 10);	// 调用库函数使用硬件 I2C 进行传输		
}

🟡️OLED_Init函数代码补全

⚠️该函数需要添加一句代码,以稳定 OLED

HAL_Delay(100);

如图3,在 OLED 的芯片手册上也有提到,在上电流程最后,推荐延迟100ms

cpp 复制代码
void OLED_Init(void)
{
//OLED_Write(TYPE_COMMAND, 0xA0);       /* 段重映射, b0:0,0->0(复位值); */
  OLED_Write(TYPE_COMMAND, 0xA1);       /* 段重映射, b0:1,0->127 */

  OLED_Write(TYPE_COMMAND, 0xA8);       /* 复用比 */
  OLED_Write(TYPE_COMMAND, 0x1F);       /* 0F~3F,16MUX~64MUX(复位值) */

//OLED_Write(TYPE_COMMAND, 0xC0);       /* COM扫描方向, b3:0,正常模式(复位值) */
  OLED_Write(TYPE_COMMAND, 0xC8);       /* COM扫描方向, b3:1,反转模式 */

  OLED_Write(TYPE_COMMAND, 0xDA);       /* COM引脚配置 */
  OLED_Write(TYPE_COMMAND, 0x00);       /* D4:0,顺序;1,交替(复位值) */

  OLED_Write(TYPE_COMMAND, 0x8D);       /* 充电泵 */
  OLED_Write(TYPE_COMMAND, 0x14);       /* D2:0,禁止(复位值);1,允许 */

  OLED_Clear();                         /* 清除屏幕 */
  OLED_Write(TYPE_COMMAND, 0xAF);       /* 开启显示 */
	
	HAL_Delay(100);	// 延迟100ms
}

图3 芯片手册

三、踩坑日记

(1)OLED显示问题

⚠️++该 OLED 像素点为128 × 32:++

  • Y轴: 显示大小为 16 时,最多显示 2 排;显示大小为 8 时,最多显示 4排;
  • X轴: ++最多显示 16个字符++ ,由于sprintf会在字符串后面添加 '\0' ,所以 OLED 显示数组 pucBuf 大小应该为 17

(2)显示对齐问题

在蓝桥杯赛题上,会对 OLED显示的字符有相对位置要求,如下图所示:
图4 赛题

根据上文对 OLED 的显示分析,一行最多有 16 个字符。那么根据这一特性,我们可以先写入一排大小为 8 的字符串 "123456789ABCDEFH",可以根据此字符串进行居中显示等;

显示偶数个字符时,左右的空位刚好相等,能够满足完全居中;

显示奇数个字符时,左边空位数 = 右边空位数 - 1,满足相对居中;

相关推荐
小仇学长10 分钟前
Linux内核编程(二十一)USB应用及驱动开发
linux·驱动开发·usb
Zevalin爱灰灰16 分钟前
FreeRTOS从入门到精通 第七章(FreeRTOS列表和列表项)
stm32·操作系统·freertos
2301_805962932 小时前
NRF24L01模块STM32通信-通信初始化
stm32·单片机·嵌入式硬件
武汉海翎光电2 小时前
电化学气体传感器在物联网中的精彩表现
物联网
阳光宅男@李光熠3 小时前
【电子通识】PWM驱动让有刷直流电机恒流工作
单片机·嵌入式硬件
跳河轻生的鱼4 小时前
海思Linux-DEMO(1)-sample_venc(h265,h264)视频流文件的获取
linux·驱动开发·学习
半个番茄4 小时前
STM32 : 奈奎斯特-香农采样定理
网络·stm32·单片机
IT信息技术学习圈6 小时前
CSP初赛知识学习计划(第二天)
单片机·嵌入式硬件·学习
硬件技术我知道10 小时前
产品 防尘防水IP等级 划分与实验方法
网络·人工智能·嵌入式硬件·物联网·计算机视觉·硬件工程·智慧城市
清弦墨客10 小时前
【蓝桥杯】43709.机器人繁殖
python·算法·蓝桥杯·机器人·程序算法