STM32整合OV7725摄像头、DHT11传感器和ESP8266模块实现数据上传
一、系统架构设计

二、硬件连接配置
| 模块 | STM32引脚 | 说明 |
|---|---|---|
| OV7725 | PA0-PA7 (D0-D7) | 并行数据总线 |
| PA4 (XCLK) | 24MHz时钟输入 | |
| PA5 (PCLK) | 像素时钟输出 | |
| PA6 (HREF) | 行同步信号 | |
| PA7 (VSYNC) | 帧同步信号 | |
| DHT11 | PB0 | 单总线数据线 |
| ESP8266 | USART1_TX (PA9) | UART通信 |
| USART1_RX (PA10) | UART通信 | |
| 电源模块 | 3.3V/5V | 需独立供电(OV7725需16MHz晶振) |
三、软件实现方案
1. OV7725驱动(DMA方式)
// 初始化配置(STM32F103)
void OV7725_Init() {
// 配置DCMI接口
RCC_AHBENR |= (1<<1); // 使能DCMI时钟
DCMI_CR |= (1<<0); // 启动捕获
DCMI_CROP |= (0x01<<16); // 设置分辨率160x120
// 配置OV7725寄存器
OV7725_WriteReg(0x12, 0x80); // 软复位
OV7725_WriteReg(0x12, 0x04); // 彩色模式
OV7725_WriteReg(0x15, 0x80); // 增益控制
}
// DMA传输回调
void DMA1_Stream1_IRQHandler() {
if(DMA_GetITStatus(DMA1_Stream1, DMA_IT_TCIF1)) {
// 处理图像数据(160x120x2字节)
Process_ImageBuffer(DMA_GetCurrentDataRegister(DMA1_Stream1));
DMA_ClearITPendingBit(DMA1_Stream1, DMA_IT_TCIF1);
}
}
2. DHT11数据采集
#define DHT_PIN PB0
uint8_t DHT_ReadData(uint8_t *temp, uint8_t *humi) {
// 发送起始信号
DHT_GPIO_Out();
DHT_Low();
Delay_ms(20);
DHT_High();
// 等待响应
if(!DHT_CheckResponse()) return 1;
// 读取40位数据
*humi = DHT_ReadByte();
*temp = DHT_ReadByte();
DHT_ReadByte(); // 校验位1
DHT_ReadByte(); // 校验位2
return 0;
}
// 单总线时序控制
void DHT_GPIO_Out() {
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_Pin = DHT_PIN;
GPIO_Init(GPIOB, &GPIO_InitStruct);
}
uint8_t DHT_CheckResponse() {
DHT_GPIO_In();
Delay_us(40);
return (GPIO_ReadInputDataBit(GPIOB, DHT_PIN) == 0);
}
3. ESP8266通信协议
// MQTT数据封装
void Send_MQTT_Payload(float temp, float humi) {
char payload[128];
sprintf(payload, "{\"temperature\":%.1f,\"humidity\":%.1f}", temp, humi);
// 发送TCP数据
ESP8266_SendCmd("AT+CIPSEND=0,%d\r\n", strlen(payload)+2);
USART_SendString(payload);
}
// OneNET平台数据上传
void Upload_To_OneNET() {
char cmd[64];
sprintf(cmd, "AT+MQTTTOPIC=\"%s/temperature\",0,0,0\r\n", DEVICE_ID);
ESP8266_SendCmd(cmd);
USART_SendString((uint8_t*)temp_str);
sprintf(cmd, "AT+MQTTTOPIC=\"%s/humidity\",0,0,0\r\n", DEVICE_ID);
ESP8266_SendCmd(cmd);
USART_SendString((uint8_t*)humi_str);
}
四、上位机显示方案
1. 基于Python的GUI界面
import tkinter as tk
import serial
import json
class DataDisplay:
def __init__(self):
self.root = tk.Tk()
self.root.title("环境监测系统")
# 创建画布
self.canvas = tk.Canvas(self.root, width=640, height=480)
self.canvas.pack()
# 串口配置
self.ser = serial.Serial('COM3', 115200)
# 启动数据接收
self.update_data()
def update_data(self):
if self.ser.in_waiting:
data = self.ser.read_until(b'\r\n')
if data.startswith(b'IMG:'):
# 处理图像数据
img_data = data[4:-2]
self.display_image(img_data)
elif data.startswith(b'DATA:'):
# 解析温湿度
json_data = json.loads(data[5:])
self.update_labels(json_data)
self.root.after(100, self.update_data)
def display_image(self, img_data):
# 将二进制数据转换为图像
image = Image.open(io.BytesIO(img_data))
self.photo = ImageTk.PhotoImage(image)
self.canvas.create_image(0,0,image=self.photo)
def update_labels(self, data):
self.temp_label.config(text=f"温度: {data['temperature']}°C")
self.humi_label.config(text=f"湿度: {data['humidity']}%")
if __name__ == "__main__":
app = DataDisplay()
app.root.mainloop()
五、调试与验证
-
硬件调试要点 使用示波器验证DCMI时序(HREF与PCLK相位关系) 检查ESP8266的AT响应时间(应<500ms) 验证DHT11数据校验位(前4字节和校验)
-
软件调试技巧
-
使用逻辑分析仪捕获I2C配置过程
-
添加调试打印:
#define DEBUG_PRINT(...) printf(__VA_ARGS__); USART_SendString(__VA_ARGS__)
-
-
典型问题解决方案
问题现象 解决方法 图像雪花噪点 检查XCLK频率(需24MHz±5%) WiFi连接超时 增加AT+CWJAP重试机制 数据包丢失 启用UDP协议替代TCP
参考代码 STM32+OV7725+DHT11+ESP8266将温度和图片数据上传到上位机显示 www.youwenfan.com/contentcnl/73296.html
六、扩展功能建议
-
多节点组网
-
使用ESP8266的AP+STA模式实现设备组网
-
示例配置:
AT+CWMODE=3 AT+CWSAP="CAM1","123456",5,4 AT+CWJAP="ROUTER","WIFI_PWD"
-
-
本地存储
-
添加SPI Flash存储最近24小时数据
-
使用FatFs文件系统:
f_open(&file, "log.txt", FA_WRITE|FA_CREATE_ALWAYS); f_write(&file, buffer, size, &bytes_written);
-
-
安全加密
-
启用TLS加密传输
-
使用mbedTLS库实现:
mbedtls_ssl_config conf; mbedtls_ssl_setup(&ssl, &conf); mbedtls_ssl_set_bio(&ssl, &tcp_sock, send_cb, recv_cb, NULL);
-

浙公网安备 33010602011771号