STM32+ESP8266+QT客户端上位机显示DHT11温湿度与点灯
目录
1、简介
2、硬件连接
3、上位机源码
3.1 widget.h
3.2 widget.c
3.3 显示图
4、下位机源码
4.1 cubemax配置
4.2 keil源码
1、简介
本文使用STM32F103C8T6单片机使用单片机通过ESP8266WIFI模块与QT设计的上位机进行通讯,ESP8266设置AP模式。实现DHT11传感器温湿度的显示与远程控制LED小灯的亮灭。
2、硬件连接
PB9---DHT11(5V)
PA9----RX
PA10---TX
ESP8266(3.3V)
PB0----LED(高电平有效)
3、上位机源码
3.1 widget.h
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QWidget>
#include <QTcpServer>
#include <QTcpSocket>
namespace Ui {
class Widget;
}
#pragma pack(1)
struct QT_info
{unsigned char Head[2];uint8_t DHT11_BUF[2];//用于存放DHT11数据
};
#pragma pack()
class Widget : public QWidget
{Q_OBJECTpublic:explicit Widget(QWidget *parent = nullptr);~Widget();//QTcpServer *tcpserver;//声明一个QTcpserver的对象,用于监听QTcpSocket *tcpsocket;//创建服务器的套接字,用于与客户端进行通信private slots:void on_open_Button_clicked();void on_close_Button_clicked();void on_send_Button_clicked();void connected_Slot();void readyRead_Slot();void on_pushButton_clicked();private:Ui::Widget *ui;
};#endif // WIDGET_H
3.2 widget.c
#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
{ui->setupUi(this);//tcpserver = new QTcpServer(this);tcpsocket = new QTcpSocket(this);
}Widget::~Widget()
{delete ui;
}//client端的连接服务器按钮
void Widget::on_open_Button_clicked()
{// 根据输入的ip和port连接指定的服务器
// tcpsocket->connectToHost(ui->IP_line->text(),ui->port_line->text().toUShort());tcpsocket->connectToHost("192.168.4.1",333);connect(tcpsocket,SIGNAL(connected()),this,SLOT(connected_Slot()));if(tcpsocket->waitForConnected(1000) == true){tcpsocket->write("Q");}}void Widget::connected_Slot()
{connect(tcpsocket,SIGNAL(readyRead()),this,SLOT(readyRead_Slot()));
}void Widget::readyRead_Slot()
{QByteArray mytemp = tcpsocket->readAll();//ui->rece_TextEdit->appendPlainText(tcpsocket->readAll());if(!mytemp.isEmpty()){ui->rece_T_Edit->clear();ui->rece_S_Edit->clear();struct QT_info* info_RX = (struct QT_info*)mytemp.data(); // unsigned char *if(info_RX->Head[0]==0x55 && info_RX->Head[1]==0xFF) {QString T = QString::asprintf("%.2d",info_RX->DHT11_BUF[1]);QString S = QString::asprintf("%2d",info_RX->DHT11_BUF[0]);ui->rece_T_Edit->insertPlainText(T);ui->rece_S_Edit->insertPlainText(S);}mytemp.clear();}
}void Widget::on_close_Button_clicked()
{tcpsocket->write("B");tcpsocket->close();ui->rece_T_Edit->clear();ui->rece_S_Edit->clear();} void Widget::on_send_Button_clicked()
{
// tcpsocket->write(ui->send_line->text().toLocal8Bit().data());tcpsocket->write("Q");
}void Widget::on_pushButton_clicked()
{tcpsocket->write("B");
}
3.3 显示图
4、下位机源码
4.1 cubemax配置
GPIO配置。
串口配置,中断打开。
4.2 keil部分源码
func
#include "func.h"struct QT_info QT_info_TX;
extern char buf;
uint16_t len;void CSH(void)
{len = sizeof(QT_info_TX);DHT11_Init();//传感器芯片初始化DHT11_ReadData(QT_info_TX.DHT11_BUF);//读出DHT11传感器数据(参数是存放数据的数组指针)HAL_Delay(200);//1 工作在路由模式printf("AT+CWMODE=2\\r\\n");HAL_Delay(200);//2 使能多链接printf("AT+CIPMUX=1\\r\\n");HAL_Delay(200);//3 建立TCPServer port = 333printf("AT+CIPSERVER=1\\r\\n");HAL_Delay(200);LED_OFF;QT_info_TX.Head[0]=0x55;QT_info_TX.Head[1]=0xFF;}
void oled_ui(void)
{ DHT11_ReadData(QT_info_TX.DHT11_BUF);//读出DHT11传感器数据(参数是存放数据的数组指针)HAL_Delay(100);HAL_UART_Receive_IT(&huart1, (uint8_t *)&buf, 1); //发送数据printf("AT+CIPSEND=0,%d\\r\\n",len);HAL_Delay(200);HAL_UART_Transmit(&huart1,(uint8_t *)&QT_info_TX,sizeof(QT_info_TX),10);
}
#include "main.h"
#include "dht11.h"
#include "usart.h"
#include "string.h"void CSH(void);
void alarm(void);
void oled_ui(void);
void Qt_UART_RxCallBack(unsigned char *Data,unsigned int Len);__packed struct QT_info
{unsigned char Head[2];uint8_t DHT11_BUF[2];//用于存放DHT11数据};
main
/* USER CODE BEGIN Header */
/* @file : main.c* @brief : Main program body* @attention Copyright (c) 2023 STMicroelectronics.* All rights reserved. This software is licensed under terms that can be found in the LICENSE file* in the root directory of this software component.* If no LICENSE file comes with this software, it is provided AS-IS./
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "i2c.h"
#include "usart.h"
#include "gpio.h"/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stdio.h"
char buf;
#include "func.h"
/* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)//涓插彛涓柇鍥炶皟鍑芥暟
{if(huart1.Instance == USART1){if(buf == 'Q'){LED_ON;HAL_UART_Receive_IT(&huart1, (uint8_t *)&buf, 1);}else if(buf == 'B'){LED_OFF;HAL_UART_Receive_IT(&huart1, (uint8_t *)&buf, 1);}HAL_UART_Receive_IT(&huart1, (uint8_t *)&buf, 1);}
}/* USER CODE END PTD *//* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD *//* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*//* USER CODE BEGIN PV *//* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP *//* USER CODE END PFP *//* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 *//* USER CODE END 0 *//* @brief The application entry point.* @retval int*/
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_USART1_UART_Init();MX_I2C1_Init();MX_USART2_UART_Init();/* USER CODE BEGIN 2 */CSH();/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){ oled_ui();// printf("1\\r\\n");/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}/* @brief System Clock Configuration* @retval None*/
void SystemClock_Config(void)
{RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};/ Initializes the RCC Oscillators according to the specified parameters* in the RCC_OscInitTypeDef structure.*/RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;RCC_OscInitStruct.HSIState = RCC_HSI_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/ Initializes the CPU, AHB and APB buses clocks*/RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK){Error_Handler();}
}/* USER CODE BEGIN 4 *//* USER CODE END 4 *//* @brief This function is executed in case of error occurrence.* @retval None*/
void Error_Handler(void)
{/* USER CODE BEGIN Error_Handler_Debug *//* User can add his own implementation to report the HAL error return state */__disable_irq();while (1){}/* USER CODE END Error_Handler_Debug */
}#ifdef USE_FULL_ASSERT
/* @brief Reports the name of the source file and the source line number* where the assert_param error has occurred.* @param file: pointer to the source file name* @param line: assert_param error line source number* @retval None*/
void assert_failed(uint8_t *file, uint32_t line)
{/* USER CODE BEGIN 6 *//* User can add his own implementation to report the file name and line number,ex: printf("Wrong parameters value: file %s on line %d\\r\\n", file, line) *//* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
dht11
/ dht11.c Created on: Oct 21, 2021* Author: Administrator*//*
//杜洋工作室出品
//洋桃系列开发板应用程序
//关注微信公众号:洋桃电子
//洋桃开发板资料下载 www.DoYoung.net/YT
//即可免费看所有教学视频,下载技术资料,技术疑难提问
//更多内容尽在 杜洋工作室主页 www.doyoung.net
*//*
《修改日志》
1-201708202309 创建。*/#include "dht11.h"
#include "main.h"void DHT11_IO_OUT (void){ //端口变为输出GPIO_InitTypeDef GPIO_InitStruct = {0};GPIO_InitStruct.Pin = DHT11_DA_Pin;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}void DHT11_IO_IN (void){ //端口变为输入GPIO_InitTypeDef GPIO_InitStruct = {0};GPIO_InitStruct.Pin = DHT11_DA_Pin;GPIO_InitStruct.Mode = GPIO_MODE_INPUT;GPIO_InitStruct.Pull = GPIO_PULLUP;HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}void DHT11_RST (void){ //DHT11端口复位,发出起始信号(IO发送)DHT11_IO_OUT();HAL_GPIO_WritePin(GPIOB,DHT11_DA_Pin, GPIO_PIN_RESET);HAL_Delay(20); //拉低至少18msHAL_GPIO_WritePin(GPIOB,DHT11_DA_Pin, GPIO_PIN_SET);delay_us(30); //主机拉高20~40us
}uint8_t Dht11_Check(void){ //等待DHT11回应,返回1:未检测到DHT11,返回0:成功(IO接收)uint8_t retry=0;DHT11_IO_IN();//IO到输入状态while (HAL_GPIO_ReadPin(GPIOB,DHT11_DA_Pin)&&retry<100){//DHT11会拉低40~80usretry++;delay_us(1);}if(retry>=100)return 1; else retry=0;while (!HAL_GPIO_ReadPin(GPIOB,DHT11_DA_Pin)&&retry<100){//DHT11拉低后会再次拉高40~80usretry++;delay_us(1);}if(retry>=100)return 1;return 0;
}uint8_t Dht11_ReadBit(void){ //从DHT11读取一个位 返回值:1/0uint8_t retry=0;while(HAL_GPIO_ReadPin(GPIOB,DHT11_DA_Pin)&&retry<100){//等待变为低电平retry++;delay_us(1);}retry=0;while(!HAL_GPIO_ReadPin(GPIOB,DHT11_DA_Pin)&&retry<100){//等待变高电平retry++;delay_us(1);}delay_us(40);//等待40us //用于判断高低电平,即数据1或0if(HAL_GPIO_ReadPin(GPIOB,DHT11_DA_Pin))return 1; else return 0;
}uint8_t Dht11_ReadByte(void){ //从DHT11读取一个字节 返回值:读到的数据uint8_t i,dat;dat=0;for (i=0;i<8;i++){dat<<=1;dat|=Dht11_ReadBit();}return dat;
}uint8_t DHT11_Init (void){ //DHT11初始化DHT11_RST();//DHT11端口复位,发出起始信号return Dht11_Check(); //等待DHT11回应
}uint8_t DHT11_ReadData(uint8_t *h){ //读取一次数据//湿度值(十进制,范围:20%~90%) ,温度值(十进制,范围:0~50°),返回值:0,正常;1,失败uint8_t buf[5];uint8_t i;DHT11_RST();//DHT11端口复位,发出起始信号if(Dht11_Check()==0){ //等待DHT11回应for(i=0;i<5;i++){//读取5位数据buf[i]=Dht11_ReadByte(); //读出数据}if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4]){ //数据校验*h=buf[0]; //将湿度值放入指针1h++;*h=buf[2]; //将温度值放入指针2}}else return 1;return 0;
}//===============================================us延时函数
void delay_us(uint32_t us)//主频72M
{uint32_t delay = (HAL_RCC_GetHCLKFreq() / 4000000 * us);while (delay--){;}
}
/ 杜洋工作室 www.DoYoung.net* 洋桃电子 www.DoYoung.net/YT
*/
#ifndef __DHT11_H
#define __DHT11_H#include "stm32f1xx_hal.h"void DHT11_IO_OUT (void);
void DHT11_IO_IN (void);
void DHT11_RST (void);
uint8_t Dht11_Check(void);
uint8_t Dht11_ReadBit(void);
uint8_t Dht11_ReadByte(void);
uint8_t DHT11_Init (void);
uint8_t DHT11_ReadData(uint8_t *h);
void delay_us(uint32_t us);
#endif