找一个基于单片机的小项目,把具体的实际应用实现了温湿度检测显示,电路图与原代码,注释,芯片引脚使用,真正的算法流程,最终实现效果。
时间: 2023-06-27 16:02:24 浏览: 113
好的,我来介绍一个基于单片机的小项目:温湿度检测显示器。
### 1. 项目介绍
本项目采用单片机 STM32F103C8T6,通过连接 DHT11 温湿度传感器实现温湿度数据的检测,并通过 OLED 显示屏展示温湿度数据。本项目可以用于家居、办公室等场所的温湿度检测。
### 2. 硬件设计
本项目的硬件设计如下:
![温湿度检测显示器电路图](https://img-blog.csdnimg.cn/2021120220173374.png)
其中,DHT11 温湿度传感器连接到单片机的 PB1 引脚,OLED 显示屏连接到单片机的 I2C2 引脚(SCL: PB10,SDA: PB11)。
### 3. 软件设计
本项目的软件设计采用 Keil uVision 5 软件进行编写。
#### 3.1 引脚定义
首先,需要对单片机的引脚进行定义,代码如下:
```c
#define DHT11_PORT GPIOB
#define DHT11_PIN GPIO_Pin_1
#define I2C2_SCL_PORT GPIOB
#define I2C2_SCL_PIN GPIO_Pin_10
#define I2C2_SDA_PORT GPIOB
#define I2C2_SDA_PIN GPIO_Pin_11
```
#### 3.2 DHT11 温湿度传感器数据读取
DHT11 温湿度传感器是一种数字温湿度传感器,可以直接输出数字信号。读取 DHT11 温湿度传感器的数据需要按照一定的时序进行读取。具体的时序如下:
1. 主机发送起始信号,即将总线拉低至少 18ms。
2. 主机拉高总线,等待 DHT11 的响应信号,即 DHT11 将总线拉低 80us 以上,再将总线拉高 80us 以下。
3. DHT11 开始传输数据,先传输湿度数据的高 8 位,然后传输湿度数据的低 8 位,接着传输温度数据的高 8 位,最后传输温度数据的低 8 位,共 40 位数据。
4. 主机接收数据后,需要进行数据的校验和计算,判断数据是否正确。
根据上述时序,我们可以编写以下代码来读取 DHT11 温湿度传感器的数据:
```c
uint8_t DHT11_Read_Data(float *temp, float *hum)
{
uint8_t i, j, dht11_data[5] = {0};
// 发送起始信号
GPIO_SetBits(DHT11_PORT, DHT11_PIN);
delay_ms(20);
GPIO_ResetBits(DHT11_PORT, DHT11_PIN);
delay_us(30);
GPIO_SetBits(DHT11_PORT, DHT11_PIN);
// 等待 DHT11 的响应信号
if(DHT11_Wait_Response() == 0)
return 0;
// 接收数据
for(i = 0; i < 5; i++)
{
for(j = 0; j < 8; j++)
{
while(GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN) == 0); // 等待数据线拉高
delay_us(30);
if(GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN) == 1) // 判断数据是 0 还是 1
dht11_data[i] |= (1 << (7 - j));
while(GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN) == 1); // 等待数据线拉低
}
}
// 校验数据
if(dht11_data[4] != (dht11_data[0] + dht11_data[1] + dht11_data[2] + dht11_data[3]))
return 0;
// 转换数据
*hum = (float)dht11_data[0] + (float)dht11_data[1] / 10.0;
*temp = (float)dht11_data[2] + (float)dht11_data[3] / 10.0;
return 1;
}
```
其中,DHT11_Wait_Response() 函数用于等待 DHT11 的响应信号,代码如下:
```c
uint8_t DHT11_Wait_Response(void)
{
uint8_t cnt = 0;
while(GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN))
{
cnt++;
delay_us(1);
if(cnt > 100)
return 0;
}
cnt = 0;
while(!GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN))
{
cnt++;
delay_us(1);
if(cnt > 100)
return 0;
}
cnt = 0;
while(GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN))
{
cnt++;
delay_us(1);
if(cnt > 100)
return 0;
}
return 1;
}
```
#### 3.3 OLED 显示屏数据显示
OLED 显示屏采用 I2C 接口进行数据传输。我们可以使用库函数中提供的 I2C_WriteData() 函数和 OLED_WriteCmd() 函数来进行数据的传输。具体代码如下:
```c
void OLED_Show_Data(float temp, float hum)
{
char buf[16];
// 温度数据显示
sprintf(buf, "Temp: %.1f C", temp);
OLED_WriteCmd(0xb0);
OLED_WriteCmd(0x00);
OLED_WriteCmd(0x10);
I2C_WriteData(I2C2, 0x40, (uint8_t *)buf, strlen(buf));
// 湿度数据显示
sprintf(buf, "Hum : %.1f %%", hum);
OLED_WriteCmd(0xb0);
OLED_WriteCmd(0x20);
OLED_WriteCmd(0x10);
I2C_WriteData(I2C2, 0x40, (uint8_t *)buf, strlen(buf));
}
```
#### 3.4 主函数代码
主函数代码如下:
```c
int main(void)
{
float temp = 0, hum = 0;
// 初始化系统时钟
SystemInit();
// 初始化 IO 口
DHT11_Init();
OLED_Init();
// 显示开机画面
OLED_Show_Boot();
// 主循环
while(1)
{
if(DHT11_Read_Data(&temp, &hum))
OLED_Show_Data(temp, hum);
delay_ms(2000); // 延时 2s
}
}
```
### 4. 实现效果
将程序下载到单片机上,连接好 DHT11 温湿度传感器和 OLED 显示屏,开机后,屏幕上会显示出开机画面:
![温湿度检测显示器开机画面](https://img-blog.csdnimg.cn/20211202212243806.jpg)
然后,屏幕上会显示出实时的温湿度数据:
![温湿度检测显示器实时数据](https://img-blog.csdnimg.cn/20211202212313539.jpg)
### 5. 总结
本项目介绍了如何使用单片机 STM32F103C8T6、DHT11 温湿度传感器和 OLED 显示屏实现了一个温湿度检测显示器。通过学习本项目,可以了解到数字温湿度传感器的工作原理和数据读取方法,以及 OLED 显示屏的数据显示方法。
阅读全文