温湿度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.hqwc.cn/news/638074.html

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

相关文章

(避雷指引:管理页面超时问题)windows下载安装RabbitMQ

一、背景&#xff1a; 学习RabbitMQ过程中&#xff0c;由于个人电脑性能问题&#xff0c;直接装在windows去使用RabbitMQ&#xff0c;根据各大网友教程&#xff0c;去下载安装完之后&#xff0c;使用web端进行简单的入门操作时&#xff0c;总是一直提示超时&#xff0c;要么容…

大sql mysql执行

先把sql 拆分 太大的执行失败 使用 SQLDumpSplitter3 拆分sql 执行拆分的sql 拆分的sql 打开发现很多 ; 开头的空行 替换掉 正则 ^; 修改数据库 my.cnf my,ini 执行可能会提示 [ERR] 2006 - Server has gone away 错误 在 [mysqld] 添加以下几行 wait_timeout2880000 inter…

WordPress SQLite Docker 镜像封装细节

为了让大家用的放心&#xff0c;同时解答 GitHub 社区中的疑问。这篇文章聊聊上一篇文章的 Docker 容器封装细节。 写在前面 在前一篇文章《WordPress 告别 MySQL&#xff1a;Docker SQLite WordPress》中&#xff0c;如果你跟着文章实践&#xff0c;大概三分钟就能够启动一个…

python 文件 成绩分析2

‘’’ 文件score.txt中存储了学生的考试信息,内容如下 小明,98,96 小刚,90,94 小红,90,94 小王,98,96 小刘,80,90 小赵,90,96 第二列是数学成绩&#xff0c;第三列是语文成绩 请写程序分析&#xff1a; 哪些同学语文成绩是相同的?哪些同学数学成绩是相同的?哪些同学语文和数…

HarmonyOS开发环境搭建 移动开发 鸿蒙开发 ArkTS

&#x1f4dc;目录 &#x1f4a1; 环境搭建 &#x1f680;安装nodejs &#x1f935;安装ohpm &#x1f354;安装SDK &#x1f4a5;Emulator安装 &#x1f336;️新建ArkTs项目 &#x1f3c6;️ArkTS语言 ✨️基本语法 &#x1f388; 声明式UI描述 &#x1f371;组件 …

如何在 PyCharm 中集成 GitLab?

GitLab 是一个全球知名的一体化 DevOps 平台&#xff0c;很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab &#xff1a;https://gitlab.cn/install?channelcontent&utm_sourcecsdn 是 GitLab 在中国的发行版&#xff0c;专门为中国程序员服务。可以一键式部署…

初识C++·类和对象(中)(3)

前言&#xff0c;最难的已经结束了&#xff0c;来点轻松了放松一下。 目录 1 流重载 2 const成员 3 取地址及const取地址操作符重载 1 流重载 C语言中printf和scanf是有局限性&#xff0c;只能直接打印内置类型&#xff0c;对于自定义类型就哦豁了&#xff0c;所以在C中就…

基础SQL DDL语句

MySQL的DDL&#xff08;Data Definition Language&#xff09;语句用于定义或修改数据库结构。 DDL数据库操作 查看所有的数据库 show databases; 红色圈起来的是系统数据库&#xff0c;是系统自带的 mysql&#xff1a;包含存储MySQL服务器运行时所需信息的表。这包括数据字典…

【Linux】小知识点温习---命令

许多常见命令会用&#xff0c;但是很少注意他们的区别&#xff1b;亦或在学习中使用较少&#xff0c;容易忘记&#xff0c;今天做一个回顾。 ls系列 -a:显示所有文件&#xff08;包括隐藏文件&#xff09; -l:将文件以竖列形式显示 -i&#xff1a;显示文件的inode编号 pwd 显…

Redis数据类型——String

Redis官网指令文档&#xff1a;Commands | Docs 前言 此处的String类型是针对Redis的Value的&#xff0c;因为Key的形式都是String&#xff0c;而Value则有哈性、列表、集合等形式。 众所周知&#xff0c;由于不同编码&#xff0c;经常会出现乱码的问题&#xff0c;但在Redi…

Umi.js:登录之后需要手动刷新权限菜单才能渲染

在使用Umi.js开发后台管理页面时&#xff0c;用户登录之后&#xff0c;总是需要手动刷新一次页面&#xff0c;才能够拿到全局状态/权限信息。 问题描述 结合使用umi/plugin-layout和umi/plugin-access&#xff0c;登录进入页面&#xff0c;配置的权限菜单未渲染&#xff0c;需…

Redis中的慢查询日志(一)

慢查询日志 概述 Redis的慢查询日志功能用于记录执行时间超过给定时长的命令请求&#xff0c;用户可以通过这个功能产生的日志来 监视和优化查询速度。服务器配置有两个和慢查询日志相关的选项: 1.slowlog-log-slower-than选项指定执行时间超过多少微妙(1秒1000 000微妙)的命…