在 制作基于stm32f103的温湿度检测时遇到的问题及解决方法

1、DHT11模块启动不了

1.没有做DHT11启动判断(若DHT11启动会出现一段低电平),(硬件启动有点玄学问题),如果一次不行就跳过这次循环,下一次再尝试启动DHT11传感器。或者尝试多次拉高电平然后再根据芯片手册的启动电平信号去改变电平信号。

2、屏幕上的数值反应有点慢。。有时候还会卡住。

猜想:可能是DHT11在某次数据采集过程中出现问题,然后在某个while循环中阻塞住了。
解决办法:在while循环中做延时有效性判断,若延时了很久那就直接return,进入下一次数据采集。
在这里插入图片描述

3.在DHT11_Read中总是卡在for循环中总是出不去

原因:因为for循环中定义的i为无符号整数。。默认大于等于0减不到小于0所以将i定义为int型即可
在这里插入图片描述在这里插入图片描述

注意点:

1、&&与&是不同的( || 与 | 同理)

&&:是逻辑与操作
&:按位与操作

项目原理

对我来说整个项目的难点在于DHT11采集。。OLED屏基本用商家给的测试代码移植一下就行了

DATA 用于微处理器与 DHT11之间的通讯和同步,采用单总线数据格式,一次
通讯时间4ms左右,数据分小数部分和整数部分,具体格式在下面说明,当前小数
部分用于以后扩展,现读出为零.操作流程如下:
一次完整的数据传输为40bit,高位先出。
数据格式:8bit湿度整数数据+8bit湿度小数数据
+8bi温度整数数据+8bit温度小数数据
+8bit校验和
数据传送正确时校验和数据等于“8bit湿度整数数据+8bit湿度小数数
用户MCU发送一次开始信号后,DHT11从低功耗模式转换到高速模式,等待主
机开始信号结束后,DHT11发送响应信号,送出40bit的数据,并触发一次信号采集,
用户可选择读取部分数据.从模式下,DHT11接收到开始信号触发一次温湿度采集,
如果没有接收到主机发送开始信号,DHT11不会主动进行温湿度采集.采集数据后
转换到低速模式。
1.通讯过程如图1所示
在这里插入图片描述

总线空闲状态为高电平,主机把总线拉低等待DHT11响应,主机把总线拉低必
须大于18毫秒,保证DHT11能检测到起始信号。 DHT11接收到主机的开始信号后,
等待主机开始信号结束,然后发送80us低电平响应信号.主机发送开始信号结束
后,延时等待20-40us后, 读取DHT11的响应信号,主机发送开始信号后,可以切换
到输入模式,或者输出高电平均可, 总线由上拉电阻拉高。
在这里插入图片描述线为低电平,说明DHT11发送响应信号,DHT11发送响应信号后,再把总线拉
高80us,准备发送数据,每一bit数据都以50us低电平时隙开始,高电平的长短定
了数据位是0还是1.格式见下面图示.如果读取响应信号为高电平,则DHT11没有
响应,请检查线路是否连接正常.当最后一bit数据传送完毕后, DHT11拉低总线
50us,随后总线由上拉电阻拉高进入空闲状态。
在这里插入图片描述在这里插入图片描述

//DHT11代码
#include "DHT11.h"
int i;
int j ;
int crc = 0;
void DHT11_init(void){
	//配置data线为PB9
	GPIO_InitTypeDef 		GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
	GPIO_InitStructure.GPIO_Mode= GPIO_Mode_Out_PP;		
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//高速响应


	GPIO_Init(GPIOB,&GPIO_InitStructure);	
	
	GPIO_SetBits(GPIOB,GPIO_Pin_9);
	
	
}

int DHT11_Read(int* d){

	
	GPIO_InitTypeDef 		GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
	GPIO_InitStructure.GPIO_Mode= GPIO_Mode_Out_PP;		
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//高速响应
	GPIO_Init(GPIOB,&GPIO_InitStructure);	
	
	GPIO_SetBits(GPIOB,GPIO_Pin_9);
	delay_us(4);
	GPIO_ResetBits(GPIOB,GPIO_Pin_9);//时序置低为电平
	delay_ms(25);
	GPIO_SetBits(GPIOB,GPIO_Pin_9);//时序置为高电平
	delay_us(30);
//	OLED_ShowNum(8,8,1,2,2);
	//变为输入状态
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
	GPIO_InitStructure.GPIO_Mode= GPIO_Mode_IPU;		
	GPIO_Init(GPIOB,&GPIO_InitStructure);	

	delay_us(5);
	//dht11 start
		i = 0;
	if(GPIO_ReadInputDataBit( GPIOB,GPIO_Pin_9) == 0){
			while(!GPIO_ReadInputDataBit( GPIOB,GPIO_Pin_9)){
				delay_us(1);
				i++;
				if(i >100){
					OLED_ShowNum(0,0,1,1,1);
					return -1;
				}
			}
			i = 0;
			//等待高电平
			for(j = 31;j >=0;j--){
				//delay_us(80);
				while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_9)){
					delay_us(1);
					i++;
					if(i >2000){
						OLED_ShowNum(0,0,3,1,1);
						return -2;
					}
				}//等待数据来临
				//OLED_ShowNum(8,8,3,2,2);
			
				while(!GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_9)){
					delay_us(1);
					i++;
					if(i >4000){
						OLED_ShowNum(0,0,4,1,1);
						return -3;
					}
				}
				//OLED_ShowNum(0,31-j,j,1,1);
				delay_us(32);
				if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_9)){
					*d |= 1<<j; // 按位或
				}

			}
			j = 0;
			for(i=7;i>=0;i--)
			{
				while(!GPIO_ReadInputDataBit( GPIOB,GPIO_Pin_9)){
					delay_us(1);
					j++;
					if(j >2000){
						OLED_ShowNum(0,0,5,1,1);
						return -4;
					}
				}//等待高电平
				j = 0;
				while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_9)){
					delay_us(1);
					j++;
					if(j >100){
						OLED_ShowNum(0,0,6,1,1);
						return -5;
					}
				}//等待数据来临
				delay_us(30);
				if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_9)==1) //1
				{
								crc |= 1<<i;
				}
			}
			//if((((*d >> 8)&0xff)+(*d&0xff)+((*d >> 16)&0xff)+((*d >> 24)&0xff)) == crc&0xff){
				return 0;
			
			//}
			
		}
	else{
		return -1;
	}
	//OLED_Clear();
	return -1;
}


  • 4
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值