STM32——显示温湿度

温湿度模块认识

一、DHT11 整体基础认知

1. 产品简介

DHT11 是一款数字式温湿度复合传感器 ,内置专用测温测湿元件与 AD 转换电路,无需外接模数转换,直接输出数字信号,单片机可直接读取解析。

2. 核心电气参数

  • 工作电压:3.3V ~ 5.5V(STM32 优先使用 3.3V 供电)
  • 湿度测量范围:20% RH ~ 90% RH,精度 ±5% RH
  • 温度测量范围:0℃ ~ 50℃,精度 ±2℃
  • 通信方式:单总线通信(仅 1 根数据线完成双向通信)
  • 最小读取间隔:1000ms(禁止高频连续读取,易损坏传感器)
  • 数据输出格式:固定40 位串行数据

3. 实物引脚定义(三线制)

引脚序号 引脚名称 功能说明
1 VCC 电源正极,接 3.3V/5V
2 DATA 双向通信数据线,连接单片机通用 GPIO 口
3 GND 电源负极,公共地

4. 上拉电阻原理

DATA 数据线默认需要外接4.7K~10KΩ 上拉电阻至 VCC

  • 作用:空闲状态下数据线保持高电平,保证通信电平稳定
  • 市面上成品 DHT11 模块已经板载上拉电阻,用户接线无需额外焊接

二、标准实物接线示意图

接线规则(STM32F103 单片机)

  1. DHT11-VCC → 单片机3.3V电源引脚
  2. DHT11-GND → 单片机GND公共地
  3. DHT11-DATA → 单片机任意空闲 GPIO 引脚(如 PA2、PB5)

接线注意事项

  1. 电源正负极严禁接反,直接烧毁传感器
  2. 数据线布线尽量简短,长距离走线极易受电磁干扰
  3. 传感器必须与单片机共地,否则通信完全失效
  4. 远离电机、电源模块、蜂鸣器等强干扰元器件

三、40 位原始数据帧格式

DHT11 一次完整通信,连续发送5 个字节 = 40 位数据,数据排列顺序固定不变:

字节顺序 数据含义 备注
第一字节 湿度整数部分 有效湿度数值
第二字节 湿度小数部分 DHT11 固定为 0,无小数精度
第三字节 温度整数部分 有效温度数值
第四字节 温度小数部分 DHT11 固定为 0,无小数精度
第五字节 数据校验和 数据校验纠错使用

校验和计算公式

校验和 = 湿度整数 + 湿度小数 + 温度整数 + 温度小数读取数据后必须进行校验,校验一致代表数据有效,不一致判定为通信干扰,直接丢弃数据。

数值读取规则

最终实际温湿度:环境湿度 = 第一字节数值环境温度 = 第三字节数值

四、单总线完整通信时序

整个通信流程分为4 大阶段,时序严格固定,延时误差超过 20μs 就会读取失败。

阶段 1:主机(STM32)发送起始信号

  1. 单片机将 DATA 数据线拉低电平 ,持续保持 ≥18ms
  2. 主机释放总线,将 DATA拉高电平 ,持续 20~40μs
  3. 起始信号发送完成,单片机 IO 切换为输入模式,等待传感器应答

时序逻辑:长低电平唤醒 DHT11,短暂高电平通知传感器准备应答

阶段 2:DHT11 传感器应答信号

  1. DHT11 检测到主机起始信号后,立即把 DATA拉低 80μs
  2. 随后自动把 DATA拉高 80μs
  3. 应答信号结束,代表传感器就绪,即将开始传输 40 位数据

阶段 3:逐位数据传输时序(区分 0 与 1)

DHT11 以低电平为起始标志,通过高电平持续时间区分发送 0 还是 1

  1. 发送数字 0 时序 数据线拉低 50μs → 拉高26~28μs
  2. 发送数字 1 时序 数据线拉低 50μs → 拉高70μs

核心区分点:高电平时长短为 0,高电平时长更长为 1

阶段 4:通信结束

40 位数据全部传输完毕后,DHT11 自动将数据线拉低,随后释放总线恢复空闲高电平,一次通信正式结束。

时序整体流程简图

主机拉低 18ms → 主机拉高 30μs → DHT11 拉低 80μs → DHT11 拉高 80μs → 连续发送 40 位 0/1 数据 → 通信结束

五、通信工作模式讲解

  1. 空闲模式 无通信任务时,数据线依靠上拉电阻保持高电平,传感器处于休眠待机状态。

  2. 主机主动发起通信单片机作为通信主机,主动发送起始信号,掌控整个通信节奏。

  3. 从机被动应答 DHT11 为通信从机,只能被动响应主机指令,无法主动向单片机上传数据。

  4. IO 口双向切换原理

  • 发送起始信号:单片机 IO 配置为推挽输出模式,自由控制高低电平
  • 接收传感器数据:单片机 IO 切换为上拉输入模式,读取总线电平状态

六、DHT11 使用硬性规范

  1. 两次数据读取间隔必须大于 1 秒,频繁读取会导致数据错乱、传感器死机
  2. 时序延时必须精准,微秒级延时是驱动成功的唯一核心
  3. 所有读取到的数据,必须执行校验,不可直接使用原始数据
  4. 低温、高湿恶劣环境下,测量误差会轻微变大,属于正常现象
  5. DHT11 仅适用于日常环境监测,不适合工业高精度测温测湿场景

代码

一、整体工程文件架构

复制代码
Project
├─ main.c        // 主函数,业务逻辑调度
├─ DHT11.c/h     // DHT11传感器底层驱动
├─ oled.c/h      // IIC-OLED屏幕驱动
├─ delay.c/h     // SysTick系统延时驱动
└─ oledfont.h    // ASCII+中文点阵字库

二、各模块源码逐行解析

1 系统延时模块 delay.c/delay.h

延时是 DHT11 时序稳定的核心,采用 SysTick 定时器 8 分频计时,提供 us、ms 两级延时。

delay.h
复制代码
#include "stm32f10x.h"

void initSysTick(void);
void delay_us(u32 xus);
void delay_ms(u32 xms);
delay.c
复制代码
#include "delay.h"
#include "stm32f10x.h"

// SysTick时钟初始化
void initSysTick(void)
{
    SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
    SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;
    SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
    SysTick->LOAD = 9;
}

// 微秒级精准延时
void delay_us(u32 xus)
{
    SysTick->LOAD = 9 * xus;
    SysTick->VAL = 0;
    while (!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk));
}

// 毫秒级延时
void delay_ms(u32 xms)
{
    SysTick->LOAD = 9000;
    SysTick->VAL = 0;
    while (xms--)
    {
        while (!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk));
    }
}

2 DHT11 温湿度驱动 DHT11.c/ DHT11.h

单总线通信逻辑:输出模式发启动信号→切换输入模式接收 40 位数据→数据校验判定有效性。

DHT11.h
复制代码
#ifndef _DHT11_H
#define _DHT11_H

#include "stm32f10x.h"

#define data1  GPIO_SetBits(GPIOB,  GPIO_Pin_11)
#define data0  GPIO_ResetBits(GPIOB,  GPIO_Pin_11)
#define read_data  GPIO_ReadInputDataBit(GPIOB,  GPIO_Pin_11)

void DHT11_GPIO_Init(void);
void DHT11_GPIO_Init1(void);
void DHT11_Start(void);
void DHT11_ReceptionBuff(void);
void DHT11_UpdateData(void);

extern uint16_t Rxbuff[5];

#endif
DHT11.c

该文件实现 DHT11 单总线传感器底层驱动,完成 GPIO 模式切换、主机下发启动指令、传感器应答检测、40 位温湿度数据读取,最终把数据存入缓存数组,依靠校验机制保障数据可靠性。DHT11 通信依靠严格时序电平变化识别数据位,高电平时长区分逻辑 0 与逻辑 1。

复制代码
#include "stm32f10x.h"
#include "DHT11.h"
#include "delay.h"
#include "stdio.h"

// 5字节数据缓存数组,固定数据格式
// Rxbuff[0]:湿度整数部分  Rxbuff[1]:湿度小数部分
// Rxbuff[2]:温度整数部分  Rxbuff[3]:温度小数部分
// Rxbuff[4]:数据校验和,用于校验数据是否失真
uint16_t Rxbuff[5];

/**
 * @brief  GPIO配置为推挽输出模式
 * @note   该模式用于主机向DHT11发送启动触发信号
 */
void DHT11_GPIO_Init(void)
{
   GPIO_InitTypeDef  GPIO_InitStructure;
   RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB,  ENABLE); // 使能GPIOB外设时钟
   GPIO_InitStructure.GPIO_Mode =  GPIO_Mode_Out_PP;       // 推挽输出,高低电平驱动能力强
   GPIO_InitStructure.GPIO_Pin  =  GPIO_Pin_11;            // 绑定数据引脚PB11
   GPIO_InitStructure.GPIO_Speed =  GPIO_Speed_50MHz;
   GPIO_Init(GPIOB, &GPIO_InitStructure);
   GPIO_SetBits(GPIOB,  GPIO_Pin_11);                      // 引脚默认高电平,空闲状态
}

/**
 * @brief  GPIO配置为下拉输入模式
 * @note   切换输入模式后,用来接收DHT11返回的温湿度数据
 */
void DHT11_GPIO_Init1(void)
{
   GPIO_InitTypeDef  GPIO_InitStructure;
   RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB,  ENABLE);
   GPIO_InitStructure.GPIO_Mode =  GPIO_Mode_IPD;  // 下拉输入,稳定采集外部电平
   GPIO_InitStructure.GPIO_Pin  =  GPIO_Pin_11;
   GPIO_InitStructure.GPIO_Speed =  GPIO_Speed_50MHz;
   GPIO_Init(GPIOB, &GPIO_InitStructure);
   GPIO_SetBits(GPIOB,  GPIO_Pin_11);
}

/**
 * @brief  检测DHT11应答响应
 * @retval 固定返回0,完成应答判定
 * @note   通信流程:主机发启动信号后,传感器拉低电平回应,再拉高代表应答完成
 */
static uint8_t DHT11_Back()
{
   uint8_t i =200;
   while(read_data && i--);  // 循环等待电平拉低,超时防止卡死
   i= 200;
   while(!read_data && i--); // 等待电平重新拉高,应答结束
   return 0;
}

/**
 * @brief  主机发送DHT11启动信号
 * @note   时序标准:引脚拉低维持20ms以上,再短暂拉高,唤醒传感器准备传数
 */
void DHT11_Start(void)
{
     data0;                  // 拉低数据线
     delay_ms(20);           // 满足启动时序最低时长要求
     data1;                  // 释放电平拉高
     delay_us(10);           // 短暂间隔切换模式
     DHT11_GPIO_Init1();     // 切换为输入,准备接收数据
     while(DHT11_Back());    // 阻塞等待传感器应答
}

/**
 * @brief  批量接收40位原始数据
 * @note   单次通信传输5字节共40位数据;电平延时40us判定位数据
 *         高电平持续久代表逻辑1,持续短代表逻辑0
 */
void DHT11_ReceptionBuff(void)
{
   uint8_t y=1;
   uint16_t i;
   uint8_t x;
   // 循环读取5个字节数据
   for(x=0;x<5;x++)
   {
	    i=0;
		// 单个字节包含8个数据位
		for(y=1;y<9;y++)
		{
		   while(read_data);        // 等待位起始低电平
		   delay_us(40);            // 延时采样判断电平状态
		   while(!read_data);
		   i= i<<1;                 // 字节左移,腾出最低位存放新数据
		   delay_us(30);
		   if(read_data) i |=1;     // 高电平置1,低电平默认0
		   while(read_data);
		}
	   Rxbuff[x] =i;              // 单字节存入缓存数组
	}
}

/**
 * @brief  完成一次完整温湿度数据采集
 * @note   封装采集流程,外部调用即可更新最新传感器数据
 */
void DHT11_UpdateData(void)
{
  DHT11_GPIO_Init();
  DHT11_Start();
  DHT11_ReceptionBuff();
}
  1. 引脚模式切换:发送指令用推挽输出,接收数据用输入模式,两种模式分工适配通信收发需求。
  2. 启动时序:固定高低电平时长唤醒传感器,时序偏差会直接导致通信失败。
  3. 数据读取规则:按位采集拼接成字节,一次性获取 5 组数据,对应温湿度与校验值。
  4. 缓存存储:统一数组托管数据,方便主函数调取使用。

数据缓冲区定义

  • Rxbuff [0]:湿度整数
  • Rxbuff [1]:湿度小数
  • Rxbuff [2]:温度整数
  • Rxbuff [3]:温度小数
  • Rxbuff [4]:校验和校验规则:前四字节相加结果 = 第五字节校验和,数据有效

3 IIC-OLED 屏幕驱动 oled.c/oled.h

基于标准 IIC 时序实现屏幕初始化、命令读写、中文数字字符显示,配套点阵字库渲染画面。

oled.h
复制代码
#ifndef _OLED_H_
#define _OLED_H_

#include "stm32f10x.h"

#define  OLED_SCLK_Set()    GPIO_SetBits(GPIOB,GPIO_Pin_0)
#define  OLED_SCLK_CLr()    GPIO_ResetBits(GPIOB,GPIO_Pin_0)
#define  OLED_SDIN_Set()    GPIO_SetBits(GPIOB,GPIO_Pin_1)
#define  OLED_SDIN_CLr()    GPIO_ResetBits(GPIOB,GPIO_Pin_1)
#define  OLED_READ_SDIN()    GPIO_ReadInputDataBit(GPIOB,  GPIO_Pin_1)

#define IIC_ACK  0
#define IIC_NO_ACK  1
#define  OLED_CMD 0
#define  OLED_DATA  1
#define SIZE 		16
#define Max_Column	128

void OLED_WR_Byte(unsigned char dat,unsigned char cmd);
void OLED_Set_Pos(unsigned char x,unsigned char y);
void OLED_Display_On(void);
void OLED_Display_Off(void);
void OLED_Clear(void);
void OLED_ShouChar(unsigned char x,unsigned char y,unsigned char chr);
void OLED_Init(void);
void OLED_ShowString(unsigned char x,unsigned char y,unsigned char *chr);
void OLED_ShowNum(unsigned char x,unsigned char y,unsigned int num,unsigned char len,unsigned char size);
void OLED_ShowCHinese(unsigned char x,unsigned char y,unsigned char no);

#endif
oled.c

基于软件 IIC 协议驱动 0.96 寸 OLED 屏幕,实现硬件初始化、总线启停、指令 / 数据读写,封装字符、数字、汉字、字符串显示接口,搭配点阵字库完成画面绘制,是屏幕画面展示的底层支撑。

复制代码
#include "stm32f10x.h"
#include "oled.h"
#include "oledfont.h"
#include "delay.h"

/**
 * @brief  OLED通信引脚初始化
 * @note   PB0为时钟线SCL,PB1为数据线SDA,开漏输出适配IIC总线特性
 */
static void OLED_GPIO_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE);
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; // 开漏输出,支持总线挂载多设备
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	OLED_SCLK_Set();
	OLED_SDIN_Set();
}

/**
 * @brief  IIC总线起始信号
 * @note   SCL高电平时,SDA由高变低,标志通信正式开始
 */
static void OLED_IIC_Start(void)
{
	OLED_SCLK_Set();
	OLED_SDIN_Set();
	delay_us(1);
	OLED_SDIN_CLr();
	delay_us(1);
	OLED_SCLK_CLr();
	delay_us(1);
}

/**
 * @brief  IIC总线停止信号
 * @note   SCL高电平时,SDA由低变高,结束本次通信
 */
static void OLED_IIC_Stop(void)
{
	OLED_SDIN_CLr();
	delay_us(1);
	OLED_SCLK_Set();
	delay_us(1);
	OLED_SDIN_Set();
	delay_us(1);
}

/**
 * @brief  等待从机应答信号
 * @retval 应答标志位,判断数据是否正常接收
 * @note   主机释放数据线,读取从机反馈电平
 */
static unsigned char IIC_Wait_Ack(void)
{
	unsigned char ack;
	OLED_SCLK_CLr();
	delay_us(1);
	OLED_SDIN_Set();
	delay_us(1);
	OLED_SCLK_Set();
	delay_us(1);
	ack = OLED_READ_SDIN() ? IIC_NO_ACK : IIC_ACK;
	OLED_SCLK_CLr();
	delay_us(1);
	return ack;
}

/**
 * @brief  IIC总线单字节数据发送
 * @param  IIC_Byte:待发送字节数据
 * @note   高位优先传输,逐位移位输出电平
 */
static void Write_IIC_Byte(unsigned char IIC_Byte)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		OLED_SCLK_CLr();
		delay_us(1);
		if(IIC_Byte & 0x80) OLED_SDIN_Set();
		else OLED_SDIN_CLr();
		IIC_Byte <<= 1;
		delay_us(1);
		OLED_SCLK_Set();
		delay_us(1);
	}
	OLED_SCLK_CLr();
	delay_us(1);
	while(IIC_Wait_Ack());
}

/**
 * @brief  向OLED写入控制命令
 * @param  IIC_Command:屏幕配置指令
 */
static void Write_IIC_Command(unsigned char IIC_Command)
{
   OLED_IIC_Start();
   Write_IIC_Byte(0x78);    // OLED设备固定IIC地址
   Write_IIC_Byte(0x00);    // 标识本次传输为命令
   Write_IIC_Byte(IIC_Command);
   OLED_IIC_Stop();
}

/**
 * @brief  向OLED写入显示数据
 * @param  IIC_Data:像素点阵数据
 */
static void Write_IIC_Data(unsigned char IIC_Data)
{
   OLED_IIC_Start();
   Write_IIC_Byte(0x78);
   Write_IIC_Byte(0x40);    // 标识本次传输为显示数据
   Write_IIC_Byte(IIC_Data);
   OLED_IIC_Stop();
}

/**
 * @brief  读写统一接口,区分命令与数据
 */
void OLED_WR_Byte(unsigned char dat,unsigned char cmd)
{
	cmd ? Write_IIC_Data(dat) : Write_IIC_Command(dat);
}

/**
 * @brief  设置屏幕光标显示坐标
 * @param  x横向坐标,y纵向坐标
 * @note   定位后,后续内容将从该坐标开始绘制
 */
void OLED_Set_Pos(unsigned char x, unsigned char y)
{
	OLED_WR_Byte(0xb0+y,OLED_CMD);
	OLED_WR_Byte((x&0x0f),OLED_CMD);
	OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD);
}

/**
 * @brief  开启屏幕显示
 */
void OLED_Display_On(void)
{
	OLED_WR_Byte(0X8D,OLED_CMD);
	OLED_WR_Byte(0X14,OLED_CMD);
	OLED_WR_Byte(0XAF,OLED_CMD);
}

/**
 * @brief  关闭屏幕显示
 */
void OLED_Display_Off(void)
{
	OLED_WR_Byte(0XAE,OLED_CMD);
	OLED_WR_Byte(0X8D,OLED_CMD);
	OLED_WR_Byte(0X10,OLED_CMD);
}

/**
 * @brief  全屏清屏,清空所有像素点
 */
void OLED_Clear(void)
{
	unsigned char i,n;
	for(i=0;i<8;i++)
	{
		OLED_WR_Byte (0xb0+i,OLED_CMD);
		OLED_WR_Byte (0x00,OLED_CMD);
		OLED_WR_Byte (0x10,OLED_CMD);
		for(n=0;n<128;n++)OLED_WR_Byte(0,OLED_DATA);
	}
}

/**
 * @brief  单个ASCII字符显示
 * @param  x,y显示坐标,chr待显示字符
 * @note   调取字库点阵,按点位点亮屏幕像素
 */
void OLED_ShouChar(unsigned char x,unsigned char y,unsigned char chr)
{
    unsigned char c = 0,i=0;
    c =chr - ' ';
	if(x>Max_Column){x=0;y=y+2;}
   if(SIZE == 16)
	 {
	   OLED_Set_Pos(x,y);
		 for(i=0;i<8;i++)
	  OLED_WR_Byte(F8X16[c*16+i],OLED_DATA);
	 	 OLED_Set_Pos(x,y+1);
		 for(i=0;i<8;i++)
	  OLED_WR_Byte(F8X16[c*16+i+8],OLED_DATA);
	 }
	 else
	 {
	   OLED_Set_Pos(x,y);
	   for(i=0;i<6;i++)
	   OLED_WR_Byte(F6x8[c][i],OLED_DATA);
	 }
}

/**
 * @brief  OLED硬件初始化配置
 * @note   上电延时稳定硬件,下发初始化指令配置屏幕参数
 */
void OLED_Init(void)
{
	OLED_GPIO_Init();
	delay_ms(200);
	OLED_WR_Byte(0xAE,OLED_CMD);
	OLED_WR_Byte(0x00,OLED_CMD);
	OLED_WR_Byte(0x10,OLED_CMD);
	OLED_WR_Byte(0x40,OLED_CMD);
	OLED_WR_Byte(0xB0,OLED_CMD);
	OLED_WR_Byte(0x81,OLED_CMD);
	OLED_WR_Byte(0xFF,OLED_CMD);
	OLED_WR_Byte(0xA1,OLED_CMD);
	OLED_WR_Byte(0xA6,OLED_CMD);
	OLED_WR_Byte(0xA8,OLED_CMD);
	OLED_WR_Byte(0x3F,OLED_CMD);
	OLED_WR_Byte(0xC8,OLED_CMD);
	OLED_WR_Byte(0xD3,OLED_CMD);
	OLED_WR_Byte(0x00,OLED_CMD);
	OLED_WR_Byte(0xD5,OLED_CMD);
	OLED_WR_Byte(0x80,OLED_CMD);
	OLED_WR_Byte(0xD9,OLED_CMD);
	OLED_WR_Byte(0xF1,OLED_CMD);
	OLED_WR_Byte(0xDA,OLED_CMD);
	OLED_WR_Byte(0x12,OLED_CMD);
	OLED_WR_Byte(0xDB,OLED_CMD);
	OLED_WR_Byte(0x40,OLED_CMD);
	OLED_WR_Byte(0x8D,OLED_CMD);
	OLED_WR_Byte(0x14,OLED_CMD);
	OLED_WR_Byte(0xAF,OLED_CMD);
	OLED_Clear();
	OLED_Set_Pos(0,0);
}

/**
 * @brief  连续字符串批量显示
 * @note   逐个调用单字符接口,自动偏移坐标换行
 */
void OLED_ShowString(unsigned char x, unsigned char y,unsigned char *chr)
{
   unsigned char j=0;
	 while(chr[j] != '\0')
	 {
	    OLED_ShouChar(x,y,chr[j]);
		 x+=8;
		 if(x>=128){x=0;y +=2;}
		 j++;
	 }
}

/**
 * @brief  数值幂运算,用于数字拆分
 */
unsigned int oled_pow(unsigned char m,unsigned char n)
{
	unsigned int result=1;
	while(n--)result*=m;
	return result;
}

/**
 * @brief  整数数字显示,自动拆分每一位数值
 */
void OLED_ShowNum(unsigned char x,unsigned char y,unsigned int num,unsigned char len,unsigned char size)
{
	unsigned char t,temp;
	unsigned char enshow=0;
	for(t=0;t<len;t++)
	{
		temp=(num/oled_pow(10,len-t-1))%10;
		if(enshow==0&&t<(len-1))
		{
			if(temp==0){OLED_ShouChar(x+(size/2)*t,y,' ');continue;}
			else enshow=1;
		}
	 	OLED_ShouChar(x+(size/2)*t,y,temp+'0');
	}
}

/**
 * @brief  汉字显示,调取中文点阵字库渲染画面
 */
void OLED_ShowCHinese(unsigned char x,unsigned char y,unsigned char no)
{
    unsigned char t,adder = 0;
	  OLED_Set_Pos(x,y);
	for(t=0;t<16;t++)
	{
		 OLED_WR_Byte( Hzk[2*no][t],OLED_DATA);
		 adder+=1;
	}
	  OLED_Set_Pos(x,y+1);
	for(t=0;t<16;t++)
	{
     OLED_WR_Byte( Hzk[2*no+1][t],OLED_DATA);
		 adder+=1;
	}
}
  1. 软件 IIC 时序:严格遵循起始、停止、应答时序,依靠引脚高低电平模拟总线通信协议。
  2. 命令与数据区分:不同标识位区分配置指令和画面数据,屏幕针对性执行功能。
  3. 坐标定位:所有显示内容都基于坐标摆放,灵活控制文字位置布局。
  4. 多类型显示封装:拆分字符、数字、汉字接口,上层调用无需关注底层点阵细节。

4 主程序 main.c

程序入口文件,统筹所有外设初始化,绘制固定界面文字,循环周期性采集温湿度数据,通过校验和过滤异常数据,最终把有效数值刷新展示在 OLED 屏幕上,实现完整功能闭环。

复制代码
#include "stm32f10x.h"
#include "main.h"
#include "delay.h"
#include "DHT11.h"
#include "oled.h"

int main(void)
{
	// 初始化SysTick定时器,提供精准延时功能
	initSysTick();
	delay_ms(1500);  // 上电延时,等待硬件模块稳定就绪

	// 初始化OLED屏幕并清空初始杂乱像素
	OLED_Init();
	OLED_Clear();

	// 固定界面文字绘制,标注温度、湿度显示区域
	OLED_ShowCHinese(0,2,6);
	OLED_ShowCHinese(16,2,7);
	OLED_ShowCHinese(32,2,8);
	OLED_ShowCHinese(48,2,9);
	OLED_ShowCHinese(66,2,10);
	OLED_ShowCHinese(90,2,15);
	OLED_ShowCHinese(112,2,11);
	OLED_ShowCHinese(16,5,6);
	OLED_ShowCHinese(32,5,7);
	OLED_ShowCHinese(48,5,12);
	OLED_ShowCHinese(64,5,9);
	OLED_ShowCHinese(80,5,10);
	OLED_ShowCHinese(112,5,13);

	// 死循环,不间断采集刷新数据
	while(1)
	{
		uint16_t check_sum;
		uint8_t temp,humi;
		DHT11_UpdateData();                 // 调用驱动读取最新温湿度数据
		// 累加前四字节数据,计算理论校验值
		check_sum = Rxbuff[0]+Rxbuff[1]+Rxbuff[2]+Rxbuff[3];

		// 校验值匹配则判定数据有效,执行显示更新
		if(Rxbuff[4] == check_sum)
		{
			humi = Rxbuff[0];               // 提取湿度整数
			temp = Rxbuff[2];               // 提取温度整数
			// 拆分十位、个位分别显示
			OLED_ShowNum(74,2,temp/10,1,16);
			OLED_ShowNum(82,2,temp%10,1,16);
			OLED_ShowNum(88,5,humi/10,1,16);
			OLED_ShowNum(96,5,humi%10,1,16);
		}
		delay_ms(2000);  // 2秒刷新一次,避免刷新过快画面闪烁
	}
}
  1. 初始化流程:先配置延时基础功能,再初始化显示屏,完成界面框架搭建。
  2. 静态界面:开机一次性绘制标题汉字,固定页面布局样式。
  3. 循环采集:周期性调用传感器驱动,持续获取环境数据。
  4. 数据校验:比对计算校验和与接收校验和,剔除干扰造成的错误数据。
  5. 数值拆分显示:将整数拆分为单独数位,调用屏幕接口完成实时数值更新。
  6. 刷新间隔:设置延时放缓更新频率,保证画面观感与设备通信稳定。

5 点阵字库 oledfont.h

内置 8*16 ASCII 字符、中文点阵数据,屏幕文字渲染依赖该字库

复制代码
#ifndef __OLEDFONT_H
#define __OLEDFONT_H 	   
//常用ASCII表
//偏移量32
//ASCII字符集
//偏移量32
//大小:12*6
/************************************6*8的点阵************************************/
const unsigned char  F6x8[][6] =		
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,// sp
0x00, 0x00, 0x00, 0x2f, 0x00, 0x00,// !
0x00, 0x00, 0x07, 0x00, 0x07, 0x00,// "
0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14,// #
0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12,// $
0x00, 0x62, 0x64, 0x08, 0x13, 0x23,// %
0x00, 0x36, 0x49, 0x55, 0x22, 0x50,// &
0x00, 0x00, 0x05, 0x03, 0x00, 0x00,// '
0x00, 0x00, 0x1c, 0x22, 0x41, 0x00,// (
0x00, 0x00, 0x41, 0x22, 0x1c, 0x00,// )
0x00, 0x14, 0x08, 0x3E, 0x08, 0x14,// *
0x00, 0x08, 0x08, 0x3E, 0x08, 0x08,// +
0x00, 0x00, 0x00, 0xA0, 0x60, 0x00,// ,
0x00, 0x08, 0x08, 0x08, 0x08, 0x08,// -
0x00, 0x00, 0x60, 0x60, 0x00, 0x00,// .
0x00, 0x20, 0x10, 0x08, 0x04, 0x02,// /
0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E,// 0
0x00, 0x00, 0x42, 0x7F, 0x40, 0x00,// 1
0x00, 0x42, 0x61, 0x51, 0x49, 0x46,// 2
0x00, 0x21, 0x41, 0x45, 0x4B, 0x31,// 3
0x00, 0x18, 0x14, 0x12, 0x7F, 0x10,// 4
0x00, 0x27, 0x45, 0x45, 0x45, 0x39,// 5
0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30,// 6
0x00, 0x01, 0x71, 0x09, 0x05, 0x03,// 7
0x00, 0x36, 0x49, 0x49, 0x49, 0x36,// 8
0x00, 0x06, 0x49, 0x49, 0x29, 0x1E,// 9
0x00, 0x00, 0x36, 0x36, 0x00, 0x00,// :
0x00, 0x00, 0x56, 0x36, 0x00, 0x00,// ;
0x00, 0x08, 0x14, 0x22, 0x41, 0x00,// <
0x00, 0x14, 0x14, 0x14, 0x14, 0x14,// =
0x00, 0x00, 0x41, 0x22, 0x14, 0x08,// >
0x00, 0x02, 0x01, 0x51, 0x09, 0x06,// ?
0x00, 0x32, 0x49, 0x59, 0x51, 0x3E,// @
0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C,// A
0x00, 0x7F, 0x49, 0x49, 0x49, 0x36,// B
0x00, 0x3E, 0x41, 0x41, 0x41, 0x22,// C
0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C,// D
0x00, 0x7F, 0x49, 0x49, 0x49, 0x41,// E
0x00, 0x7F, 0x09, 0x09, 0x09, 0x01,// F
0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A,// G
0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F,// H
0x00, 0x00, 0x41, 0x7F, 0x41, 0x00,// I
0x00, 0x20, 0x40, 0x41, 0x3F, 0x01,// J
0x00, 0x7F, 0x08, 0x14, 0x22, 0x41,// K
0x00, 0x7F, 0x40, 0x40, 0x40, 0x40,// L
0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F,// M
0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F,// N
0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E,// O
0x00, 0x7F, 0x09, 0x09, 0x09, 0x06,// P
0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E,// Q
0x00, 0x7F, 0x09, 0x19, 0x29, 0x46,// R
0x00, 0x46, 0x49, 0x49, 0x49, 0x31,// S
0x00, 0x01, 0x01, 0x7F, 0x01, 0x01,// T
0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F,// U
0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F,// V
0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F,// W
0x00, 0x63, 0x14, 0x08, 0x14, 0x63,// X
0x00, 0x07, 0x08, 0x70, 0x08, 0x07,// Y
0x00, 0x61, 0x51, 0x49, 0x45, 0x43,// Z
0x00, 0x00, 0x7F, 0x41, 0x41, 0x00,// [
0x00, 0x55, 0x2A, 0x55, 0x2A, 0x55,// 55
0x00, 0x00, 0x41, 0x41, 0x7F, 0x00,// ]
0x00, 0x04, 0x02, 0x01, 0x02, 0x04,// ^
0x00, 0x40, 0x40, 0x40, 0x40, 0x40,// _
0x00, 0x00, 0x01, 0x02, 0x04, 0x00,// '
0x00, 0x20, 0x54, 0x54, 0x54, 0x78,// a
0x00, 0x7F, 0x48, 0x44, 0x44, 0x38,// b
0x00, 0x38, 0x44, 0x44, 0x44, 0x20,// c
0x00, 0x38, 0x44, 0x44, 0x48, 0x7F,// d
0x00, 0x38, 0x54, 0x54, 0x54, 0x18,// e
0x00, 0x08, 0x7E, 0x09, 0x01, 0x02,// f
0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C,// g
0x00, 0x7F, 0x08, 0x04, 0x04, 0x78,// h
0x00, 0x00, 0x44, 0x7D, 0x40, 0x00,// i
0x00, 0x40, 0x80, 0x84, 0x7D, 0x00,// j
0x00, 0x7F, 0x10, 0x28, 0x44, 0x00,// k
0x00, 0x00, 0x41, 0x7F, 0x40, 0x00,// l
0x00, 0x7C, 0x04, 0x18, 0x04, 0x78,// m
0x00, 0x7C, 0x08, 0x04, 0x04, 0x78,// n
0x00, 0x38, 0x44, 0x44, 0x44, 0x38,// o
0x00, 0xFC, 0x24, 0x24, 0x24, 0x18,// p
0x00, 0x18, 0x24, 0x24, 0x18, 0xFC,// q
0x00, 0x7C, 0x08, 0x04, 0x04, 0x08,// r
0x00, 0x48, 0x54, 0x54, 0x54, 0x20,// s
0x00, 0x04, 0x3F, 0x44, 0x40, 0x20,// t
0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C,// u
0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C,// v
0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C,// w
0x00, 0x44, 0x28, 0x10, 0x28, 0x44,// x
0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C,// y
0x00, 0x44, 0x64, 0x54, 0x4C, 0x44,// z
0x14, 0x14, 0x14, 0x14, 0x14, 0x14,// horiz lines
};
/****************************************8*16的点阵************************************/
const unsigned char  F8X16[]=	  
{
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// 0
  0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x30,0x00,0x00,0x00,//! 1
  0x00,0x10,0x0C,0x06,0x10,0x0C,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//" 2
  0x40,0xC0,0x78,0x40,0xC0,0x78,0x40,0x00,0x04,0x3F,0x04,0x04,0x3F,0x04,0x04,0x00,//# 3
  0x00,0x70,0x88,0xFC,0x08,0x30,0x00,0x00,0x00,0x18,0x20,0xFF,0x21,0x1E,0x00,0x00,//$ 4
  0xF0,0x08,0xF0,0x00,0xE0,0x18,0x00,0x00,0x00,0x21,0x1C,0x03,0x1E,0x21,0x1E,0x00,//% 5
  0x00,0xF0,0x08,0x88,0x70,0x00,0x00,0x00,0x1E,0x21,0x23,0x24,0x19,0x27,0x21,0x10,//& 6
  0x10,0x16,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//' 7
  0x00,0x00,0x00,0xE0,0x18,0x04,0x02,0x00,0x00,0x00,0x00,0x07,0x18,0x20,0x40,0x00,//( 8
  0x00,0x02,0x04,0x18,0xE0,0x00,0x00,0x00,0x00,0x40,0x20,0x18,0x07,0x00,0x00,0x00,//) 9
  0x40,0x40,0x80,0xF0,0x80,0x40,0x40,0x00,0x02,0x02,0x01,0x0F,0x01,0x02,0x02,0x00,//* 10
  0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x1F,0x01,0x01,0x01,0x00,//+ 11
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xB0,0x70,0x00,0x00,0x00,0x00,0x00,//, 12
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,//- 13
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00,//. 14
  0x00,0x00,0x00,0x00,0x80,0x60,0x18,0x04,0x00,0x60,0x18,0x06,0x01,0x00,0x00,0x00,/// 15
  0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,//0 16
  0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//1 17
  0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,//2 18
  0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00,//3 19
  0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00,//4 20
  0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00,//5 21
  0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00,//6 22
  0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,//7 23
  0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00,//8 24
  0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00,//9 25
  0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,//: 26
  0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x60,0x00,0x00,0x00,0x00,//; 27
  0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x00,//< 28
  0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00,//= 29
  0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x20,0x10,0x08,0x04,0x02,0x01,0x00,//> 30
  0x00,0x70,0x48,0x08,0x08,0x08,0xF0,0x00,0x00,0x00,0x00,0x30,0x36,0x01,0x00,0x00,//? 31
  0xC0,0x30,0xC8,0x28,0xE8,0x10,0xE0,0x00,0x07,0x18,0x27,0x24,0x23,0x14,0x0B,0x00,//@ 32
  0x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00,0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20,//A 33
  0x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00,//B 34
  0xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00,0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00,//C 35
  0x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00,0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00,//D 36
  0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x20,0x23,0x20,0x18,0x00,//E 37
  0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x00,0x03,0x00,0x00,0x00,//F 38
  0xC0,0x30,0x08,0x08,0x08,0x38,0x00,0x00,0x07,0x18,0x20,0x20,0x22,0x1E,0x02,0x00,//G 39
  0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20,//H 40
  0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//I 41
  0x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,0x00,//J 42
  0x08,0xF8,0x88,0xC0,0x28,0x18,0x08,0x00,0x20,0x3F,0x20,0x01,0x26,0x38,0x20,0x00,//K 43
  0x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x20,0x30,0x00,//L 44
  0x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08,0x00,0x20,0x3F,0x00,0x3F,0x00,0x3F,0x20,0x00,//M 45
  0x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08,0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00,//N 46
  0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,0x00,//O 47
  0x08,0xF8,0x08,0x08,0x08,0x08,0xF0,0x00,0x20,0x3F,0x21,0x01,0x01,0x01,0x00,0x00,//P 48
  0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x18,0x24,0x24,0x38,0x50,0x4F,0x00,//Q 49
  0x08,0xF8,0x88,0x88,0x88,0x88,0x70,0x00,0x20,0x3F,0x20,0x00,0x03,0x0C,0x30,0x20,//R 50
  0x00,0x70,0x88,0x08,0x08,0x08,0x38,0x00,0x00,0x38,0x20,0x21,0x21,0x22,0x1C,0x00,//S 51
  0x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//T 52
  0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//U 53
  0x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08,0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00,//V 54
  0xF8,0x08,0x00,0xF8,0x00,0x08,0xF8,0x00,0x03,0x3C,0x07,0x00,0x07,0x3C,0x03,0x00,//W 55
  0x08,0x18,0x68,0x80,0x80,0x68,0x18,0x08,0x20,0x30,0x2C,0x03,0x03,0x2C,0x30,0x20,//X 56
  0x08,0x38,0xC8,0x00,0xC8,0x38,0x08,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//Y 57
  0x10,0x08,0x08,0x08,0xC8,0x38,0x08,0x00,0x20,0x38,0x26,0x21,0x20,0x20,0x18,0x00,//Z 58
  0x00,0x00,0x00,0xFE,0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x7F,0x40,0x40,0x40,0x00,//[ 59
  0x00,0x0C,0x30,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x06,0x38,0xC0,0x00,//\ 60
  0x00,0x02,0x02,0x02,0xFE,0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x7F,0x00,0x00,0x00,//] 61
  0x00,0x00,0x04,0x02,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//^ 62
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,//_ 63
  0x00,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//` 64
  0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x19,0x24,0x22,0x22,0x22,0x3F,0x20,//a 65
  0x08,0xF8,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x11,0x20,0x20,0x11,0x0E,0x00,//b 66
  0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x0E,0x11,0x20,0x20,0x20,0x11,0x00,//c 67
  0x00,0x00,0x00,0x80,0x80,0x88,0xF8,0x00,0x00,0x0E,0x11,0x20,0x20,0x10,0x3F,0x20,//d 68
  0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x22,0x22,0x22,0x22,0x13,0x00,//e 69
  0x00,0x80,0x80,0xF0,0x88,0x88,0x88,0x18,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//f 70
  0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x6B,0x94,0x94,0x94,0x93,0x60,0x00,//g 71
  0x08,0xF8,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//h 72
  0x00,0x80,0x98,0x98,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//i 73
  0x00,0x00,0x00,0x80,0x98,0x98,0x00,0x00,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,//j 74
  0x08,0xF8,0x00,0x00,0x80,0x80,0x80,0x00,0x20,0x3F,0x24,0x02,0x2D,0x30,0x20,0x00,//k 75
  0x00,0x08,0x08,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//l 76
  0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x20,0x3F,0x20,0x00,0x3F,0x20,0x00,0x3F,//m 77
  0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//n 78
  0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//o 79
  0x80,0x80,0x00,0x80,0x80,0x00,0x00,0x00,0x80,0xFF,0xA1,0x20,0x20,0x11,0x0E,0x00,//p 80
  0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x0E,0x11,0x20,0x20,0xA0,0xFF,0x80,//q 81
  0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x20,0x20,0x3F,0x21,0x20,0x00,0x01,0x00,//r 82
  0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x33,0x24,0x24,0x24,0x24,0x19,0x00,//s 83
  0x00,0x80,0x80,0xE0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x1F,0x20,0x20,0x00,0x00,//t 84
  0x80,0x80,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x1F,0x20,0x20,0x20,0x10,0x3F,0x20,//u 85
  0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x00,0x01,0x0E,0x30,0x08,0x06,0x01,0x00,//v 86
  0x80,0x80,0x00,0x80,0x00,0x80,0x80,0x80,0x0F,0x30,0x0C,0x03,0x0C,0x30,0x0F,0x00,//w 87
  0x00,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x31,0x2E,0x0E,0x31,0x20,0x00,//x 88
  0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x80,0x81,0x8E,0x70,0x18,0x06,0x01,0x00,//y 89
  0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x21,0x30,0x2C,0x22,0x21,0x30,0x00,//z 90
  0x00,0x00,0x00,0x00,0x80,0x7C,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x3F,0x40,0x40,//{ 91
  0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,//| 92
  0x00,0x02,0x02,0x7C,0x80,0x00,0x00,0x00,0x00,0x40,0x40,0x3F,0x00,0x00,0x00,0x00,//} 93
  0x00,0x06,0x01,0x01,0x02,0x02,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//~ 94
};
const unsigned char  Hzk[][32]={

{0x10,0x10,0x10,0xFF,0x10,0x90,0x08,0x88,0x88,0x88,0xFF,0x88,0x88,0x88,0x08,0x00},
{0x04,0x44,0x82,0x7F,0x01,0x80,0x80,0x40,0x43,0x2C,0x10,0x28,0x46,0x81,0x80,0x00},/*"技",0*/

{0x40,0x44,0x54,0x65,0xC6,0x64,0x54,0x44,0x00,0xFC,0x44,0x44,0xC4,0x42,0x40,0x00},
{0x20,0x12,0x4A,0x82,0x7F,0x02,0x0A,0x92,0x60,0x1F,0x00,0x00,0xFF,0x00,0x00,0x00},/*"新",1*/

{0x00,0x00,0xF8,0x88,0x88,0x88,0x88,0xFF,0x88,0x88,0x88,0x88,0xF8,0x00,0x00,0x00},
{0x00,0x00,0x1F,0x08,0x08,0x08,0x08,0x7F,0x88,0x88,0x88,0x88,0x9F,0x80,0xF0,0x00},/*"电",2*/

{0x80,0x82,0x82,0x82,0x82,0x82,0x82,0xE2,0xA2,0x92,0x8A,0x86,0x82,0x80,0x80,0x00},
{0x00,0x00,0x00,0x00,0x00,0x40,0x80,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"子",3*/

{0x24,0x24,0xA4,0xFE,0xA3,0x22,0x00,0x22,0xCC,0x00,0x00,0xFF,0x00,0x00,0x00,0x00},
{0x08,0x06,0x01,0xFF,0x00,0x01,0x04,0x04,0x04,0x04,0x04,0xFF,0x02,0x02,0x02,0x00},/*"科",4*/

{0x10,0x10,0x10,0xFF,0x10,0x90,0x08,0x88,0x88,0x88,0xFF,0x88,0x88,0x88,0x08,0x00},
{0x04,0x44,0x82,0x7F,0x01,0x80,0x80,0x40,0x43,0x2C,0x10,0x28,0x46,0x81,0x80,0x00},/*"技",5*/


{0x00,0x00,0x00,0x10,0x20,0x60,0x00,0xFC,0x04,0x40,0xA0,0x98,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x01,0x41,0x49,0x49,0x29,0x25,0x25,0x24,0x3F,0x01,0x00,0x00,0x00},/*"当",6*/

{0x00,0x20,0x20,0xA0,0xA0,0xA4,0xA8,0x20,0x20,0x98,0x16,0xF0,0x10,0x10,0x10,0x00},
{0x00,0x00,0x00,0x1F,0x0A,0x2A,0x7F,0x00,0x00,0x0F,0x20,0x6F,0x30,0x00,0x00,0x00},/*"前",7*/


{0x00,0x00,0x40,0x08,0x18,0x00,0x08,0xF8,0xA8,0x68,0x68,0x74,0x18,0x00,0x00,0x00},
{0x00,0x00,0x30,0x0E,0x22,0x20,0x3E,0x22,0x1E,0x12,0x2E,0x22,0x1F,0x12,0x00,0x00},/*"温",8*/

{0x00,0x00,0x00,0x00,0xF0,0x90,0xB0,0xF0,0x56,0xD8,0x28,0x48,0x00,0x00,0x00,0x00},
{0x00,0x20,0x10,0x0C,0x43,0x40,0x40,0x2D,0x13,0x1E,0x22,0x60,0x40,0x40,0x40,0x00},/*"度",9*/


{0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x31,0x31,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*":",10*/

{0x00,0x0C,0x12,0x0C,0x00,0xC0,0x70,0x10,0x08,0x08,0x08,0x08,0x10,0x30,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x0F,0x18,0x30,0x20,0x20,0x20,0x20,0x30,0x1C,0x00,0x00},/*"℃",11*/

{0x00,0x00,0x40,0x08,0x08,0x08,0xF8,0xA8,0xA8,0x58,0x48,0x7C,0x08,0x00,0x00,0x00},
{0x00,0x00,0x38,0x06,0x20,0x20,0x2C,0x3D,0x23,0x21,0x3F,0x24,0x23,0x20,0x20,0x00},/*"湿",12*/

{0x00,0xF0,0xF8,0x08,0x88,0xF8,0xF0,0x00,0x80,0x40,0x20,0x10,0x08,0x00,0x00,0x00},
{0x00,0x00,0x00,0x21,0x18,0x0C,0x02,0x01,0x00,0x1E,0x3F,0x21,0x21,0x1E,0x1E,0x00},/*"%",13*/

{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",14*/


{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x10,0x30,0x30,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*".",15*/


};

#endif

三、程序整体运行流程

  1. 上电启动 → 初始化 SysTick 延时
  2. 延时等待硬件稳定,初始化 OLED 屏幕并清屏
  3. 绘制固定中文标题界面
  4. 进入死循环
    1. 调用接口读取 DHT11 5 字节数据
    2. 累加前四字节与校验和比对,过滤无效杂波数据
    3. 拆分温度、湿度整数位,刷新 OLED 数字
    4. 间隔 2 秒,重复采集显示
相关推荐
IT搬砖客9 小时前
CC2340从机开发入门之OAD例程的选择
c语言·开发语言·单片机·嵌入式硬件
济61710 小时前
ROS开发专栏---激光雷达数据获取仿真实验+ RViz2使用教程--适配Ubuntu 22.04
嵌入式硬件·嵌入式·ros2·机器人方向
郝学胜-神的一滴10 小时前
CMake 011:跨平台动态库编译
开发语言·c++·嵌入式硬件·qt·程序人生·cmake·liunx
国产化创客10 小时前
ESP32+WebServer+LD2402实现人体/宠物感知
单片机·物联网·开源·智能硬件
坤坤藤椒牛肉面11 小时前
EXIT外部中断
单片机·嵌入式硬件
xiangw@GZ11 小时前
射频信号隔离度量化分析及优化措施
单片机·嵌入式硬件
车软派开发学长11 小时前
零基础学习车软嵌入式AUTOSAR,以一帧CAN报文实战讲解AUTOSAR的学习
网络·stm32·车载系统·autosar·嵌入式实时数据库
╰ㄣ浮华若梦︶ _11 小时前
51单片机的DS1302使用
单片机·嵌入式硬件·51单片机·ds1302·8051
启芯硬件11 小时前
用AI解决电源最复杂PDN问题的实战设计案例
人工智能·经验分享·嵌入式硬件·硬件工程·高速仿真