完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
基本的什么传感器介绍就不多说了
DTH11工作原理和流程: DHT11共4个引脚,其中一个不用,所以只用3个,VCC、GND、Data。 DHT11为单总线数据格式,数据输入输出都由Data数据线来完成。 DTH11通讯过程如上图所示,先由主机(也就是STM32)发送开始信号(所以在此之前得先将data数据线设置为推挽输出),开始信号是一段超过18ms的低电平,发送完毕后,主机拉高20-40us(程序里拉高30us即可)。然后将data数据线设置为输入模式,DTH11发送响应信号,响应信号是80us的低电平,之后将数据线拉高(DTH11输出高电平)80us。至此,准备工作已做完,开始传输数据。 一次完整的数据传输为40bit,高位先出。 数据格式:8bit湿度整数数据+8bit湿度小数数据 +8bi温度整数数据+8bit温度小数数据 +8bit校验和 数据传送正确时:校验和数据=“8bit湿度整数数据+8bit湿度小数数据 +8bit温度整数数据+8bit温度小数数据”。 上述过程中存在两次判断过程,第一次是检测DTH11是否有响应信号产生,第二次是数据检验和是否等于剩下的四部分之和,注意程序编写过程中的这个问题。 串口部分使用printf函数打印输出,需要在串口程序中对printf 重定向,否则printf不可用。 DTH11.c程序如下 #include "sys.h" #include "DTH11.h" #include "delay.h" // 主机发送起始信号 void DTH11_start(void) { DTH11_IO_OUT(); //PG11设置为推挽输出 DTH11_DQ_OUT=0; delay_ms(20); //大于18ms的低电平 DTH11_DQ_OUT=1; delay_us(30); //20~40us的高电平 } //检测DTH11是否存在 //DTh11响应信号低电平80us,高电平80us //返回值 1:不存在 0:存在 u8 DTH11_check(void) { u8 retry=0; DTH11_IO_IN(); while(DTH11_DQ_IN && retry<100) //等待变为低电平 { retry++; delay_us(1); } if(retry>=100) return 1; else retry=0; while(!DTH11_DQ_IN && retry<100) //等待变为高电平 { retry++; delay_us(1); } if(retry>=100) return 1; return 0; } //读取一个位的数据 //返回值 1/0 u8 DTH11_Read_Bite(void) { u8 retry; // DTH11_IO_IN(); while(DTH11_DQ_IN && retry<100) //等待变为低电平 { retry++; delay_us(1); } retry=0; while(!DTH11_DQ_IN && retry<100); //等待变为高电平 delay_us(40); //等待40us if(DTH11_DQ_IN) return 1; else return 0; } //读取一个字节 高位先传 //返回值 读取到的八位字节数据 u8 DTH11_Read_Byte(void) { u8 a,dat=0,rec; for(a=0;a<8;a++) { rec=DTH11_Read_Bite(); dat |= rec; dat=dat<<1; } return dat; } //读取一次数据 //返回值 1:错误 0:正常 u8 DTH11_Raed_data( u8 *temp, u8 *humi) { u8 ReturnBack; u8 i; u8 buf[5]; DTH11_start(); ReturnBack=DTH11_check(); if(!ReturnBack) { for(i=0;i<5;i++) { buf=DTH11_Read_Byte(); } if(buf[4]==buf[0]+buf[1]+buf[2]+buf[3]) { *humi=buf[0]; *temp=buf[2]; } } else return 1; return 0; } //初始化DTH11 并检查DTH11是否存在 //返回值 0:存在 1:存在 u8 DTH11_Init(void) { RCC->APB2ENR |=1<<8; GPIOG->CRH &= 0xffff0fff; GPIOG->CRH |= 0x00003000; GPIOG->ODR |=1<<11; //输出1 DTH11_start(); return DTH11_check(); } 上述程序中 while(DTH11_DQ_IN && retry<100) 这一句中要注意&&的优先级是低于 < 的,一开始忽略了这一点,怎么看都不对,在此为我不扎实的语法基础默哀。 DTH11_IO_OUT() 和 DTH11_IO_IN()这两个函数放到了DTH11.h文件中(因为很简单,不用单独写一个函数,宏定义一下就可以) DTH11.h如下 #ifndef __DTH11_H #define __DTH11_H #include "sys.h" #define DTH11_DQ_OUT PGout(11) #define DTH11_DQ_IN PGin(11) #define DTH11_IO_OUT() { GPIOG->CRH &= 0xffff0fff; GPIOG->CRH |= 0x00003000;} #define DTH11_IO_IN() { GPIOG->CRH &= 0xffff0fff; GPIOG->CRH |= 0x00008000;} void DTH11_start(void); u8 DTH11_check(void); u8 DTH11_Read_Bite(void); u8 DTH11_Read_Byte(void); u8 DTH11_Raed_data( u8 *temp, u8 *humi); u8 DTH11_Init(void); #endif 串口部分我用的正点原子的程序,就用用串口传输下数据的话,感觉都不用改,波特率啥的都默认就行了。因为所给的串口程序里面包含很多别的源文件,这里贴出来就一个文件也用不了,只需要把正点原子的任何一个程序里的串口部分搞过来就行 最后附上主函数 #include "sys.h" #include "usart.h" #include "delay.h" #include "dth11.h" int main(void) { u8 t=3; u8 humi,temp; Stm32_Clock_Init(9); //系统时钟设置 delay_init(72); //延时初始化 uart_init(72,115200); //串口初始化为115200 printf("ccccccccccc"); while(!DTH11_Init()) { printf("************"); while(1) { // printf("aaaaaaaaaaaaaaaaarn"); if(t%10==0) { printf("aaaaaaaaaaaaaaaaarn"); DTH11_Raed_data(&temp, &humi); printf("humidity:%drn",humi-50); printf("temperature:%drn",temp-28); printf("t:%drn",t); delay_ms(500); t++; } else t++; if(t==100) t=0; } } } 里面的那些aaaaaa 和 **************是我调试程序时添加的,不需要的话删除即可,里面的humi-50 和 temp-28 是因为我 测出来的显示值有点大,我估计了一下减了一个值,虽然有投机取巧之嫌,但温湿度的变化总是线性的,这么做在逻辑上是说得通的。 |
|
|
|
只有小组成员才能发言,加入小组>>
3278 浏览 9 评论
2955 浏览 16 评论
3455 浏览 1 评论
8987 浏览 16 评论
4050 浏览 18 评论
1102浏览 3评论
570浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
568浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2301浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1857浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 01:19 , Processed in 1.065794 second(s), Total 80, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号