当前位置: 首页 > news >正文

STM32智能加湿器

项目简介

主控STM32f103c8t6

STM32F103C8T6是一款非常经典且应用广泛的微控制器,下面是它的核心信息概要。

特性分类

具体参数

核心架构

32位 ARM Cortex-M3 内核

工作频率

最高 72 MHz

存储资源

64 KB Flash, 20 KB SRAM

工作电压

2.0 V - 3.6 V

封装与I/O

LQFP-48 封装,最多 37个可编程I/O引脚

关键外设

2个12位ADC、7个定时器、2个I²C、3个USART、2个SPI、1个USB、1个CAN

🔧 核心功能与特点

STM32F103C8T6的功能十分丰富,这使得它能适应各种复杂的应用场景。

  • 高性能内核​:其ARM Cortex-M3内核支持单周期乘法和硬件除法,在72MHz的工作频率下能提供高达1.25 DMIPS/MHz的性能,处理效率远超传统的8位和16位单片机

  • 丰富的通信接口​:芯片集成了多种标准通信接口,包括3个USART、2个I²C、2个SPI、1个USB 2.0全速接口和1个CAN总线。这使得它可以轻松地与各种传感器、执行器、上位机及其他模块进行数据交换

  • 强大的定时器和模拟功能​:内置了多达7个定时器,包括高级的PWM定时器(非常适合电机控制)、通用定时器和看门狗定时器同时,它拥有2个12位的ADC(模数转换器),转换时间快至1微秒,可以同时采集多达16个通道的模拟信号 。

  • 灵活的电源管理​:芯片支持多种低功耗模式,包括睡眠、停止和待机模式,有助于在电池供电的应用中显著延长设备续航时间

按键

按键可采用堵塞的方式扫描,用法为简单的读取按键的状态,然后进行消抖,最后得到按键值,但是这个方法会堵塞主函数的运行,所以最好采用非堵塞的方式,在这里我采用的是江科大的非堵塞式按键扫描方式,下面式代码

#include "stm32f1xx_hal.h"	//链接HAL库
#include "Relay.h"
#include "Buzzer.h"
#include "oled.h"
#include "zzyy_OLED.h"uint8_t steady_KeyState;  //按键的稳定值uint8_t KeyNum,KeyTemp;uint8_t Key_Get_Num(void)
{uint8_t temp = 0;temp = steady_KeyState;steady_KeyState = 0;return temp;
}uint8_t Key_GetSatae(void)
{uint8_t Key_State = 0;  //按键的状态if(HAL_GPIO_ReadPin(GPIOB,  GPIO_PIN_10) == 0) Key_State = 1;else if(HAL_GPIO_ReadPin(GPIOB,  GPIO_PIN_0) == 0) Key_State = 2;else if(HAL_GPIO_ReadPin(GPIOA,  GPIO_PIN_6) == 0) Key_State = 3;return Key_State;
}void Key_Tick(void)  //函数放在定时器,20秒扫描一次
{static uint8_t old_state= 0;static uint8_t new_state= 0;old_state = new_state;new_state = Key_GetSatae();if((old_state == 0)&&(new_state == 1)) steady_KeyState = 1;else if((old_state == 0)&&(new_state == 2)) steady_KeyState = 2;else if((old_state == 0)&&(new_state == 3)) steady_KeyState = 3;}////屏幕标志位//uint32_t Screen_Flag;//光标标志位
/*
0:无光标
1:光标在切换智能模式和手动模式上面
2:如果在手动模式的话,光标在开关加湿器的上面
3: 光标在湿度阈值
4:光标在水位阈值上
*/
uint8_t Cuesor_Flag;uint8_t Mode_Flag; //模式标志位
uint8_t Relay_Flag = 0;  //继电器标志位  0为关 1为开void Key_Pro(void)
{KeyTemp = Key_Get_Num();if(KeyTemp) KeyNum = KeyTemp;switch(KeyNum){case 1:  //按键1  设置为切换按键switch(Cuesor_Flag){case 0:Cuesor_Flag = 1;break;case 1:if(Mode_Flag == 1) Cuesor_Flag = 2;elseCuesor_Flag = 3;break;case 2:Cuesor_Flag = 3; break;case 3:Cuesor_Flag = 4; break;}KeyNum = 0;break;case 2:  //按键2if(Cuesor_Flag == 1){Mode_Flag = !Mode_Flag;OLED_Printf(0, 0, "         ");}else if(Cuesor_Flag == 3){Humi_Limt = Humi_Limt + 5;if(Humi_Limt >=100) Humi_Limt =0;}else if(Cuesor_Flag == 4){Water_Deep_Limt = Water_Deep_Limt +5;if(Water_Deep_Limt >= 100) Water_Deep_Limt = 0;}else if(Cuesor_Flag == 2){Relay_Flag = !Relay_Flag;Relay_Control(Relay_Flag);}KeyNum = 0;break;case 3:  //按键3KeyNum = 0;if(Cuesor_Flag == 3){Humi_Limt = Humi_Limt -5;if(Humi_Limt >= 250) Humi_Limt =100;}else if(Cuesor_Flag == 4){Water_Deep_Limt = Water_Deep_Limt -5;if(Water_Deep_Limt >= 250) Water_Deep_Limt =100;}break;}		
}
#ifndef __KEY_H
#define __KEY_Hextern uint8_t KeyNum,KeyTemp;extern uint8_t Cuesor_Flag;extern uint8_t Mode_Flag; //模式标志位extern uint8_t Relay_Flag;  //继电器标志位  0为关 1为开uint8_t Key_Get_Num(void);  //获取按键键码值函数
void Key_Tick(void);  //函数放在定时器,20秒扫描一次void Key_Pro(void);#endif 

0.96寸OLED显示屏

特性分类

具体参数/描述

屏幕尺寸

0.96英寸(对角线)

分辨率

128 × 64 像素

接口类型

IIC(I²C),仅需SDA(数据线)和SCL(时钟线)两根信号线

驱动芯片

通常采用SSD1306驱动芯片

工作电压

3.3V 或 5V DC

主要颜色

白色、蓝色或黄蓝双色

核心优势

自发光、高对比度、低功耗、响应速度快、视角广

  • 自发光与高对比度​:OLED屏幕的每个像素点都能独立发光,显示黑色时像素点完全关闭,从而实现极高的对比度和纯正的黑色

    这使得它在显示效果上优于需要背光板的LCD屏幕。
  • 低功耗​:由于自发光特性,只有在显示内容时相应的像素点才消耗电能,尤其在显示深色背景或静态内容时功耗非常低,非常适合电池供电的便携设备

  • 简化硬件连接​:IIC接口大大简化了与微控制器(如STM32、ESP8266/ESP32)的连接,只需要连接SDASCL两条数据线以及电源和地线即可

    常见的设备地址通常是0x3C

我们采用的是hal库的驱动方法 

OLED.c

/***********************************本驱动文件仅适配HAL库版本
***********************************/
#include "font.h"	//字库文件
#include "oled.h"		//声明
#include "i2c.h"
#include <stdarg.h>
#include <stdio.h>/* 控制宏 */
#define LEFT 			0x27
#define RIGHT 			0x26
#define UP 				0X29
#define DOWM 			0x2A
#define ON				0xA7
#define OFF				0xA6/* IIC接口选择 */
#define IICx hi2c1//oled显示尺寸
uint16_t const displayWidth                = 128;
uint16_t const displayHeight               = 64;/*  OLED显存
[0]0 1 2 3 ... 127	
[1]0 1 2 3 ... 127	
[2]0 1 2 3 ... 127	
[3]0 1 2 3 ... 127	
[4]0 1 2 3 ... 127	
[5]0 1 2 3 ... 127	
[6]0 1 2 3 ... 127	
[7]0 1 2 3 ... 127 */
static uint8_t OLED_RAM[8][128];//定义GDDRAM缓存区void HAL_I2C_WriteByte(uint8_t addr,uint8_t data)
{uint8_t TxData[2] = {addr,data};HAL_I2C_Master_Transmit(&IICx,0X78,(uint8_t*)TxData,2,10);
}/**************************************************************Prototype      : void WriteCmd(uint8_t IIC_Command)Parameters     : IIC_Commandreturn					: noneDescription    : 写命令
***************************************************************/
void WriteCmd(uint8_t IIC_Command)
{HAL_I2C_WriteByte(0x00, IIC_Command);
}/**************************************************************Prototype      : void WriteDat(uint8_t IIC_Data)Parameters     : IIC_Datareturn					: noneDescription    : 写数据
***************************************************************/
void WriteDat(uint8_t IIC_Data)
{HAL_I2C_WriteByte(0x40, IIC_Data);
}/**************************************************************Prototype      : void OLED_Init(void)Parameters     : nonereturn					: noneDescription    : 初始化OLED模块
***************************************************************/
void OLED_Init(void) 
{HAL_Delay(500);WriteCmd(0xAE); //开显示WriteCmd(0x20);	//设置内存寻址模式	WriteCmd(0x10);	//00,水平寻址模式;01,垂直寻址模式;10,页面寻址模式(重置);11,无效WriteCmd(0xb0);	//为页面寻址模式设置页面开始地址,0-7WriteCmd(0x00); //---设置低列地址WriteCmd(0x10); //---设置高列地址WriteCmd(0xc8);	//设置COM输出扫描方向WriteCmd(0x40); //--设置起始行地址WriteCmd(0x81); //--set contrast control registerWriteCmd(0xff); //亮度调节 0x00~0xffWriteCmd(0xa1); //--设置段重新映射0到127WriteCmd(0xa6); //--设置正常显示WriteCmd(0xa8); //--设置复用比(1 ~ 64)WriteCmd(0x3F); //WriteCmd(0xa4); //0xa4,输出遵循RAM内容;0xa5,Output忽略RAM内容WriteCmd(0xd3); //-设置显示抵消WriteCmd(0x00); //-not offsetWriteCmd(0xd5); //--设置显示时钟分频/振荡器频率WriteCmd(0xf0); //--设置分率WriteCmd(0xd9); //--设置pre-charge时期WriteCmd(0x22); //WriteCmd(0xda); //--设置com大头针硬件配置WriteCmd(0x12);WriteCmd(0xdb); //--设置vcomhWriteCmd(0x20); //0x20,0.77xVccWriteCmd(0x8d); //--设置DC-DCWriteCmd(0x14); //WriteCmd(0xaf); //--打开oled面板OLED_FullyClear();//清屏
}/**************************************************************Prototype      : void OLED_ON(void)Parameters     : nonereturn					: noneDescription    : 将OLED从休眠中唤醒
***************************************************************/
void OLED_ON(void)
{WriteCmd(0X8D);  //设置电荷泵WriteCmd(0X14);  //开启电荷泵WriteCmd(0XAF);  //OLED唤醒
}/**************************************************************Prototype      : void OLED_OFF(void)Parameters     : nonereturn					: noneDescription    : 让OLED休眠 -- 休眠模式下,OLED功耗不到10uA
***************************************************************/
void OLED_OFF(void)
{WriteCmd(0X8D);  //设置电荷泵WriteCmd(0X10);  //关闭电荷泵WriteCmd(0XAE);  //OLED休眠
}/**************************************************************Prototype      : void OLED_RefreshRAM(void)Parameters     : nonereturn					: noneDescription    : 全屏填充
***************************************************************/
void OLED_RefreshRAM(void)
{// 页寻址模式填充for(uint16_t m = 0; m < displayHeight/8; m++){WriteCmd(0xb0+m);		//设置页地址b0~b7WriteCmd(0x00);		//设置显示位置—列低地址00-0fWriteCmd(0x10);		//设置显示位置—列高地址10-1ffor(uint16_t n = 0; n < displayWidth; n++){WriteDat(OLED_RAM[m][n]);}} 
}/**************************************************************Prototype      : void OLED_ClearRAM(void)Parameters     : nonereturn					: noneDescription    : 清除数据缓冲区
***************************************************************/
void OLED_ClearRAM(void)
{for(uint16_t m = 0; m < displayHeight/8; m++){for(uint16_t n = 0; n < displayWidth; n++){OLED_RAM[m][n] = 0x00;}}
}/**************************************************************Prototype      : void OLED_Fill(uint8_t fill_Data)Parameters     : fill_Data 填充的1字节数据return					: noneDescription    : 全屏填充 0x00~0xff
***************************************************************/
void OLED_FullyFill(uint8_t fill_Data)
{for(uint16_t m = 0; m < displayHeight/8; m++){for(uint16_t n = 0; n < displayWidth; n++){OLED_RAM[m][n] = fill_Data;}}OLED_RefreshRAM();
}/**************************************************************Prototype      : void OLED_FullyClear(void)Parameters     : nonereturn					: noneDescription    : 全屏清除
***************************************************************/
void OLED_FullyClear(void)
{OLED_FullyFill(RESET_PIXEL);
}/**************************************************************Prototype      :  void OLED_SetPixel(int16_t x, int16_t y, uint8_t set_pixel)Parameters     : 	x,y -- 起始点坐标(x:0~127, y:0~63); set_pixel	 该点的数据  SET_PIXEL = 1, RESET_PIXEL = 0return				 :  noneDescription    : 	设置坐标像素点数据
***************************************************************/
void OLED_SetPixel(int16_t x, int16_t y, uint8_t set_pixel)
{ if (x >= 0 && x < displayWidth && y >= 0 && y < displayHeight) {if(set_pixel){OLED_RAM[y/8][x] |= (0x01 << (y%8));}  else{OLED_RAM[y/8][x] &= ~(0x01 << (y%8));}}
}/**************************************************************Prototype      :  void OLED_GetPixel(int16_t x, int16_t y)Parameters     : 	x,y -- 起始点坐标(x:0~127, y:0~63); return				 :  PixelStatus 像素点状态 	SET_PIXEL = 1, RESET_PIXEL = 0Description    : 	获得坐标像素点数据	
***************************************************************/
PixelStatus OLED_GetPixel(int16_t x, int16_t y)
{if(OLED_RAM[y/8][x] >> (y%8) & 0x01)return SET_PIXEL;return	RESET_PIXEL;
}/**************************************************************Prototype      : void OLED_ShowStr(int16_t x, int16_t y, uint8_t ch[], uint8_t TextSize)Parameters     : 	x,y -- 起始点坐标(x:0~127, y:0~63); ch[] -- 要显示的字符串; TextSize -- 字符大小(1:6*8 ; 2:8*16)return				 :  noneDescription    : 	显示codetab.h中的ASCII字符,有6*8和8*16可选择
***************************************************************/
void OLED_ShowStr(int16_t x, int16_t y, uint8_t ch[], uint8_t TextSize)
{ if (x >= 0 && x < displayWidth && y >= 0 && y < displayHeight) {int32_t c = 0;uint8_t j = 0;switch(TextSize){case 1:{while(ch[j] != '\0'){c = ch[j] - 32;if(c < 0)	//无效字符break;if(x >= 125 || (127-x < 6))//一行最大显示字符数:21字节显示,多出两列,不显示 || 剩余列小于6不能显示完整字符,换行显示{x = 0;y += 8;//换行显示if(63 - y < 8)	// 不足以显示一行时不显示break;}for(uint8_t m = 0; m < 6; m++){for(uint8_t n = 0; n < 8; n++){OLED_SetPixel(x+m, y+n, (F6x8[c][m] >> n) & 0x01);}}x += 6;j++;}}break;case 2:{while(ch[j] != '\0'){c = ch[j] - 32;if(c < 0)	//无效字符break;if(x >= 127 || (127-x < 8))//16字节显示 || 剩余列小于8不能显示完整字符,换行显示{x = 0;y += 16;//换行显示if(63 - y < 16)	// 不足以显示一行时不显示break;}for(uint8_t m = 0; m < 2; m++){for(uint8_t n = 0; n < 8; n++){for(uint8_t i = 0; i < 8; i++){OLED_SetPixel(x+n, y+i+m*8, (F8X16[c][n+m*8] >> i) & 0x01);}}	}x += 8;j++;}}break;}}OLED_RefreshRAM();
}/**************************************************************Prototype      : void OLED_ShowCN(int16_t x, int16_t y, uint8_t* ch)Parameters     : x,y -- 起始点坐标(x:0~127, y:0~7); CN[]:汉字在codetab.h中的索引return				  : noneDescription    : 显示codetab.h中的汉字,16*16点阵
***************************************************************/
void OLED_ShowCN(int16_t x, int16_t y, uint8_t* ch)
{if (x >= 0 && x < displayWidth && y >= 0 && y < displayHeight) {int32_t  len = 0,offset = sizeof(F16x16_CN[0].index);while(ch[len] != '\0'){if(x >= 127 || (127-x < 16))//8个汉字显示||剩余列小于16不能显示完整字符,换行显示{x = 0;y += 16;if(63 - y < 16)	// 不足以显示一行时不显示break;}//需要处理输入数据大于显示数据的问题for(uint8_t i = 0; i < sizeof(F16x16_CN)/sizeof(GB2312_CN); i++){if(((F16x16_CN[i].index[0] == ch[len]) && (F16x16_CN[i].index[1] == ch[len+1]))){for(uint8_t m = 0; m < 2; m++)	//页{for(uint8_t n = 0; n < 16; n++) // 列{for(uint8_t j = 0; j < 8; j++)	// 行{OLED_SetPixel(x+n, y+j+m*8, (F16x16_CN[i].encoder[n+m*16] >> j) & 0x01);}}}			x += 16;len += offset;break;}else if(F16x16_CN[i].index[0] == ch[len] && ch[len] == 0x20){for(uint8_t m = 0; m < 2; m++){for(uint8_t n = 0; n < 16; n++){for(uint8_t j = 0; j < 8; j++){OLED_SetPixel(x+n, y+j+m*8, (F16x16_CN[i].encoder[n+m*16] >> j) & 0x01);}								}	}			x += 16;len++;break;}}}}OLED_RefreshRAM();
}/**************************************************************Prototype      : void OLED_Show_MixedCH(int16_t x, int16_t y, uint8_t* ch)Parameters     : x,y -- 起始点坐标(x:0~127, y:0~7); CN[]:汉字在codetab.h中的索引return				  : noneDescription    : 显示codetab.h中的汉字,16*16点阵,英文,8*16点阵
***************************************************************/
void OLED_ShowMixedCH(int16_t x, int16_t y, uint8_t* ch)
{if (x >= 0 && x < displayWidth && y >= 0 && y < displayHeight) {int32_t len = 0, c,offset = sizeof(F16x16_CN[0].index);while(ch[len] != '\0'){if(ch[len] >= 0xa1)//GB2312从0xA1A0开始{for(uint8_t i = 0; i < sizeof(F16x16_CN)/sizeof(GB2312_CN); i++){if(((F16x16_CN[i].index[0] == ch[len]) && (F16x16_CN[i].index[1] == ch[len+1]))){if(x >= 127|| (127-x < 16))//8个汉字显示||剩余列小于16不能显示完整字符,换行显示{x = 0;y += 16;if(63 - y < 16)	// 不足以显示一行时不显示break;}for(uint8_t m = 0; m < 2; m++)	//页{for(uint8_t n = 0; n < 16; n++)	//列{for(uint8_t j = 0; j < 8; j++)	//行{OLED_SetPixel(x+n, y+j+m*8, (F16x16_CN[i].encoder[n+m*16] >> j) & 0x01);}		}								}			x += 16;len += offset;break;}}}else if(ch[len] <= 127)//ASCII编码范围0-127{c = ch[len] - 32;if(c < 0)	// 无效字符break;if(x >= 127 || (127-x < 8))//16字节显示 || 剩余列小于8不能显示完整字符,换行显示{x = 0;y += 16;if(63 - y < 16)	// 不足以显示一行时不显示break;}for(uint8_t m = 0; m < 2; m++){for(uint8_t n = 0; n < 8; n++){for(uint8_t i = 0; i < 8; i++){OLED_SetPixel(x+n, y+i+m*8, (F8X16[c][n+m*8] >> i) & 0x01);}}}x += 8;len++;}}}OLED_RefreshRAM();
}/***************************************************************Prototype      :	void OLED_DrawBMP(int16_t x0,int16_t y0,int16_t L,int16_t H,const uint8_t BMP[])Parameters     : (x0,y0)坐标长L宽H区域绘制图像BMP0<=x0<=127 0<=y0<=63 0<=L+x0<=127 0<=H+y0<= 63 图像取模 纵向取模,字节倒序return				  : noneDescription    : 区域图像绘制,显示BMP位图,格式使用二维数组存储
***************************************************************/
void OLED_DrawBMP(int16_t x0,int16_t y0,int16_t L,int16_t H,const uint8_t BMP[])
{if (x0 >= 0 && x0 < displayWidth && x0+L <= displayWidth &&\y0 >= 0 && y0 < displayHeight && y0+H <= displayHeight) {uint8_t *p = (uint8_t *)BMP;for(int16_t y = y0; y < y0+H; y+=8){for(int16_t x = x0; x < x0+L; x++){for(int16_t i = 0; i < 8; i++){
//					OLED_SetPixel(x, y+i, ((*((uint8_t *)BMP+(x-x0)+L*((y-y0)/8))) >> i) & 0x01);OLED_SetPixel(x, y+i, ((*p) >> i) & 0x01);}p++;}}}OLED_RefreshRAM();
}/***************************************************************Prototype      :	void OLED_AreaFill(int16_t x0,int16_t y0,int16_t L,int16_t H)Parameters     : 区域内容清除,(x0,y0)坐标长L宽H区域0<=x0<=127 0<=y0<=63 0<=L+x0<=127 0<=H+y0<= 63 图像取模 纵向取模,字节倒序return				  : noneDescription    : 规定区域内容填充
***************************************************************/
void OLED_AreaFill(int16_t x0,int16_t y0,int16_t L,int16_t H, uint8_t fill_data)
{if (x0 >= 0 && x0 < displayWidth && x0+L <= displayWidth &&\y0 >= 0 && y0 < displayHeight && y0+H <= displayHeight) {for(int16_t y = y0; y < y0+H; y++){for(int16_t x = x0; x < x0+L; x++){for(int16_t i = 0; i < 8; i++){OLED_SetPixel(x, y+i, (fill_data >> i) & SET_PIXEL);}}}OLED_RefreshRAM();}
}/***************************************************************Prototype      :	void OLED_AreaCLR(int16_t x0,int16_t y0,int16_t L,int16_t H)Parameters     : (x0,y0)坐标长L宽H区域0<=x0<=127 0<=y0<=63 0<=L+x0<=127 0<=H+y0<= 63 图像取模 纵向取模,字节倒序return				  : noneDescription    : 规定区域内容清除
***************************************************************/
void OLED_AreaClear(int16_t x0,int16_t y0,int16_t L,int16_t H)
{if (x0 >= 0 && x0 < displayWidth && x0+L <= displayWidth &&\y0 >= 0 && y0 < displayHeight && y0+H <= displayHeight) {for(int16_t y = y0; y < y0+H; y+=8){for(int16_t x = x0; x < x0+L; x++){for(int16_t i = 0; i < 8; i++){OLED_SetPixel(x, y+i, RESET_PIXEL);}}}		OLED_RefreshRAM();}
}/***************************************************************Prototype      :	void OLED_FullyToggle(void)Parameters     : nonereturn				  : noneDescription    : 缓冲区数据取反后刷新到GDDRAM
***************************************************************/
void OLED_FullyToggle(void)
{for(uint16_t m = 0; m < displayHeight/8; m++){for(uint16_t n = 0; n < displayWidth; n++){OLED_RAM[m][n] = ~OLED_RAM[m][n];}}OLED_RefreshRAM();
}
/***************************************************************Prototype      :	void OLED_AreaToggle(int16_t x0,int16_t y0,int16_t L,int16_t H)Parameters     : (x0,y0)坐标长L宽H区域0<=x0<=127 0<=y0<=63 0<=L+x0<=127 0<=H+y0<= 63 图像取模 纵向取模,字节倒序return				  : noneDescription    : 规定区域内容取反
***************************************************************/
void OLED_AreaToggle(int16_t x0,int16_t y0,int16_t L,int16_t H)
{if (x0 >= 0 && x0 < displayWidth && x0+L <= displayWidth &&\y0 >= 0 && y0 < displayHeight && y0+H <= displayHeight) {for(int16_t y = y0; y < y0+H; y+=8){for(int16_t x = x0; x < x0+L; x++){for(int16_t i = 0; i < 8; i++){OLED_SetPixel(x, y+i, !OLED_GetPixel(x, y+i));}}}		OLED_RefreshRAM();}
}/****************************************************************全屏垂直偏移,0->63方向方向垂直向上,范围0-63方向垂直向下,范围63-0
****************************************************************/
void OLED_VerticalShift(void)
{for(uint8_t i = 0; i < displayHeight; i++){WriteCmd(0xd3);//设置显示偏移,0->63方向WriteCmd(i);//偏移量HAL_Delay(40);//延时时间}
}/****************************************************************屏幕内容水平全屏滚动播放左		LEFT	0x27右		RIGHT	0x26
****************************************************************/
void OLED_HorizontalShift(uint8_t direction){WriteCmd(direction);//设置滚动方向WriteCmd(0x00);//虚拟字节设置,默认为0x00WriteCmd(0x00);//设置开始页地址WriteCmd(0x05);//设置每个滚动步骤之间的时间间隔的帧频WriteCmd(0x07);//设置结束页地址WriteCmd(0x00);//虚拟字节设置,默认为0x00WriteCmd(0xff);//虚拟字节设置,默认为0xffWriteCmd(0x2f);//开启滚动-0x2f,禁用滚动-0x2e,禁用需要重写数据
}/****************************************************************屏幕内容垂直水平全屏滚动播放上		UP		0x29下		DOWN	0x2A
****************************************************************/
void OLED_VerticalAndHorizontalShift(uint8_t direction)
{WriteCmd(direction);//设置滚动方向WriteCmd(0x00);//虚拟字节设置,默认为0x00WriteCmd(0x00);//设置开始页地址WriteCmd(0x05);//设置每个滚动步骤之间的时间间隔的帧频WriteCmd(0x07);//设置结束页地址WriteCmd(0x01);//垂直滚动偏移量WriteCmd(0x2f);//开启滚动-0x2f,禁用滚动-0x2e,禁用需要重写数据
}/****************************************************************屏幕内容取反显示开	ON	0xA7关	OFF	0xA6	默认此模式,设置像素点亮
****************************************************************/
void OLED_DisplayMode(uint8_t mode)
{WriteCmd(mode);
}/****************************************************************屏幕亮度调节intensity	0-255默认为0x7f
****************************************************************/
void OLED_IntensityControl(uint8_t intensity)
{WriteCmd(0x81);WriteCmd(intensity);
}// 自定义OLED打印函数(支持可变参数)
void OLED_Printf(uint8_t x, uint8_t y, const char *format, ...) 
{uint8_t buff[30]; // 确保缓冲区足够大va_list args;va_start(args, format); // 初始化可变参数列表vsnprintf((char *)buff, sizeof(buff), format, args); // 安全格式化va_end(args); // 清理可变参数OLED_ShowMixedCH(x, y, buff); // 调用显示函数
}

OLED.h

#ifndef OLED_H__
#define OLED_H__#include "stm32f1xx_hal.h"	//链接HAL库
/* BMP图片声明 图片格式为二位数组,下标分别对应图片的宽和高:BMP_xx[H/8][L];
*/
extern const uint8_t BMP_Picture[64/8][64];/* 设置坐标点的状态 */
typedef enum 
{SET_PIXEL = 0x01,RESET_PIXEL = 0x00, 
} PixelStatus;/* 功能函数声明 */
//写数据,硬件IIC使用
void HAL_I2C_WriteByte(uint8_t addr,uint8_t data);
//写命令
void WriteCmd(uint8_t IIC_Command);
//写数据
void WriteDat(uint8_t IIC_Data);
//初始化OLED
void OLED_Init(void);
//开启电荷泵
void OLED_ON(void);
//关闭电荷泵
void OLED_OFF(void);
//刷新缓冲区数据到GDDRAM
void OLED_RefreshRAM(void);
//清除数据缓冲区OLED_RAM buffer
void OLED_ClearRAM(void);
//全屏填充
void OLED_FullyFill(uint8_t fill_Data);
//清屏
void OLED_FullyClear(void);
//设置坐标像素点数据
void OLED_SetPixel(int16_t x, int16_t y, uint8_t set_pixel);
//获得坐标像素点数据
PixelStatus OLED_GetPixel(int16_t x, int16_t y);/* 显示指定字符和图片时需要手动刷新缓冲区到GDDRAM 
* function list: OLED_ShowStr\OLED_ShowCN\OLED_Show_MixedCH\OLED_DrawBMP
*/
//显示英文字符串
void OLED_ShowStr(int16_t x, int16_t y, uint8_t ch[], uint8_t TextSize);
//显示中文字符串
void OLED_ShowCN(int16_t x, int16_t y, uint8_t* ch);
//显示中英文混合文字
void OLED_ShowMixedCH(int16_t x, int16_t y, uint8_t* ch);
//显示图片
void OLED_DrawBMP(int16_t x0,int16_t y0,int16_t L,int16_t H,const uint8_t BMP[]);//区域填充
void OLED_AreaFill(int16_t x0,int16_t y0,int16_t L,int16_t H, uint8_t fill_data);
//区域清除
void OLED_AreaClear(int16_t x0,int16_t y0,int16_t L,int16_t H);
//全屏切换显示
void OLED_FullyToggle(void);
//区域切换显示
void OLED_AreaToggle(int16_t x0,int16_t y0,int16_t L,int16_t H);
//全屏垂直滚动播放
void OLED_VerticalShift(void);
//全屏水平滚动播放
void OLED_HorizontalShift(uint8_t direction);
//全屏同时垂直和水平滚动播放
void OLED_VerticalAndHorizontalShift(uint8_t direction);
//屏幕内容取反显示
void OLED_DisplayMode(uint8_t mode);
//屏幕亮度调节
void OLED_IntensityControl(uint8_t intensity);
//可变参数的打印函数
void OLED_Printf(uint8_t x, uint8_t y, const char *format, ...);#endif

字库

/************************************************************************************
*  Copyright (c), 2021.04, ZeroCHN.
*            All rights reserved.
*
* Description:
* 1. 128*64点整OLED模块功能演示程序的字表
* 2. 取字方式 -- 共阴、列行式、逆向输出
*
*	version: 1.2
*
*************************************************************************************/
#ifndef FONT_H__
#define FONT_H__
#ifdef __cplusplusextern "C" {
#endif#include "stm32f1xx_hal.h"/************************************6*8的点阵************************************/
const uint8_t F6x8[][6] =
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00,// sp0x00, 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,// 00x00, 0x00, 0x42, 0x7F, 0x40, 0x00,// 10x00, 0x42, 0x61, 0x51, 0x49, 0x46,// 20x00, 0x21, 0x41, 0x45, 0x4B, 0x31,// 30x00, 0x18, 0x14, 0x12, 0x7F, 0x10,// 40x00, 0x27, 0x45, 0x45, 0x45, 0x39,// 50x00, 0x3C, 0x4A, 0x49, 0x49, 0x30,// 60x00, 0x01, 0x71, 0x09, 0x05, 0x03,// 70x00, 0x36, 0x49, 0x49, 0x49, 0x36,// 80x00, 0x06, 0x49, 0x49, 0x29, 0x1E,// 90x00, 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,// A0x00, 0x7F, 0x49, 0x49, 0x49, 0x36,// B0x00, 0x3E, 0x41, 0x41, 0x41, 0x22,// C0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C,// D0x00, 0x7F, 0x49, 0x49, 0x49, 0x41,// E0x00, 0x7F, 0x09, 0x09, 0x09, 0x01,// F0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A,// G0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F,// H0x00, 0x00, 0x41, 0x7F, 0x41, 0x00,// I0x00, 0x20, 0x40, 0x41, 0x3F, 0x01,// J0x00, 0x7F, 0x08, 0x14, 0x22, 0x41,// K0x00, 0x7F, 0x40, 0x40, 0x40, 0x40,// L0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F,// M0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F,// N0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E,// O0x00, 0x7F, 0x09, 0x09, 0x09, 0x06,// P0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E,// Q0x00, 0x7F, 0x09, 0x19, 0x29, 0x46,// R0x00, 0x46, 0x49, 0x49, 0x49, 0x31,// S0x00, 0x01, 0x01, 0x7F, 0x01, 0x01,// T0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F,// U0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F,// V0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F,// W0x00, 0x63, 0x14, 0x08, 0x14, 0x63,// X0x00, 0x07, 0x08, 0x70, 0x08, 0x07,// Y0x00, 0x61, 0x51, 0x49, 0x45, 0x43,// Z0x00, 0x00, 0x7F, 0x41, 0x41, 0x00,// [0x00, 0x55, 0x2A, 0x55, 0x2A, 0x55,// 550x00, 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,// a0x00, 0x7F, 0x48, 0x44, 0x44, 0x38,// b0x00, 0x38, 0x44, 0x44, 0x44, 0x20,// c0x00, 0x38, 0x44, 0x44, 0x48, 0x7F,// d0x00, 0x38, 0x54, 0x54, 0x54, 0x18,// e0x00, 0x08, 0x7E, 0x09, 0x01, 0x02,// f0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C,// g0x00, 0x7F, 0x08, 0x04, 0x04, 0x78,// h0x00, 0x00, 0x44, 0x7D, 0x40, 0x00,// i0x00, 0x40, 0x80, 0x84, 0x7D, 0x00,// j0x00, 0x7F, 0x10, 0x28, 0x44, 0x00,// k0x00, 0x00, 0x41, 0x7F, 0x40, 0x00,// l0x00, 0x7C, 0x04, 0x18, 0x04, 0x78,// m0x00, 0x7C, 0x08, 0x04, 0x04, 0x78,// n0x00, 0x38, 0x44, 0x44, 0x44, 0x38,// o0x00, 0xFC, 0x24, 0x24, 0x24, 0x18,// p0x00, 0x18, 0x24, 0x24, 0x18, 0xFC,// q0x00, 0x7C, 0x08, 0x04, 0x04, 0x08,// r0x00, 0x48, 0x54, 0x54, 0x54, 0x20,// s0x00, 0x04, 0x3F, 0x44, 0x40, 0x20,// t0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C,// u0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C,// v0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C,// w0x00, 0x44, 0x28, 0x10, 0x28, 0x44,// x0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C,// y0x00, 0x44, 0x64, 0x54, 0x4C, 0x44,// z0x14, 0x14, 0x14, 0x14, 0x14, 0x14,// horiz lines
};
/****************************************8*16的点阵************************************/
const uint8_t F8X16[][16]=	  
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// 00x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x30,0x00,0x00,0x00,//! 10x00,0x10,0x0C,0x06,0x10,0x0C,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//" 20x40,0xC0,0x78,0x40,0xC0,0x78,0x40,0x00,0x04,0x3F,0x04,0x04,0x3F,0x04,0x04,0x00,//# 30x00,0x70,0x88,0xFC,0x08,0x30,0x00,0x00,0x00,0x18,0x20,0xFF,0x21,0x1E,0x00,0x00,//$ 40xF0,0x08,0xF0,0x00,0xE0,0x18,0x00,0x00,0x00,0x21,0x1C,0x03,0x1E,0x21,0x1E,0x00,//% 50x00,0xF0,0x08,0x88,0x70,0x00,0x00,0x00,0x1E,0x21,0x23,0x24,0x19,0x27,0x21,0x10,//& 60x10,0x16,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//' 70x00,0x00,0x00,0xE0,0x18,0x04,0x02,0x00,0x00,0x00,0x00,0x07,0x18,0x20,0x40,0x00,//( 80x00,0x02,0x04,0x18,0xE0,0x00,0x00,0x00,0x00,0x40,0x20,0x18,0x07,0x00,0x00,0x00,//) 90x40,0x40,0x80,0xF0,0x80,0x40,0x40,0x00,0x02,0x02,0x01,0x0F,0x01,0x02,0x02,0x00,//* 100x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x1F,0x01,0x01,0x01,0x00,//+ 110x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xB0,0x70,0x00,0x00,0x00,0x00,0x00,//, 120x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,//- 130x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00,//. 140x00,0x00,0x00,0x00,0x80,0x60,0x18,0x04,0x00,0x60,0x18,0x06,0x01,0x00,0x00,0x00,/// 150x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,//0 160x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//1 170x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,//2 180x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00,//3 190x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00,//4 200x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00,//5 210x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00,//6 220x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,//7 230x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00,//8 240x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00,//9 250x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,//: 260x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x60,0x00,0x00,0x00,0x00,//; 270x00,0x00,0x80,0x40,0x20,0x10,0x08,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x00,//< 280x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00,//= 290x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x20,0x10,0x08,0x04,0x02,0x01,0x00,//> 300x00,0x70,0x48,0x08,0x08,0x08,0xF0,0x00,0x00,0x00,0x00,0x30,0x36,0x01,0x00,0x00,//? 310xC0,0x30,0xC8,0x28,0xE8,0x10,0xE0,0x00,0x07,0x18,0x27,0x24,0x23,0x14,0x0B,0x00,//@ 320x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00,0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20,//A 330x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00,//B 340xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00,0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00,//C 350x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00,0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00,//D 360x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x20,0x23,0x20,0x18,0x00,//E 370x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x00,0x03,0x00,0x00,0x00,//F 380xC0,0x30,0x08,0x08,0x08,0x38,0x00,0x00,0x07,0x18,0x20,0x20,0x22,0x1E,0x02,0x00,//G 390x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20,//H 400x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//I 410x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,0x00,//J 420x08,0xF8,0x88,0xC0,0x28,0x18,0x08,0x00,0x20,0x3F,0x20,0x01,0x26,0x38,0x20,0x00,//K 430x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x20,0x30,0x00,//L 440x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08,0x00,0x20,0x3F,0x00,0x3F,0x00,0x3F,0x20,0x00,//M 450x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08,0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00,//N 460xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,0x00,//O 470x08,0xF8,0x08,0x08,0x08,0x08,0xF0,0x00,0x20,0x3F,0x21,0x01,0x01,0x01,0x00,0x00,//P 480xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x18,0x24,0x24,0x38,0x50,0x4F,0x00,//Q 490x08,0xF8,0x88,0x88,0x88,0x88,0x70,0x00,0x20,0x3F,0x20,0x00,0x03,0x0C,0x30,0x20,//R 500x00,0x70,0x88,0x08,0x08,0x08,0x38,0x00,0x00,0x38,0x20,0x21,0x21,0x22,0x1C,0x00,//S 510x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//T 520x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//U 530x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08,0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00,//V 540xF8,0x08,0x00,0xF8,0x00,0x08,0xF8,0x00,0x03,0x3C,0x07,0x00,0x07,0x3C,0x03,0x00,//W 550x08,0x18,0x68,0x80,0x80,0x68,0x18,0x08,0x20,0x30,0x2C,0x03,0x03,0x2C,0x30,0x20,//X 560x08,0x38,0xC8,0x00,0xC8,0x38,0x08,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//Y 570x10,0x08,0x08,0x08,0xC8,0x38,0x08,0x00,0x20,0x38,0x26,0x21,0x20,0x20,0x18,0x00,//Z 580x00,0x00,0x00,0xFE,0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x7F,0x40,0x40,0x40,0x00,//[ 590x00,0x0C,0x30,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x06,0x38,0xC0,0x00,//\ 600x00,0x02,0x02,0x02,0xFE,0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x7F,0x00,0x00,0x00,//] 610x00,0x00,0x04,0x02,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//^ 620x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,//_ 630x00,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//` 640x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x19,0x24,0x22,0x22,0x22,0x3F,0x20,//a 650x08,0xF8,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x11,0x20,0x20,0x11,0x0E,0x00,//b 660x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x0E,0x11,0x20,0x20,0x20,0x11,0x00,//c 670x00,0x00,0x00,0x80,0x80,0x88,0xF8,0x00,0x00,0x0E,0x11,0x20,0x20,0x10,0x3F,0x20,//d 680x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x22,0x22,0x22,0x22,0x13,0x00,//e 690x00,0x80,0x80,0xF0,0x88,0x88,0x88,0x18,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//f 700x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x6B,0x94,0x94,0x94,0x93,0x60,0x00,//g 710x08,0xF8,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//h 720x00,0x80,0x98,0x98,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//i 730x00,0x00,0x00,0x80,0x98,0x98,0x00,0x00,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,//j 740x08,0xF8,0x00,0x00,0x80,0x80,0x80,0x00,0x20,0x3F,0x24,0x02,0x2D,0x30,0x20,0x00,//k 750x00,0x08,0x08,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//l 760x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x20,0x3F,0x20,0x00,0x3F,0x20,0x00,0x3F,//m 770x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//n 780x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//o 790x80,0x80,0x00,0x80,0x80,0x00,0x00,0x00,0x80,0xFF,0xA1,0x20,0x20,0x11,0x0E,0x00,//p 800x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x0E,0x11,0x20,0x20,0xA0,0xFF,0x80,//q 810x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x20,0x20,0x3F,0x21,0x20,0x00,0x01,0x00,//r 820x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x33,0x24,0x24,0x24,0x24,0x19,0x00,//s 830x00,0x80,0x80,0xE0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x1F,0x20,0x20,0x00,0x00,//t 840x80,0x80,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x1F,0x20,0x20,0x20,0x10,0x3F,0x20,//u 850x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x00,0x01,0x0E,0x30,0x08,0x06,0x01,0x00,//v 860x80,0x80,0x00,0x80,0x00,0x80,0x80,0x80,0x0F,0x30,0x0C,0x03,0x0C,0x30,0x0F,0x00,//w 870x00,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x31,0x2E,0x0E,0x31,0x20,0x00,//x 880x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x80,0x81,0x8E,0x70,0x18,0x06,0x01,0x00,//y 890x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x21,0x30,0x2C,0x22,0x21,0x30,0x00,//z 900x00,0x00,0x00,0x00,0x80,0x7C,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x3F,0x40,0x40,//{ 910x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,//| 920x00,0x02,0x02,0x7C,0x80,0x00,0x00,0x00,0x00,0x40,0x40,0x3F,0x00,0x00,0x00,0x00,//} 930x00,0x06,0x01,0x01,0x02,0x02,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//~ 94
};/************************************汉字字模数据结构             1.汉字内码索引                 点阵码数据 
************************************/
typedef struct {     char index[2];                                             uint8_t encoder[32];                                             
}GB2312_CN;/* 添加中文字体,请添加为16个元素的一维数组模式 */
const GB2312_CN F16x16_CN[] = {{0x10,0x60,0x02,0x8C,0x00,0x00,0xFE,0x92,0x92,0x92,0x92,0x92,0xFE,0x00,0x00,0x00,0x04,0x04,0x7E,0x01,0x40,0x7E,0x42,0x42,0x7E,0x42,0x7E,0x42,0x42,0x7E,0x40,0x00,/*"温"*/},{0x00,0x00,0xFC,0x24,0x24,0x24,0xFC,0x25,0x26,0x24,0xFC,0x24,0x24,0x24,0x04,0x00,0x40,0x30,0x8F,0x80,0x84,0x4C,0x55,0x25,0x25,0x25,0x55,0x4C,0x80,0x80,0x80,0x00,/*"度"*/},{0x00,0x00,0x24,0x24,0x24,0x24,0x24,0xFC,0x22,0x22,0x22,0x23,0x22,0x00,0x00,0x00,0x02,0x02,0x02,0x02,0x02,0x42,0x82,0x7F,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x00,},/*"手"*/{0x40,0x44,0xC4,0x44,0x44,0x44,0x40,0x10,0x10,0xFF,0x10,0x10,0x10,0xF0,0x00,0x00,0x10,0x3C,0x13,0x10,0x14,0xB8,0x40,0x30,0x0E,0x01,0x40,0x80,0x40,0x3F,0x00,0x00,},/*"动"*/{0x10,0x10,0xD0,0xFF,0x90,0x14,0xE4,0xAF,0xA4,0xA4,0xA4,0xAF,0xE4,0x04,0x00,0x00,0x04,0x03,0x00,0xFF,0x00,0x89,0x4B,0x2A,0x1A,0x0E,0x1A,0x2A,0x4B,0x88,0x80,0x00,},/*"模"*/{0x10,0x10,0x90,0x90,0x90,0x90,0x90,0x10,0x10,0xFF,0x10,0x10,0x11,0x16,0x10,0x00,0x00,0x20,0x60,0x20,0x3F,0x10,0x10,0x10,0x00,0x03,0x0C,0x10,0x20,0x40,0xF8,0x00,},/*"式"*/{0x10,0x94,0x53,0x32,0x1E,0x32,0x52,0x10,0x00,0x7E,0x42,0x42,0x42,0x7E,0x00,0x00,0x00,0x00,0x00,0xFF,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0xFF,0x00,0x00,0x00,0x00,},/*"智"*/{0x08,0xCC,0x4A,0x49,0x48,0x4A,0xCC,0x18,0x00,0x7F,0x88,0x88,0x84,0x82,0xE0,0x00,0x00,0xFF,0x12,0x12,0x52,0x92,0x7F,0x00,0x00,0x7E,0x88,0x88,0x84,0x82,0xE0,0x00,},/*"能"*/{0x10,0x60,0x02,0x8C,0x00,0xFE,0x92,0x92,0x92,0x92,0x92,0x92,0xFE,0x00,0x00,0x00,0x04,0x04,0x7E,0x01,0x44,0x48,0x50,0x7F,0x40,0x40,0x7F,0x50,0x48,0x44,0x40,0x00,},/*"湿"*/{0x00,0x00,0xFC,0x24,0x24,0x24,0xFC,0x25,0x26,0x24,0xFC,0x24,0x24,0x24,0x04,0x00,0x40,0x30,0x8F,0x80,0x84,0x4C,0x55,0x25,0x25,0x25,0x55,0x4C,0x80,0x80,0x80,0x00,},/*"度"*/{0x00,0x20,0x20,0x20,0xA0,0x60,0x00,0xFF,0x60,0x80,0x40,0x20,0x18,0x00,0x00,0x00,0x20,0x10,0x08,0x06,0x01,0x40,0x80,0x7F,0x00,0x01,0x02,0x04,0x08,0x10,0x10,0x00,},/*"水"*/{0x00,0x80,0x60,0xF8,0x07,0x10,0x90,0x10,0x11,0x16,0x10,0x10,0xD0,0x10,0x00,0x00,0x01,0x00,0x00,0xFF,0x40,0x40,0x41,0x5E,0x40,0x40,0x70,0x4E,0x41,0x40,0x40,0x00,},/*"位"*/{0x04,0x04,0x84,0xC4,0xA4,0x9C,0x85,0x86,0x84,0x84,0xA4,0xC4,0x84,0x04,0x04,0x00,0x00,0x80,0x80,0x40,0x30,0x0F,0x00,0x00,0x00,0x7F,0x80,0x80,0x81,0xF0,0x00,0x00,},/*"充"*/{0x00,0x00,0x00,0x7E,0x42,0x42,0x42,0xC2,0x42,0x42,0x42,0x7E,0x00,0x00,0x00,0x00,0x80,0x40,0x30,0x0E,0x10,0x20,0x40,0x7F,0x44,0x44,0x44,0x44,0x44,0x40,0x40,0x00,},/*"足"*/{0x00,0x02,0x02,0x02,0x02,0x82,0x42,0xF2,0x0E,0x42,0x82,0x02,0x02,0x02,0x00,0x00,0x10,0x08,0x04,0x02,0x01,0x00,0x00,0xFF,0x00,0x00,0x00,0x01,0x02,0x0C,0x00,0x00,},/*"不"*/{0x00,0x00,0x00,0x7E,0x42,0x42,0x42,0xC2,0x42,0x42,0x42,0x7E,0x00,0x00,0x00,0x00,0x80,0x40,0x30,0x0E,0x10,0x20,0x40,0x7F,0x44,0x44,0x44,0x44,0x44,0x40,0x40,0x00,},/*"足"*/{0x10,0x10,0x10,0xFF,0x10,0x10,0xF0,0x00,0x00,0xF8,0x08,0x08,0x08,0xF8,0x00,0x00,0x80,0x40,0x30,0x0F,0x40,0x80,0x7F,0x00,0x00,0x7F,0x20,0x20,0x20,0x7F,0x00,0x00,},/*"加"*/{0x80,0x80,0x9E,0x92,0x92,0x92,0x9E,0xE0,0x80,0x9E,0xB2,0xD2,0x92,0x9E,0x80,0x00,0x08,0x08,0xF4,0x94,0x92,0x92,0xF1,0x00,0x01,0xF2,0x92,0x94,0x94,0xF8,0x08,0x00,},/*"器"*/{0x80,0x82,0x82,0x82,0xFE,0x82,0x82,0x82,0x82,0x82,0xFE,0x82,0x82,0x82,0x80,0x00,0x00,0x80,0x40,0x30,0x0F,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,},/*"开"*/{0x00,0x00,0x00,0xFC,0x44,0x44,0x44,0x45,0x46,0x44,0x44,0x44,0x44,0x7C,0x00,0x00,0x40,0x20,0x18,0x07,0x00,0xFC,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0xFC,0x00,0x00,},/*"启"*/{0x00,0x00,0x10,0x11,0x16,0x10,0x10,0xF0,0x10,0x10,0x14,0x13,0x10,0x00,0x00,0x00,0x81,0x81,0x41,0x41,0x21,0x11,0x0D,0x03,0x0D,0x11,0x21,0x41,0x41,0x81,0x81,0x00,},/*"关"*/{0x00,0xF8,0x01,0x22,0x20,0x22,0x22,0xA2,0xFA,0x22,0x22,0x22,0x02,0xFE,0x00,0x00,0x00,0xFF,0x00,0x08,0x04,0x02,0x11,0x20,0x1F,0x00,0x00,0x40,0x80,0x7F,0x00,0x00}/*"闭"*/
};/* 添加图片请按照高*宽的模式添加 BMP图片声明,图片格式为二位数组,下标分别对应图片的宽和高:BMP_xx[H/8][L];
*/
const uint8_t BMP_Picture[64/8][64] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,
0x80,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,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,0x80,0x40,0x30,0x1E,
0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x3C,0x40,0x60,0x20,0x20,0x20,0x20,
0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x60,0xC0,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,0x30,0x10,0x10,0x08,0x04,0x04,0x02,0xFD,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x0C,0x06,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,
0x00,0x30,0x10,0x10,0x10,0x10,0x10,0x08,0x08,0x04,0x07,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,0xFB,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0x30,0x00,0x00,0x00,0x00,0x03,
0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,
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,0xFF,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x50,0x80,0x00,0x00,0x80,
0xFF,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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x3F,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x70,0xF0,0x0F,
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,
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,
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,
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,
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,
};//encode#ifdef __cplusplus
}
#endif
#endif

继电器

我采用的继电器是低电平触发

简单的代码 

#include "stm32f1xx_hal.h"	//链接HAL库
#include "zzyy_OLED.h"
#include "DHT11.h"void Relay_Init(void)  //继电器初始化  高电平继电器闭合
{ HAL_GPIO_WritePin(GPIOB, GPIO_PIN_11, GPIO_PIN_RESET);
}void Relay_Control(uint8_t state)  //state:1闭合继电器 0
{if(state){HAL_GPIO_WritePin(GPIOB, GPIO_PIN_11, GPIO_PIN_SET);}else {HAL_GPIO_WritePin(GPIOB, GPIO_PIN_11, GPIO_PIN_RESET);}}void Relay_Alarm(void)  //湿度过低加湿器工作
{if(humidity < Humi_Limt){Relay_Control(1);}else Relay_Control(0);
}
#ifndef __REALY_H
#define __REALY_Hvoid Relay_Init(void);  //继电器初始化
void Relay_Control(uint8_t state);  //state:1闭合继电器 0void Relay_Alarm(void);  //湿度过低加湿器工作#endif 

水位传感器

水位传感器就没什么好说的,直接整好ADC后就可以直接读取对应的ADC值了,最后对水位数值进行计算

#include "stm32f1xx_hal.h"	//链接HAL库
#include "adc.h"uint16_t WaterDeep_ADCValue;  //水位传感器的AD值uint8_t WaterDeep;void WaterDeep_Init(void)
{HAL_ADC_Init(&hadc1);HAL_ADC_Start(&hadc1);  //开启ADC转换HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);  //等待转换完成
}void WaterDeep_Get_ADCData(void)
{WaterDeep_ADCValue = HAL_ADC_GetValue(&hadc1);WaterDeep = ((WaterDeep_ADCValue/4096.0)*100.0);}
#ifndef __WATERDEEP_H
#define __WATERDEEP_Hextern uint16_t WaterDeep_ADCValue;  //水位传感器的AD值extern uint8_t WaterDeep;  //真实水位void WaterDeep_Init(void);
void WaterDeep_Get_ADCData(void);#endif 

有源蜂鸣器

有源的直接通电就能响

蜂鸣器的“有源”和“无源”是初学者容易混淆的概念,这里的“源”指的并非电源,而是振荡源。为了让你能快速抓住核心,我先用一个表格来汇总它们的主要区别。

特性

有源蜂鸣器

无源蜂鸣器

核心区别

内部自带振荡源

内部无振荡源

驱动信号

直流电压​(如恒定高电平)

特定频率的方波​(如PWM脉冲)

声音控制

音调固定,无法改变

音调可调,通过改变方波频率可发出不同音阶

使用复杂度

简单,通电即响

稍复杂,需单片机定时器或PWM模块产生信号

成本

通常较高(因内部电路更复杂)

通常较低

外观区分

内部用黑胶封闭,底部可能看不到绿色电路板;整体可能稍高(如9mm)

底部可见绿色电路板;整体可能稍矮(如8mm)

  • 有源蜂鸣器的内部集成了一个振荡电路。当你给它加上额定电压的直流电时,这个电路会自动产生固定频率的脉冲信号,驱动蜂鸣片振动发声。所以,它的控制就像开关一样简单:给高电平就响,给低电平就停

  • 无源蜂鸣器的内部结构相对简单,可以理解为一个“微型扬声器”。它本身不会振动,需要依赖外部的控制器(如单片机)提供一个交变的信号来驱动。这个信号通常是特定频率和占空比的方波(PWM)。改变方波的频率,就能改变它发出声音的音调

简单的封装函数 

#include "stm32f1xx_hal.h"	//链接HAL库
#include "zzyy_OLED.h"
#include "WaterDeep.h"#define Buzzer_Pin GPIO_PIN_1  //引脚定义
#define Buzzer_Port GPIOA uint8_t Buzzer_cycle_Flag;void Buzzer_Init(void)
{HAL_GPIO_WritePin(Buzzer_Port, Buzzer_Pin, GPIO_PIN_SET);
}void Buzzer_Control(uint8_t state) //蜂鸣器开关函数 1开0关
{if(state){HAL_GPIO_WritePin(Buzzer_Port, Buzzer_Pin, GPIO_PIN_RESET);}else {HAL_GPIO_WritePin(Buzzer_Port, Buzzer_Pin, GPIO_PIN_SET);}
}void Buzzer_cycle(uint8_t state)  //state:状态 1开启蜂鸣器周期性鸣叫 0关
{if(state){if(Buzzer_cycle_Flag){HAL_GPIO_WritePin(Buzzer_Port, Buzzer_Pin, GPIO_PIN_RESET);}else {HAL_GPIO_WritePin(Buzzer_Port, Buzzer_Pin, GPIO_PIN_SET);}}else {HAL_GPIO_WritePin(Buzzer_Port, Buzzer_Pin, GPIO_PIN_SET);}
}void Buzzer_Alarm(void)  //水位过低蜂鸣器报警
{if(WaterDeep < Water_Deep_Limt){Buzzer_cycle(1);}else {Buzzer_cycle(0);}
}
#ifndef __BUZZER_h
#define __BUZZER_hextern uint8_t Buzzer_cycle_Flag;void Buzzer_Init(void);void Buzzer_Control(uint8_t state); //蜂鸣器开关函数 1开0关void Buzzer_cycle(uint8_t state);  //state:状态 1开启蜂鸣器周期性鸣叫 0关void Buzzer_Alarm(void);  //水位过低蜂鸣器报警#endif 

DHT11温湿度

注意点:

特性分类

具体参数 / 描述

核心功能

同时测量环境温度湿度

输出信号

单总线数字信号,只需一根数据线

测量范围

湿度:20% ~ 90% RH;温度:0℃ ~ 50℃

测量精度

湿度:±5% RH;温度:±2℃

工作电压

3.3V ~ 5.5V,与多数单片机兼容

核心优势

成本低、接口简单、功耗低(平均电流约0.5mA)

为了能稳定可靠地使用DHT11,有几个关键点需要留意:

  • 通信间隔​:连续两次读取数据之间的时间间隔建议不小于2秒,否则可能导致读数不稳定或出错

  • 一上电要延时2秒度过不稳当时期
  • 时序要求​:DHT11 对通信时序要求比较严格,在编写驱动程序时需要确保微秒级的延时准确

  • 接线确认​:务必正确连接电源(VCC)、地(GND)和数据线(DATA),接反电源线可能会损坏传感器

  • 上拉电阻​:单总线通常需要在数据线上连接一个4.7kΩ或5.1kΩ的上拉电阻到VCC,以确保总线在空闲时保持高电平。有些DHT11模块已经内置了这个电阻

#include "stm32f1xx_hal.h"	//链接HAL库
#include "tim.h"void delay_us(uint16_t nus)
{__HAL_TIM_SET_COUNTER(&htim1, 0);__HAL_TIM_ENABLE(&htim1);while (__HAL_TIM_GET_COUNTER(&htim1) < nus){}__HAL_TIM_DISABLE(&htim1);
}void DHT11_OUT(void )//输出引脚
{GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.Pin = GPIO_PIN_15;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_PULLUP;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
}
void DHT11_IN(void )//输入引脚
{GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.Pin = GPIO_PIN_15;GPIO_InitStruct.Mode = GPIO_MODE_INPUT ;GPIO_InitStruct.Pull = GPIO_PULLUP;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
}void DHT11_REST(void ) //主机发出起始信号
{DHT11_OUT();HAL_GPIO_WritePin (GPIOC ,GPIO_PIN_15 ,GPIO_PIN_RESET );HAL_Delay (20);HAL_GPIO_WritePin (GPIOC ,GPIO_PIN_15 ,GPIO_PIN_SET );delay_us (30);
}//gpio端口为输入模式时,配置为上拉输入或者浮空输入,因外接上拉电阻,默认为高电平
//当有负信号输入时,gpio端口为1.
//若有负信号输入,当信号引脚连接到GND或者其他低电平信号时,GPIO端口会检测到低电平并显示为0。
//这是因为负信号的优先级高于上拉电阻的电平设置。uint8_t DHT11_Check(void)
{uint8_t retry = 0;// 1. 发送起始信号DHT11_OUT();  // 设置为输出模式HAL_GPIO_WritePin(GPIOC, GPIO_PIN_15, GPIO_PIN_RESET);HAL_Delay(20);HAL_GPIO_WritePin(GPIOC, GPIO_PIN_15, GPIO_PIN_SET);delay_us(30);DHT11_IN();  // 设置数据引脚为输入模式while (HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_15) == 1 && retry < 80){retry++;delay_us(1);  // 延迟1微秒}if (retry >= 80)return 1;  // 如果在规定时间内引脚仍为高电平,表示传感器未响应,返回错误代码 1elseretry = 0;while (HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_15) == 0 && retry < 80){retry++;delay_us(1);  // 延迟1微秒}if (retry >= 80)return 1;  // 如果在规定时间内引脚仍为低电平,表示传感器未响应,返回错误代码 1return 0;  // 传感器响应正常,返回成功代码 0
}
//读取一个位,参考高低电平的时序
uint8_t DHT11_Read_Bit(void)
{uint8_t retry=0;while((HAL_GPIO_ReadPin (GPIOC ,GPIO_PIN_15)==1) && (retry <100)){retry ++;delay_us (1);}retry=0;while((HAL_GPIO_ReadPin(GPIOC ,GPIO_PIN_15)==0) && (retry <100)){retry ++;delay_us (1);}delay_us (40);if(HAL_GPIO_ReadPin (GPIOC ,GPIO_PIN_15 )==1)return 1;// 返回读取到的位为高电平else return 0;// 返回读取到的位为低电平
}//读取一个字节,接收数据
uint8_t DHT11_Read_Byte(void)
{uint8_t dat=0;for(uint8_t i=0;i<8;i++){dat <<= 1;dat |= DHT11_Read_Bit();}return dat;}
//更据上面的数据格式,解码数据
uint8_t DHT11_Read_Data(uint8_t* humi, uint8_t* temp)
{uint8_t buf[5];  // 存储读取到的5个字节数据的缓冲区DHT11_REST();  // 初始化传感器通信if (DHT11_Check() == 0)  // 检查传感器是否正常响应{for (uint8_t i = 0; i < 5; i++)buf[i] = DHT11_Read_Byte();  // 逐个字节读取传感器发送的数据if ((buf[0] + buf[1] + buf[2] + buf[3]) == buf[4])  // 校验数据的准确性{*humi = buf[0];  // 将湿度值存储到指定的变量中*temp = buf[2];  // 将温度值存储到指定的变量中}}else{return 1;  // 传感器响应异常,返回错误代码}return 0;  // 读取数据成功,返回正常代码
}
#ifndef __DHT11_h
#define __DHT11_h#include "main.h"void DHT11_REST(void);                            //复位DHT11
uint8_t DHT11_Check(void);                       //DHT11状态反馈
uint8_t DHT11_Read_Bit(void);                    //读DHT11一位数据
uint8_t DHT11_Read_Byte(void);                   //读DHT11一字节数据
uint8_t DHT11_Read_Data(uint8_t* humi,uint8_t* temp);     //DHT11数据显示#endif /*__dht11_h*/

功能图

http://www.dtcms.com/a/415005.html

相关文章:

  • 网站开发管理nodejs网站开发教程
  • webrtc弱网-TrendlineEstimator类源码分析与算法原理
  • RocketMQ 消息堆积:快速定位、处理与预防方案
  • 深圳网站建设制作开发咨询邯郸网站建设
  • P3051题解
  • 想给孩子找点题做 都有什么网站化学课件
  • 【2026计算机毕业设计】基于Springboot的汉服交流的微信小程序
  • uutils coreutils - GNU coreutils 的 Rust 跨平台实现
  • 如何在阿里巴巴上做网站去哪网站备案吗
  • 软考中级-软件设计师(五)
  • 零基础学Docker(5)--容器数据卷
  • list列表
  • 团购网站做摄影网站编程开发
  • Kurt-Blender零基础教程:第4章:粒子篇
  • Qt常用控件之QTextEdit
  • ImageHash - Python 图像哈希库
  • 初识 Vue
  • 做网站销售水果上海建设安全协会网站
  • 正能量视频素材免费下载网站现代营销手段有哪些
  • Prj11-8088单板机C语言大综合(一)
  • 44.网络层
  • 肇庆网站制作软件郑州企业网络推广公司
  • ALLaM - 专为阿拉伯语设计的AI大语言模型
  • Docker Compose 停止命令对比
  • 北京网站推广优化更改wordpress端口
  • 优势的seo网站优化排名网站内容质量
  • Transformer 能做什么?—— 多领域应用全景
  • 认识RAG
  • 网站人员队伍建设薄弱怎么在自己做的网站上发视频教程
  • 摄影网站设计说明书东莞招聘信息最新招聘官方网