温湿度LCD显示并上传服务器

项目需求

通过温湿度传感器将值传到LCD1602,并实时通过蓝牙透传到手机。

硬件介绍

温湿度传感器 DHT11温湿度传感器 DHT11_温湿度传感器数据格式-CSDN博客

LCD1602LCD1602-CSDN博客

HC-01

继电器模块

硬件接线

LCD1602
  • D0~D7 --> A0~A7
  • VDD, A --> 5v
  • VSS, VO, K --> GND
  • RS --> B1
  • RW --> B2
  • E --> B10
DHT11
  • VCC --> 5v
  • GND --> GND
  • DATA --> B7
HC-01(也可不接,和电脑串口显示一样的,透传模式)
  • VCC --> 5v
  • GND --> GND
  • RXD --> TX1
  • TXD --> RX1

 各个硬件在先前学习了,就不再一一讲述,此项目仅做代码的移植

 CubeMX

1.常规配置

SYS->Debug->Serial Wire

RCC->High Speed Clock(HSE)->Crystal/Ceramic Resonator

时钟树HSE、PLLCLK打开,HCLK设置成72MHz

打开GPIO口

打开uart1

框内的是在CubeMx重定义的引脚名称,会在mian.h中显示

其中,DHT11的DATA线既作为输入也作为输出,因此不能在CubeMX中进行配置!

为了方便阅读与编写,可在main.h文件重定义引脚

2.时钟

由于hal_delay()只是ms级别的延时,而DHT11中需要us的延时,则需要重新写延时函数,这里我们可以使用软件延时或者硬件延时

软件延时 
void delay_us(uint16_t cnt)
{uint8_t i;while(cnt){for (i = 0; i < 10; i++){}cnt--;}
}
硬件延时:打开定时器

计数一次经过的时间是 (PSC + 1) / Tclk , 因此如果我想要计数1微秒,即0.000001s, 已知Tclk = 72 000 000, 那么PSC就应该设置为 71。然后在main.c中就可以定义出一个实现微秒级延时的函数: 

STM32的HAL库开发各函数意义、笔记_hal_tim_set_counter-CSDN博客

void TIM1_Delay_us(uint16_t n_us) //使用TIM1来做us级延时函数  一个基于STM32 HAL库的TIM1(定时器1)进行微秒级延时的功能。
{
/* 使能定时器1计数 */__HAL_TIM_ENABLE(&htim1);__HAL_TIM_SetCounter(&htim1, 0);while(__HAL_TIM_GetCounter(&htim1) < ((1 * n_us)-1) );
/* 关闭定时器1计数 */__HAL_TIM_DISABLE(&htim1);
}

 3.生成代码

keil

1. 打开MICRO-LIB

2. 编写代码:

 关于上面提到的DHT的DATA引脚,由于有时需要作为输入,有时需要输出,所以不能在Cube中进行定义,而是在Keil中自己写代码定义,可以直接参考main函数中main.c的MX_GPIO_Init()函数,经过跳转可以看到详细信息:

如图,需要:

  • 定义一个结构体
  • 使能时钟
  • 赋初值(这步可省略)
  • 对于结构体的成员变量进行赋值,分别是GPIO_InitStruct.Pin; GPIO_InitStruct.Mode; 
  • GPIO_InitStruct.Speed,其中GPIO_InitStruct.Mode就是需要根据情况修改的
  • 调用HAL_GPIO_Init 函数
    void DHT11_Init(uint32_t Mode)
    {GPIO_InitTypeDef GPIO_InitStruct = {0};__HAL_RCC_GPIOB_CLK_ENABLE();GPIO_InitStruct.Pin = GPIO_PIN_7;GPIO_InitStruct.Mode = Mode;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);}

    然后,

    就可以在需要往DATA写数据的时候写:DHT_GPIO_Init(GPIO_MODE_OUTPUT_PP);

    在需要从DATA读数据的时候写:DHT_GPIO_Init(GPIO_MODE_INPUT);

并且,由于89C52和STM32的硬件差别,使用STM32来驱动LCD1602时,是不需要检测BUSY信号的!!!

但是32驱动LCD的时候,在写命令或内容时,需要用到us级的延时,故要重新编写延时函数

 分文件编写,要将相应的.c.h文件分别添加到incsrc文件中,在新添加的文件在CubeMx重新更改的配置重新生成的文件并不会消失。

main.h

#define RS_GPIO_Pin GPIO_PIN_1
#define RS_GPIO_GPIO_Port GPIOB
#define RW_GPIO_Pin GPIO_PIN_2
#define RW_GPIO_GPIO_Port GPIOB
#define EN_GPIO_Pin GPIO_PIN_10
#define EN_GPIO_GPIO_Port GPIOB/* USER CODE BEGIN Private defines */
#define DHT_11_GPIO GPIOB
#define DHT_11_PIN GPIO_PIN_7#define DHT_11_LOW  HAL_GPIO_WritePin(DHT_11_GPIO,DHT_11_PIN,GPIO_PIN_RESET)
#define DHT_11_HIGH HAL_GPIO_WritePin(DHT_11_GPIO,DHT_11_PIN,GPIO_PIN_SET)
#define DHT_11_VALUE HAL_GPIO_ReadPin(DHT_11_GPIO,DHT_11_PIN)#define RS_HIGH HAL_GPIO_WritePin(RS_GPIO_GPIO_Port,RS_GPIO_Pin,GPIO_PIN_SET)
#define RS_LOW  HAL_GPIO_WritePin(RS_GPIO_GPIO_Port,RS_GPIO_Pin,GPIO_PIN_RESET)
#define RW_HIGH HAL_GPIO_WritePin(RW_GPIO_GPIO_Port,RW_GPIO_Pin,GPIO_PIN_SET)
#define RW_LOW  HAL_GPIO_WritePin(RW_GPIO_GPIO_Port,RW_GPIO_Pin,GPIO_PIN_RESET)
#define EN_HIGH HAL_GPIO_WritePin(EN_GPIO_GPIO_Port,EN_GPIO_Pin,GPIO_PIN_SET)
#define EN_LOW  HAL_GPIO_WritePin(EN_GPIO_GPIO_Port,EN_GPIO_Pin,GPIO_PIN_RESET)

main.c

#include "stdio.h"
#include "lcd1602.h"
#include "dht11.h"extern char datas[5];
char temperature[9];
char humidity[9];void Build_datas()
{humidity[0] = 'H';humidity[1] = ':';humidity[2] = datas[0]/10 + 0x30;humidity[3] = datas[0]%10 + 0x30;humidity[4] = '.';humidity[5] = datas[1]/10 + 0x30;humidity[6] = datas[1]%10 + 0x30;humidity[7] = '%';humidity[8] = '\0';temperature[0] = 'T';temperature[1] = ':';temperature[2] = datas[2]/10 + 0x30;temperature[3] = datas[2]%10 + 0x30;temperature[4] = '.';temperature[5] = datas[3]/10 + 0x30;temperature[6] = datas[3]%10 + 0x30;temperature[7] = 'C';temperature[8] = '\0';
}int fputc(int a, FILE *f) //一个字符一个字符发送
{unsigned char temp[1] = {a};HAL_UART_Transmit(&huart1, temp, 1, 0xffff);return a;
}printf("code hhh\r\n");LCD1602_Init();LCD1602_ShowLine(1,5,"shion");LCD1602_ShowLine(2,5,"114514");HAL_Delay(2000);while (1){Read_data_From_DHT();printf("Temp ; %d,%d\t",datas[2],datas[3]);printf("Humi ; %d,%d\r\n",datas[0],datas[1]);Build_datas();printf("%s\t",humidity);printf("%s",temperature);LCD1602_ShowLine(1,2,humidity);LCD1602_ShowLine(2,2,temperature);HAL_Delay(1000);}}

 LCD1602.h

#ifndef __LCD1602_H
#define __LCD1602_Hvoid Write_cmd_Func(char cmd);//写入指令的函数void Write_data_Func(char dataShow);//写入数据的函数void LCD1602_Init(void);void LCD1602_ShowLine(char row,char col,char *string);#endif

LCD1602.c

#include "lcd1602.h"
#include "gpio.h"
#include "main.h"void Write_cmd_Func(char cmd)//写入指令的函数
{RS_LOW;//写指令RW_LOW;EN_LOW;HAL_Delay(5);GPIOA->ODR = cmd;EN_HIGH;HAL_Delay(5);EN_LOW;
}void Write_data_Func(char dataShow)//写入数据的函数
{RS_HIGH;//写内容RW_LOW;EN_LOW;HAL_Delay(5);GPIOA->ODR = dataShow;EN_HIGH;HAL_Delay(5);EN_LOW;
}void LCD1602_Init(void)
{//(1)延时 15msHAL_Delay(15);//(2)写指令 38H(不检测忙信号)Write_cmd_Func(0x38);//(3)延时 5msHAL_Delay(5);//(4)以后每次写指令,读/写数据操作均需要检测忙信号//(5)写指令 38H:显示模式设置Write_cmd_Func(0x38);//(6)写指令 08H:显示关闭Write_cmd_Func(0x08);//(7)写指令 01H:显示清屏Write_cmd_Func(0x01);//(8)写指令 06H:显示光标移动设置Write_cmd_Func(0x06);//(9)写指令 0CH:显示开及光标设置Write_cmd_Func(0x0C);}void LCD1602_ShowLine(char row,char col,char *string)
{switch(row){case 1:Write_cmd_Func(0x80+col);//只要定下开始的位置,之后光标会自行移动while(*string){Write_data_Func(*string);string++;}break;case 2:Write_cmd_Func(0x80+0x40+col);//只要定下开始的位置,之后光标会自行移动while(*string){Write_data_Func(*string);string++;}break;	}/*char pos;if(hang == 0){//如果第一行pos = 0x80 + 0x00 + lie; }else if(hang == 1){//如果第二行pos = 0x80 + 0x40 + lie;}Check_Busy();Write_data_Func(*string);while(*string != '\0'){Check_Busy();Write_data_Func(*string);string++;}*/
}

 DHT11.h

#ifndef __DHT11_H
#define __DHT11_Hvoid Read_data_From_DHT();#endif

 dht11.c

#include "dht11.h"
#include "gpio.h"
#include "main.h"uint8_t datas[5];void delay_us(uint16_t cnt)
{uint8_t i;while(cnt){for (i = 0; i < 10; i++){}cnt--;}
}void DHT11_Init(uint32_t Mode)
{GPIO_InitTypeDef GPIO_InitStruct = {0};__HAL_RCC_GPIOB_CLK_ENABLE();GPIO_InitStruct.Pin = GPIO_PIN_7;GPIO_InitStruct.Mode = Mode;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);}void DHT_Start()
{DHT11_Init(GPIO_MODE_OUTPUT_PP);//设置为输出模式!!DHT_11_HIGH;DHT_11_LOW;HAL_Delay(30);DHT_11_HIGH;DHT11_Init(GPIO_MODE_INPUT);//设置为输入模式!!while(DHT_11_VALUE == 1);//不断读取直到DHT再次变低,跳出循环,说明模块响应while(DHT_11_VALUE == 0);//不断读取直到DHT再次拉高,80us之后,再经过50us后DHT变成低电平,就代表要开始变高并开始传输数据了while(DHT_11_VALUE == 1);//等待数据传输,不断读取直到DHT再次变低,如退出循环说明数据传输前的50us低电平开始了}void Read_data_From_DHT()
{int i;//轮int j;//每一轮读多少次char temp;char flag;DHT_Start();for(i = 0;i < 5;  i++){//5组数据for(j =0;j<8;j++){//每组数据8位while(!DHT_11_VALUE);//等待上拉  dht = 1 退出循环delay_us(40);//高电平持续26-28us是‘0’,高电平持续70us是'1',所以delay40us之后观察还是否是高电平if(DHT_11_VALUE == 1){flag = 1;while(DHT_11_VALUE);//不断读取下拉的一瞬间,因为在开始传输数据之前要延迟80us,如果提前结束,下一次开始传输数据就会出错,因为“开始传输数据”是从判断上拉开始的}else{flag = 0;}temp =  temp << 1;//temp左移一位,例如temp= 10101011  左移之后变成-》01010110(第一个数移出去,最后一位补零)temp |= flag;//假如flag=1,temp=01010111}datas[i] = temp;}}

 效果显示

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/1318.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

STM32H750外设ADC之双重 ADC 模式

目录 概述 1 双重 ADC 模式介绍 1.1 双重 ADC模式 1.2 双重 ADC 模式的类型 2 双重 ADC 模式寄存器的配置 3 模式功能实现 3.1 注入同步模式 3.2 支持独立注入的常规同步模式 3.2.1 中断的方式 3.2.2 DMA 读取常规数据 3.3 支持独立注入的交替模式 3.3.1 中断触发…

色彩的魔力:渐变色在设计中的无限可能性

夕阳&#xff0c;天空&#xff0c;湖面&#xff0c;夕阳...随着距离和光影的变化&#xff0c;颜色的渐变色&#xff0c;近大远小、近实远虚的透视&#xff0c;为大自然营造了浪漫的氛围。延伸到UI/UX设计领域&#xff0c;这种现实、惊艳、独特的渐变色也深受众多设计师的喜爱。…

setmapAVL树红黑树

目录 关联式容器树形结构的关联式容器setset的模板参数列表set的构造函数set的迭代器set的容量操作set其他操作 multisetmap键值对map的模板参数列表map的迭代器map中元素的修改map的容量与元素访问 multimap底层结构avl树avl树概念AVL树结点的定义AVL树的插入AVL树的旋转AVL树…

python-flask结合bootstrap实现网页小工具实例-半小时速通版

参考&#xff1a; Python之flask结合Bootstrap框架快速搭建Web应用_支持bootstrap的python软件-CSDN博客 https://blog.csdn.net/lovedingd/article/details/106696832 Bootstrap 警告框 | 菜鸟教程 https://www.runoob.com/bootstrap/bootstrap-alert-plugin.html flask框架…

数据结构——7.3 树形查找

7.3 树形查找 概念 二叉排序树&#xff08;BST&#xff09; 二叉排序树&#xff08;Binary Sort Tree&#xff0c;BST&#xff09;&#xff0c;又称为二叉查找&#xff08;搜索&#xff09;树&#xff08;Binary Search Tree&#xff09;&#xff0c;是一种特殊的二叉树&am…

力扣---从前序与中序遍历序列构造二叉树

给定两个整数数组 preorder 和 inorder &#xff0c;其中 preorder 是二叉树的先序遍历&#xff0c; inorder 是同一棵树的中序遍历&#xff0c;请构造二叉树并返回其根节点。 示例 1: 输入: preorder [3,9,20,15,7], inorder [9,3,15,20,7] 输出: [3,9,20,null,null,15,7]示…

使用Docker搭建Redis主从集群

文章目录 ☃️前言☃️搭建❄️❄️架构❄️❄️实例说明❄️❄️搭建第一个服务器上的两个实例❄️❄️搭建第二个服务器上的一个实例 ☃️开启主从❄️❄️改配置❄️❄️重启从节点 ☃️验证 ☃️前言 单节点 Redis 的并发能力是有上限的&#xff0c;要进一步提高Redis的并…

[大模型]TransNormerLLM-7B FastApi 部署调用

TransNormerLLM-7B FastApi 部署调用 1. TransNormer 介绍 TransNormerLLM 是一个基于线性注意力的 LLM&#xff0c;在准确性和效率方面均优于传统的基于 softmax 注意力的模型。它是在包含多达1.4 万亿个令牌的高质量语料库上进行训练的&#xff0c;TransNormerLLM 从之前的…

K-means和DBSCAN

目录 一、K-means和DBSCAN之间的主要区别 二、DBSCAN聚类算法 2.1DBSCAN聚类算法实现点集数据的聚类 2.2DBSCAN聚类算法实现鸢尾花数据集的聚类 三、K-means聚类算法 3.1K-means聚类算法实现随机数据的聚类 3.2K-means聚类算法实现鸢尾花数据集的聚类 一、K-means和DBSC…

014Node.js时间格式包silly-datetime安装与使用

下载&#xff1a; https://www.npmjs.com/网站上下载silly-datetime 安装 npm i silly-datetime --save var sd require(silly-datetime);console.log(new Date()); //2024-04-18T04:40:38.505Zvar dsd.format(new Date(), YYYY-MM-DD HH:mm);console.log(d); //2024…

idea在controller或者service使用ctrl+alt+b进入方法后,如何返回到 进入前的那一层

idea在controller或者service使用ctrlaltb进入方法后&#xff0c;如何返回到进入方法的最外层 解决方案使用 ctrlalt ← /→← /→ 键盘上的左右键盘

stm32中断发送接收数据

配置hal库 1配置时钟 2配置uart 3打开中断 程序结构 uart中断函数 中断接收和发送函数 HAL_UART_Receive_IT()&#xff1a;启动中断驱动的接收过程&#xff0c;当接收到指定数量的字节后会产生中断&#xff0c;并调用HAL_UART_RxCpltCallback()回调函数。 HAL_StatusTypeD…

STL分解

效果图 ref&#xff1a;时序数据分析的利器——STL分解 - 知乎 (zhihu.com)

2024化工制造企业数字化白皮书

来源&#xff1a;蓝凌研究院 中国石油和化学工业联合会发布2023年中国石油和化工行业经济运行情况。数据显示&#xff0c;2023年&#xff0c;我国石化行业实现营业收入15.95万亿元&#xff0c; 同比下降1.1%&#xff0c;利润总额8733.6亿元&#xff0c;行业经济运行总体呈现低…

MySQL-笔记-06.数据高级查询

目录 6.1 连接查询 6.1.1 交叉连接&#xff08;cross join&#xff09; 6.1.2 内连接&#xff08;inner join&#xff09; 6.1.3 外连接&#xff08;outer join&#xff09; 6.1.3.1 左外连接&#xff08;left [outer] join&#xff09; 6.1.3.2 右外连接&#xff08;rig…

VSCode 目录折叠展开、缩进深度设置

1、VSCode 目录折叠展开设置 运行 Visual Studio Code &#xff0c;按 Ctrl &#xff0c;打开设置 输入Explorer:Compact Folders&#xff0c;取消勾选 或者在设置文件上添加 "explorer.compactFolders": false2、VSCode 目录缩进深度设置 输入Workbench Tree:…

【C# 数据结构-队列】

在C#中&#xff0c;队列&#xff08;Queue&#xff09;是一种先进先出&#xff08;First In First Out&#xff0c;FIFO&#xff09;的数据结构&#xff0c;允许添加&#xff08;Enqueue&#xff09;和移除&#xff08;Dequeue&#xff09;元素。队列类在.NET Framework的Syste…

Navicat Premium 16最新版激活 mac/win

Navicat Premium 16 for Mac是一款专业的多连接数据库管理工具。它支持连接多种类型的数据库&#xff0c;包括MySQL、MongoDB、Oracle、SQLite、SQL Server、PostgreSQL等&#xff0c;可以同时连接多种数据库&#xff0c;帮助用户轻松地管理和迁移数据。 Navicat Premium 16 fo…

1.PROXY-代理内容

SwitchyOmega&#xff0c;浏览器插件&#xff08;edge&#xff0c;火狐插件库都是存在的&#xff09;&#xff0c;安装后的样式 1.安装 2.设置 我们常用的功能&#xff0c;主要是设置一个代理ip访问学习网站入github等&#xff0c;或者docker服务等 3.启动代理 4.验证 https…

LLMs之Llama3:Llama 3的简介、安装和使用方法、案例应用之详细攻略

LLMs之Llama3&#xff1a;Llama 3的简介、安装和使用方法、案例应用之详细攻略 导读&#xff1a;2024年4月18日&#xff0c;Meta 重磅推出了Meta Llama 3&#xff0c;本文章主要介绍了Meta推出的新的开源大语言模型Meta Llama 3。模型架构 Llama 3 是一种自回归语言模型&#x…