基于STM32的温湿度监测系统:最小系统板上的实时追踪

您所在的位置:网站首页 最小系统程序 基于STM32的温湿度监测系统:最小系统板上的实时追踪

基于STM32的温湿度监测系统:最小系统板上的实时追踪

#基于STM32的温湿度监测系统:最小系统板上的实时追踪| 来源: 网络整理| 查看: 265

目录 功能概述 所用硬件 演示效果 程序部分 DHT11温湿度的获取 DS18B20温度的获取 ESP8266的使用 Socket服务器的创建 主函数部分 调试及下载 功能概述

基于STM32F103C8T6最小系统板制作的温湿度监测系统,监测温度和湿度并通过WIFI模块将监测的数据传输到电脑上的Socket服务器端。

所用硬件

STM32F103C8T6最小系统板、DHT11温湿度传感器、DS18B20温度传感器、ESP8266-01SWIFI模块。

注:传感器可只用DHT11,DS18B20可有可无。

演示效果

实物图:

服务器测试图:

程序部分 DHT11温湿度的获取

关于DHT11温湿度传感器的使用,网上有很多详细的资料,这里只进行简单的说明。

这是DHT11的通讯过程,我们需要通过引脚先将DHT11置于低电平至少18ms,再置高电平20-40us。然后DHT11会先返回80us的低电平信号,再返回一个80us的高电平信号,之后开始传送数据。

代码部分

dht11.h

#ifndef __DHT11_H #define __DHT11_H #include "stm32f10x.h" void DHT11_GPIO_OUT(void); void DHT11_GPIO_IN(void); uint8_t DHT_Read_Byte(void); uint8_t DHT_Read(void); #endif

dht11.c

#include "Delay.h" #include "dht11.h" uint8_t dat[5]={0x00,0x00,0x00,0x00,0x00}; uint8_t sum = 0; /* *初始化输出 */ void DHT11_GPIO_OUT(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); } /* *初始化输入 */ void DHT11_GPIO_IN(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOB, &GPIO_InitStructure); } /* *读取一个字节 */ uint8_t DHT_Read_Byte(void) { uint8_t temp; uint8_t ReadDat = 0; uint8_t retry = 0; uint8_t i; for(i=0; i Delay_us(1); retry++; } retry = 0; Delay_us(30); temp = 0; //再接收高电平信号16us-28us(代表数据0)或高电平信号70us(代表数据1) if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14)==1) temp=1; while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14) == 1 && retry uint8_t i; uint8_t retry = 0; //总线设置为输出并拉低18ms DHT11_GPIO_OUT(); GPIO_ResetBits(GPIOB, GPIO_Pin_14); Delay_ms(18); //总线再拉高40ms GPIO_SetBits(GPIOB, GPIO_Pin_14); Delay_us(40); //总线设置为输入 DHT11_GPIO_IN(); Delay_us(20); //等待响应信号为低电平 if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14) == 0) { //等待响应信号为高电平,超时等待100us while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14)==0&&retry Delay_us(1); retry++; } retry=0; //循环读取数据,dat[0]为湿度整数数据,dat[1]为湿度小数数据,dat[2]为温度整数数据,dat[3]为温度小数数据,dat[4]为校验和数据 for(i=0;i return 1; } else return 0; } DS18B20温度的获取

没有使用DS18B20可跳过这部分 关于DS18B20的初始化时序图以及读写时序图网上有很多详细的资料,这里不再赘述,直接上代码。

ds18b20.h

#ifndef __DS18B20_H #define __DS18B20_H #include "stm32f10x.h" #include "stdio.h" void DS18B20_GPIO_OUT(void); void DS18B20_GPIO_IN(void); void DS18B20_RST(void); int DS18B20_Check(void); uint8_t DS18B20_Read_Bit(void); void DS18B20_Write_One(void); void DS18B20_Write_Zero(void); uint8_t DS18B20_Read_Byte(void); void DS18B20_Write_Byte(uint8_t data); void DS18B20_Start(void); float DS18B20_Get_Temp(void); #endif

ds18b20.c

#include "ds18b20.h" #include "Delay.h" /* *初始化输出 */ void DS18B20_GPIO_OUT(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); } /* *初始化输入 */ void DS18B20_GPIO_IN(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOB, &GPIO_InitStructure); } /* *复位ds18b20 */ void DS18B20_RST(void) { DS18B20_GPIO_OUT(); GPIO_ResetBits(GPIOB, GPIO_Pin_13); Delay_us(750); GPIO_SetBits(GPIOB, GPIO_Pin_13); Delay_us(15); } /* *检测ds18b20的存在 */ int DS18B20_Check(void) { uint8_t retry = 0; DS18B20_GPIO_IN(); while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_13) == 1 && retry retry++; Delay_us(1); } if(retry>=240) return 1; return 0; } /* *读取一位数据 */ uint8_t DS18B20_Read_Bit(void) { uint8_t data; DS18B20_GPIO_OUT(); GPIO_ResetBits(GPIOB, GPIO_Pin_13); Delay_us(2); GPIO_SetBits(GPIOB, GPIO_Pin_13); DS18B20_GPIO_IN(); Delay_us(10); if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_13) == 1) data = 1; else data =0; Delay_us(50); return data; } /* *进行写数据1操作 */ void DS18B20_Write_One(void) { DS18B20_GPIO_OUT(); GPIO_ResetBits(GPIOB, GPIO_Pin_13); Delay_us(2); GPIO_SetBits(GPIOB, GPIO_Pin_13); Delay_us(60); } /* *进行写数据0操作 */ void DS18B20_Write_Zero(void) { DS18B20_GPIO_OUT(); GPIO_ResetBits(GPIOB, GPIO_Pin_13); Delay_us(60); GPIO_SetBits(GPIOB, GPIO_Pin_13); Delay_us(2); } /* *读取一个字节 */ uint8_t DS18B20_Read_Byte(void) { uint8_t data = 0; for(uint8_t i=0;i data |=0x80; } } return data; } /* *写入一个字节 */ void DS18B20_Write_Byte(uint8_t data) { DS18B20_GPIO_OUT(); for(int i =1;i DS18B20_RST(); DS18B20_Check(); DS18B20_Write_Byte(0xcc); DS18B20_Write_Byte(0x44); } /* *温度获取 */ float DS18B20_Get_Temp(void) { float data; uint8_t TH,TL; uint16_t TB; DS18B20_Start(); DS18B20_RST(); DS18B20_Check(); DS18B20_Write_Byte(0xCC); DS18B20_Write_Byte(0xBE); TL = DS18B20_Read_Byte(); TH = DS18B20_Read_Byte(); TB = TH; TB //设置工作模式为STA模式 printf("AT+CWMODE=1\r\n"); //延时500ms指令有足够时间操作 Delay_ms(500); //设置esp8266要连接的wifi信息 printf("AT+CWJAP=\"WIFI名称\",\"WIFI密码\"\r\n"); Delay_ms(3000); //设置连接的服务端的信息,这里的ip地址和端口号与后面socket服务端使用的ip地址和端口号是一致的 printf("AT+CIPSTART=\"TCP\",\"ip地址例如192.168.1.9\",端口号例如8080\r\n"); Delay_ms(3000); } /* *发送温度湿度信息 *hum是dht11发送的,temp是ds18b20发送的 */ void ESP_SendMeassage(u8 hum, float tem) { //进入透传模式 printf("AT+CIPMODE=1\r\n"); Delay_ms(500); //开始发送数据 printf("AT+CIPSEND\r\n"); Delay_ms(500); printf("湿度:%d%%,温度:%f度\r\n",hum, tem); //退出发送数据 printf("+++"); Delay_ms(100); //退出透传模式 printf("AT+CIPMODE=0\r\n"); Delay_ms(100); } Socket服务器的创建

关于套机字通信可以看看这个作者写的: 套接字编程.

先来看看这里的socket通信过程

与一般的socket编程不同的地方在于,我们的服务器端只需要接收数据,不需要向客户端发送数据,同时我们只需要进行服务器端的socket编程,无需写客户端部分的代码,只需交给esp8266来完成即可。

服务端代码 注意这部分是单独在vs中进行编程的,并不在项目工程当中。

server.cpp

#include #include #include using namespace std; int main() { //服务器ip地址,端口号 const char* host = "192.168.1.9"; unsigned int port = 8080; WSADATA wsaData; int len; int recv_len; SOCKET sock_server, sock_client; SOCKADDR_IN server_addr, client_addr; server_addr.sin_family = AF_INET; inet_pton(AF_INET, host, &server_addr.sin_addr); server_addr.sin_port = htons(port); //初始化套接字 WORD w_req = MAKEWORD(2, 2); if (WSAStartup(w_req, &wsaData) != 0) { WSACleanup(); cout cout //data用于读取ds18b20的数据 float data; //初始化串口,波特率设置为115200 USART_Init_Config(115200); //初始化esp8266 ESP_Init(); //进行温湿度的读取 while(1) { //当DHT11得到数据时 if(DHT_Read()) { //ds18b20也读取一次数据 data = DS18B20_Get_Temp(); ESP_SendMeassage(dat[0], data); /* 若不使用ds18b20,则使用这段代码,将ESP_SendMeassge()注释掉。 printf("湿度:%d%%,温度:%d度\r\n",dat[0],dat[2]); */ Delay_ms(3000); } } } 调试及下载

将程序烧录到stm32中,串口PA9和PA10与esp8266的RX和TX连接,PB14与dht11数据端连接,PB13与ds18b20数据端连接,将其余的VCC和GND接好。电脑上先运行socket服务端,再将stm32上电,等待数据发送至服务端。

有需要可自行下载: 项目链接。

您可能感兴趣的内容: 基于STM32的全面智能农业系统:上位机与下位机完美结合 基于STM32的智能家居系统设计:构建一个聪明的家 STM32F103系列:使用Proteus仿真实现4*4矩阵键盘与LCD1602显示的连接 测量数据STM32与DHT11温湿度传感器交互:测量数据实时可视化 C++常见容器一网打尽


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3