使用STM32 在实现温湿度LCD显示并蓝牙透传

这篇具有很好参考价值的文章主要介绍了使用STM32 在实现温湿度LCD显示并蓝牙透传。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

项目需求

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

硬件介绍

LCD1602

使用STM32 在实现温湿度LCD显示并蓝牙透传,stm32,单片机,c语言

是一种工业字符型液晶,能够同时显示16x02即32字符 (16列两行)

DHT11 

使用STM32 在实现温湿度LCD显示并蓝牙透传,stm32,单片机,c语言

DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。

HC-01

使用STM32 在实现温湿度LCD显示并蓝牙透传,stm32,单片机,c语言

蓝牙模块。

关于以上这三个模块的使用和详细介绍可以看前面的章节,这里直接进行代码的移植。

硬件接线

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

使用STM32 在实现温湿度LCD显示并蓝牙透传,stm32,单片机,c语言

 文章来源地址https://www.toymoban.com/news/detail-581900.html

CubeMX

1. 惯例配置 + 开串口1 + GPIO口

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

使用STM32 在实现温湿度LCD显示并蓝牙透传,stm32,单片机,c语言  

2. 开启Timer2:

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

使用STM32 在实现温湿度LCD显示并蓝牙透传,stm32,单片机,c语言

2. 惯例配置生成代码:

使用STM32 在实现温湿度LCD显示并蓝牙透传,stm32,单片机,c语言 

 

Keil

1. 打开MICRO-LIB

使用STM32 在实现温湿度LCD显示并蓝牙透传,stm32,单片机,c语言

2. 编写代码:

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

使用STM32 在实现温湿度LCD显示并蓝牙透传,stm32,单片机,c语言

 如图,需要:

  • 定义一个结构体
  • 使能时钟
  • 赋初值(这步可省略)
  • 对于结构体的成员变量进行赋值,分别是GPIO_InitStruct.Pin; GPIO_InitStruct.Mode; 
  • GPIO_InitStruct.Speed,其中GPIO_InitStruct.Mode就是需要根据情况修改的
  • 调用HAL_GPIO_Init 函数
void DHT_GPIO_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的时候,在写命令或内容时,拉高E和拉低E的间隔也需要从微妙级变成毫秒级,不然无法成功驱动!!!

#include "stdio.h"

char flag_busy = 0;

char buffer;
char datas[5];
char temp[9];
char huma[9];

void TIM2_Delay_us(uint16_t n_us) //使用TIM2来做us级延时函数
{
/* 使能定时器2计数 */
	__HAL_TIM_ENABLE(&htim2);
	__HAL_TIM_SetCounter(&htim2, 0);
	while(__HAL_TIM_GetCounter(&htim2) < ((1 * n_us)-1) );
/* 关闭定时器2计数 */
	__HAL_TIM_DISABLE(&htim2);
}

void DHT_GPIO_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 write(char flag_w, char cmd) //write(1,cmd)代表写内容;write(0,cmd)代表写指令
{
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_RESET); //RW全程置0
	
	if(flag_w == 1){
		HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_SET); //RS置1写内容
		HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_RESET); //E置0
		TIM2_Delay_us(2);
		
		GPIOA->ODR = cmd; //根据时序图,E为0时开始传内容
		
		HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_SET); //E置1
		HAL_Delay(5);
		HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_RESET); //E置0
		HAL_Delay(5);
	}
	
	if(flag_w == 0){
		HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET); //RS置0写指令
		HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_RESET); //E置0
		TIM2_Delay_us(2);
		
		GPIOA->ODR = cmd; //根据时序图,E为0时开始传内容
		
		HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_SET); //E置1
		HAL_Delay(5);
		HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_RESET); //E置0
		HAL_Delay(5);
	}
	
}
 

 
void Init()
{
	HAL_Delay(15);
	write(0,0x38);
	HAL_Delay(5);
	
	//detectBusy();
	write(0,0x38);
	//detectBusy();
	write(0,0x08);
	//detectBusy();
	write(0,0x01);
	//detectBusy();
	write(0,0x06);
	//detectBusy();
	write(0,0x0C);
	
}
 
void showStr(char *msg, char hang, char lie)
{
	char pos;
	
	if(hang == 0){//如果第一行
			pos = 0x80 + 0x00 + lie; 
	}else if(hang == 1){//如果第二行
			pos = 0x80 + 0x40 + lie;
	}
	//detectBusy();
	write(0,pos); //只要定下开始的位置,之后光标会自行移动
	
	while(*msg != '\0'){
		//detectBusy();
		write(1,*msg);
		msg++;
	}
		
}


void Start()
{	
	DHT_GPIO_Init(GPIO_MODE_OUTPUT_PP);//设置为输出模式!!
	
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET);
	HAL_Delay(30);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET);
	
	
	DHT_GPIO_Init(GPIO_MODE_INPUT);//设置为输入模式!!
	
	while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_7) == GPIO_PIN_SET);//不断读取直到DHT再次变低,说明模块响应
	while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_7) == GPIO_PIN_RESET); //不断读取直到DHT再次拉高,80us之后,再经过50us低电平,就代表要开始变高并开始传输数据了
	while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_7) == GPIO_PIN_SET);//不断读取直到DHT再次变低,说明数据传输前的50us低电平开始了
 
}

void showDataFromDHT()
{
	int i;//轮
	int j;//每一轮读多少次
  char tmp;
	char flag;
	
	Start();
	for(i= 0;i < 5;i++){ //5组数据
		for(j=0;j<8;j++){ //每组数据8位
			while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_7) == GPIO_PIN_RESET);//等待上拉
			TIM2_Delay_us(40);//高电平持续26-28us是‘0’,高电平持续70us是'1',所以delay40us之后观察还是否是高电平
			if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_7) == GPIO_PIN_SET){
				flag = 1;
				while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_7) == GPIO_PIN_SET);//不断读取下拉的一瞬间,因为要延迟80us,如果提前结束,下一次detect01就会出错,因为detect01是从判断上拉开始的
			}else{
				flag = 0;
			} 
			tmp = tmp << 1; //tmp左移一位,再最右侧空出一位
			tmp |= flag; //将Flag的值写入空出的一位,这样经历8次,就得到了完整的tmp,且第一个读入的数据就是最高位,符合DHT的数据传输逻辑
			//!!使用这种移位再赋值的方法可以得到的一个完整的char型数据,而不是像之前char xxx[8]一样,得到的是8个char型的字符串,不利于数据转化!!
		}
		datas[i] = tmp;
	}
	
}
 
void Build_Datas() //由于刚刚存储的是8位char型的数字,但是不管是蓝牙还是LCD,需要显示的都是字符,而比如数字“9”和字符"9"是不同的二进制表示,所以,需要转化
{
	huma[0] = 'H';
	huma[1] = ':';
	huma[2] = datas[0]/10 + 0x30; //查阅ASCII码可知,数字Y加上0x30就是字符Y
	huma[3] = datas[0]%10 + 0x30; //同时由于不管整数或小数,都使用两位数字来表示,因此需要对‘十位’和‘个位’分别进行提取再转化成字符
	huma[4] = '.';
	huma[5] = datas[1]/10 + 0x30;
	huma[6] = datas[1]%10 + 0x30;
	huma[7] = '%';
	huma[8] = '\0';
	
	temp[0] = 'T';
	temp[1] = ':';
	temp[2] = datas[2]/10 + 0x30;
	temp[3] = datas[2]%10 + 0x30;
	temp[4] = '.';
	temp[5] = datas[3]/10 + 0x30;
	temp[6] = datas[3]%10 + 0x30;
	temp[7] = 'C';
	temp[8] = '\0';
	
}

int fputc(int a, FILE *f) //一个字符一个字符发送
{
	unsigned char temp[1] = {a};
	HAL_UART_Transmit(&huart1, temp, 1, 0xffff);
	return a;
}

int main(void)
{
	
  Init(); //LCD1602初始化

  while (1)
  {
		HAL_Delay(1000);
		showDataFromDHT();	
		Build_Datas();
		
		printf(temp);
		printf("\r\n");
		printf(huma);
		printf("\r\n");
		
		showStr(temp,0,4);
		showStr(huma,1,4);
  }

}

实现效果

使用STM32 在实现温湿度LCD显示并蓝牙透传,stm32,单片机,c语言

 

 

到了这里,关于使用STM32 在实现温湿度LCD显示并蓝牙透传的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 68、基于STM32单片机DHT11温湿度蓝牙控制报警器app系统设计

    毕设帮助、开题指导、技术解答(有偿)见文末。 目录 摘要 一、硬件方案 二、设计功能 三、实物图 四、原理图 五、PCB图 六、程序源码 七、资料包括 温度、湿度和人类的生产、生活有着密切的关系,同时也是工业生产中最常见最基本的工艺参数,例如机械、电子、石油、

    2024年02月08日
    浏览(55)
  • STM32驱动dht11检测温湿度由OLED12864显示

    本次实验所使用的硬件环境如下: STM32F103C8T6开发板 DHT11温湿度传感器 OLED12864显示屏 杜邦线若干 软件环境 本次实验所使用的软件环境如下: Keil C51编译器 ST-LINK V2下载器 ST-LINK Utility软件 硬件连接 首先,将STM32F103C8T6开发板、DHT11温湿度传感器和OLED12864显示屏分别连接在一起

    2023年04月13日
    浏览(55)
  • 第七章 OLED+DHT11+STM32动态显示温湿度

            上一章给大家介绍了OLED显示模块的使用,但上一章我们在OLED上显示的是静态的,不会变动的,所以这一章我结合第一章介绍的DHT11温湿度模块,实现温湿度数值在OLED显示模块上进行动态显示,其实也是非常简单。         首先打开第一章提供的DHT11代码工程文件和

    2024年01月16日
    浏览(42)
  • 86、基于STM32单片机的温湿度DHT11 MQ-2烟雾火灾报警器蓝牙物联网设计

    毕设帮助、开题指导、技术解答(有偿)见文末。 目录 摘要 一、硬件方案                     二、设计功能 三、实物图 四、原理图 五、硬件框图 六、流程图 七、程序源码   八、资料包括 随着社会和经济的发展,防火工作越来越重要,但是目前国内的许多研发都侧重

    2024年02月06日
    浏览(44)
  • STM32+ESP8266+QT客户端上位机显示DHT11温湿度与点灯

    目录 1、简介 2、硬件连接 3、上位机源码 3.1 widget.h 3.2 widget.c  3.3 显示图  4、下位机源码 4.1 cubemax配置  4.2 keil源码 本文使用STM32F103C8T6单片机使用单片机通过ESP8266WIFI模块与QT设计的上位机进行通讯,ESP8266设置AP模式。实现DHT11传感器温湿度的显示与远程控制LED小灯的亮灭

    2024年02月06日
    浏览(49)
  • STM32--ESP8266物联网WIFI模块(贝壳物联)--温湿度数据上传服务器显示

    本文适用于STM32F103C8T6等MCU,其他MCU可以移植,完整资源见文末链接 一、简介 随着移动物联网的发展,各场景下对于物联控制、数据上传、远程控制的诉求也越来越多,基于此乐鑫科技推出了便宜好用性价比极高的wifi物联模块——ESP8266,话不多少我们先来看看这个神奇的模

    2024年02月08日
    浏览(49)
  • 基于STM32使用DHT11温湿度模块

    目录 前言 一、DHT11模块介绍 1、原理图 2、通信时序(单总线) 2.1、通信总过程 2.2、起始信号及DHT11应答 2.3、数字1信号的应答时序 2.4、数字0信号的应答时序 2.5、数据格式 二、使用步骤 1.使用CubeMX进行配置(基于stm32f407zgt6) 2.编写相关函数 ​编辑3、实验结果 三、代码分享

    2024年02月10日
    浏览(51)
  • [教程]一文搞懂STM32使用DHT11采集温湿度

          DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高 的可靠性与卓越的长期稳定性。传感器包括一个电阻式感湿元件和一个NTC测 温元件,并与一个高性能8位单片机相连接。

    2024年02月01日
    浏览(39)
  • STM32使用温湿度DHT11基于HAL库开发

    DHT11 是一款湿温度一体化的数字传感器。该传感器包括一个电阻式测湿元件和一个 NTC 测温元件,并与一个高性能 8 位单片机相连接。通过单片机等微处理器简单的电路连接就能够 实时的采集本地湿度和温度。DHT11 与单片机之间能采用简单的单总线进行通信,仅仅需要一 个

    2024年02月03日
    浏览(64)
  • Arduino Uno零基础入门学习笔记——智能时钟(可以显示温湿度)【LCD1602+DS1302+温湿度传感器+红外接收器+LED+蜂鸣器】

    需要以下几个外设 LCD1602(IIC驱动) DS1302 1-WIRE温湿度检测器 红外接收器 遥控器 两个LED(一红一蓝) 蜂鸣器 LCD1602IIC引脚 Arduino引脚 VCC 5V GND GND SDA A4 SCL A5 我这里的LCD1602是IIC的,所以只需要4根线 传感器引脚 Arduino引脚 - GND S 8 + 5V 中间的线是要接5V的 红外接收器引脚 Arduino引脚 -

    2024年02月06日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包