sophialili
SHT-31是一款低成本环境温湿度检测模块。DHT11是一款有已校准数字信号输出的温湿度传感器。DHT11数字温湿度传感器应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性和卓越的长期稳定性。传感器包括一个电阻式感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。因此该产品具有品质卓越、超快响应、抗干扰能力强、性价比极高等优点。每个DHT11传感器都在极为精确的湿度校验室中进行校准。校准系数以程序的形式存在OTP内存中,传感器内部在检测信号的处理过程中要调用这些校准系数。单线制串行接口,使系统集成变得简易快捷。超小的体积、极低的功耗,使其成为该类应用中,在苛刻应用场合的最佳选择。产品为4针单排引脚封装,连接方便。SHT-31是一款低成本环境温湿度检测模块。工作电压功耗小,体积小,采用DFN封装工艺。其工作原理,是通过单片机读取温度湿度数据,IIC通信方式输出。
快到碗里吧吧吧
使用51单片机,12M晶振,LCD1206液晶显示屏显示DHT11使用SPI单总线通讯协议进行通信,对延时程序的精度要求较高,如果得不到结果的话大部分都是延时有问题。#include"" //头文件#define uint unsigned int#define uchar unsigned charint humi,temp,check;uchar n,Readflag; //定义全局变量sbit SPI = P1^1;sbit RS = P2^4; sbit RW = P2^5;sbit EN = P2^6; //定义端口void delayms(uchar ms);void Init_Timer0(void); //函数声明void write_com(uchar com) //LCD1206端口写函数{RS=0;P0=com;delayms(5);EN=1;delayms(5);EN=0;}void write_data(uchar date) //LCD1206数据写函数{RS=1;P0=date;delayms(5);EN=1;delayms(5);EN=0;}void LCD1602_init() //LCD1206初始化函数{RW=0;EN=0;write_com(0x38);write_com(0x0c);write_com(0x06);write_com(0x01);}void Display_Humi(int v,unsigned char position) ////////////湿度显示函数{int shu;write_com(position);write_data('R');write_data('H');shu=v%100/10;write_data(shu+'0');shu=v%10;write_data(shu+'0');write_data('%');}void Display_Temp(int v,unsigned char position) ///////////温度显示函数{int shu;write_com(position);write_data('T');write_data('e');write_data('m');write_data('p');write_data(':');shu=v%100/10;write_data(shu+'0');shu=v%10;write_data(shu+'0');write_data(0xdf);write_data('C');}void Display_Check(int v,uchar position) //校验位显示函数{int shu;write_com(position);write_data('C');write_data('h');write_data('e');write_data('c');write_data('k');write_data(':');shu=v/100;write_data(shu+'0');shu=v%100/10;write_data(shu+'0');shu=v%10;write_data(shu+'0'); } void delayms(uchar ms) //精确延时毫秒级函数 {uchar i;while(ms--){for(i=0;i<120;i++);} }void delayus(uchar us) //精确延时微秒级函数{while(us--);}void DHT_Rst() //DHT11启动函数{SPI=0; //主机拉低总线18ms以上delayms(20);SPI=1; //主机拉高总线约30usdelayus(14);/// 20-40uswhile(SPI); //等待DHT11响应while(!SPI); //等待DHT11拉高总线}uchar Readbit() //读一位程序{while(SPI);//等待总线变为低电平while(!SPI);//等待总线变为高电平delayus(5);//等待10us,执行下几条程序使用约20usif(SPI)return 1;elsereturn 0; //////判断SPI总线状态,返回0或1}uchar Readbyte() //读一个字节程序{uchar i,dat;dat=0;for(i=0;i<8;i++) //重复读取8位数据{dat=dat<<1; //dat左移一次,总共8次dat=Readbit()|dat; //dat和返回值,按位或}return dat; //返回dat}void ReadDHT() //读DHT11温湿度传感器{uchar buf[5],i; //定义临时变量DHT_Rst(); //初始化传感器for(i=0;i<5;i++) //读5字节,共40位buf[i]=Readbyte();SPI=1; //通讯结束,拉高总线if(buf[0]+buf[1]+buf[2]+buf[3]==buf[4])//数据校验{humi=buf[0];//湿度值temp=buf[2];//温度值check=buf[4];//校验位值,校验位=湿度值+温度值(小数位为零)}}void main() //主函数{Init_Timer0(); //初始化定时器Readflag=0; //读标志位为0LCD1602_init(); //初始化LCD1602液晶显示屏while(1) //主循环{if(Readflag==1) //验证是否读{Readflag=0; //重置读标志位ReadDHT(); //读一次DHT11}Display_Temp(temp,0x80);Display_Humi(humi,0x8A);Display_Check(check,0xc0); /////显示值} }void Init_Timer0(void) //定时器初始化函数{TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响EA=1; //总中断打开ET0=1; //定时器中断打开TR0=1; //定时器开关打开}void Timer0_isr(void) interrupt 1 //定时器中断服务程序{static unsigned int num;TH0=(65536-10000)/256; //重新赋值 10msTL0=(65536-10000)%256;num++;if(num==20) //大致200ms{num=0;Readflag=1; //激活读命令}}纯手打,望采纳
比尼爱汤姆
亲爱的读者们,我又回来了~ 上一章中,我带着大家实现了时钟显示和按键调整的功能。在这一章中,我将利用DHT11温湿度传感器,来测量环境温度和湿度。 DHT11温湿度传感器是数字式的,包括1个电阻式感湿元件和1个NTC测温元件,内部自带AD转换功能,采用单总线,具有响应快、抗干扰能力强、性价比高等特点。该模块总共4个引脚,其中两个是电源引脚VCC和GND,一个是数据引脚,还有一个为空引脚。 目前流行的数据传输总线有II2C总线,SPI总线,单总线等,而DHT11则采用单总线传输数据。单总线,顾名思义,就是采用单根信号线,即可传输时钟,又能传输数据,而且数据传输是双向的,从而有主机和从机之别。在这里,stm32作为核心控制器,所以是主机,而DHT11为从机。 采用单总线进行数据传输,我们需要查看数据手册的时序图。 总线空闲状态为高电平,主机把总线拉低等待 DHT11 响应,主机把总线拉低必须大于 18 毫秒,保证 DHT11 能检测到起始信号。DHT11 接收到主机的开始信号后, 等待主机开始信号结束,然后发送 80us 低电平响应信号.主机发送开始信号结束后,延时等待 20-40us 后, 读取 DHT11 的响应信号,主机发送开始信号后,可以切换到输入模式,或者输出高电平均可, 总线由上拉电阻拉高。 根据时序图,单片机需要先将总线拉低至少18ms,然后拉高总线20~40us,此时主机的开始信号结束,检测DHT11的响应信号。如果检测到低电平,则DHT11响应,并且低电平时间维持80us,然后DHT11拉高总线80us。此时DHT11准备传输数据,传输的数据间隙为50us低电平,传输的数据通过高电平的时间长短来区分"0"和"1"。数据传输完毕,DHT11将总线拉低50us,最后主机再拉高总线。 (1)编写延时函数 由于DHT11的时序比较严格,需要毫秒级别和微妙级别的延时。这里我们采用Systick去做延时。在之前按键扫描函数里也用到延时的,在此我叙述一下。 我们需要配置系统时钟,然后把Systick设置成72,这样就能产生1us时间基准,其次编写Systick中断处理函数,让变量自减,从而达到延时的效果,最后编写延时函数,也就是对自减的变量赋初始值。 __IO uint32_t TimingDelay; /*配置SysTick函数*/ void systick_init(void) { /*配置Systick重载值,系统时钟为72MHz*/ /*设置72,中断时间:72*(1/72000000) = 1us*/ if(SysTick_Config(72)==1) //若SysTick_Config函数返回产生中断信号,返回值为0 { while(1); //SysTick_Config函数返回值为1,则等待 } } /*时间变量自减函数*/ void TimingDelay_Decrement(void) { if(TimingDelay!=0x00) { TimingDelay--; } } /*SysTick中断处理函数*/ void SysTick_Handler(void) { TimingDelay_Decrement(); } /*延时函数,时间基准为1ms*/ void delay_ms(__IO uint32_t nTime) { TimingDelay = nTime*1000; while(TimingDelay!=0); } /*延时函数,时间基准为1us*/ void delay_us(__IO uint32_t nTime) { TimingDelay = nTime; while(TimingDelay!=0); } (2)配置相应的GPIO口作为单总线数据端 /*配置DHT11数据引脚,设置成浮空输入模式*/ void dht11_gpio_portIn(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); = GPIO_Pin_4; = GPIO_Mode_IN_FLOATING; = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); } /*配置DHT11数据引脚,设置成推挽输出模式*/ void dht11_gpio_portOut(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); = GPIO_Pin_4; = GPIO_Mode_Out_PP; = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); } 由于DHT11采用单总线通信协议,所以数据传输是双向的,所以分别将数据端口设置成浮空输入模式和推挽输出模式。并且将数据口的输入和输出定义成宏定义的形式。 #define DHT11_OUT_H GPIO_SetBits(GPIOA, GPIO_Pin_4) #define DHT11_OUT_L GPIO_ResetBits(GPIOA, GPIO_Pin_4) #define DHT11_IN GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_4) (3)根据DHT11时序图,编写时序函数 现在,我们开始编写总线的驱动函数,根据时序图,主机发送命令启动转换,接着,等待DHT11转换响应并且输出数据,最后读取数据。 /*启动总线函数*/ void dht11_reset(void) { dht11_gpio_portOut(); //设置成输出模式 DHT11_OUT_L; //主机将总线拉低至少18ms delay_ms(18); DHT11_OUT_H; //主机拉高保持20~40us delay_us(30); dht11_gpio_portIn(); //设置成输入模式,等待DHT11响应 } /*DHT11响应函数*/ u8 dht11_scan(void) { return DHT11_IN; //返回值为DHT11的响应信号 } 实时监控DHT11的数据线,直至其产生出低电平,表示DHT11响应主机请求,开始传输数据。 /*DHT11读取位函数*/ u8 dht11_read_bit(void) { while(DHT11_IN==RESET); //传输数据位前存在50us低电平 delay_us(40); //根据高电平的时间长短决定电平是1还是0 if(DHT11_IN==SET) //"0"电平持续时间为26~28us,"1"电平持续时间为70us { while(DHT11_IN==SET); return 1; //若检测到高电平,返回值为1 } else { return 0; //若检测到高电平,返回值为0 } } /*DHT11读取字节函数*/ //注:数据最高位先传输 u8 dht11_read_byte(void) { u8 i,dat = 0x00; for(i=0; i<8; i++) { dat = dat<<1; dat = dat|dht11_read_bit();//将串行数据读取出来 } return dat; } 当DHT11响应后,就开始通过单总线传输数据,在读取位函数里,通过高电平的时间长短来判断输出的是'1'还是'0',在读取字节函数里,调用读取位函数,将传输的每8位整合出字节,并读取出来。 我们查阅DHT11数据手册,得知数据传输的结构(依次顺序):湿度整数部分(1字节)、湿度小数部分(1字节)、温度整数部分(1字节)、温度小数部分(1字节)、校验和(1字节)。这里,其实就是一个简单的通信协议。校验和就是源数据所有字节之和的低8位,确保传输数据的正确与稳定。 /*DHT11读取数据函数*/ u8 dht11_read_data(void) { u8 i; dht11_reset(); if(dht11_scan()==RESET) //DHT11发出响应信号 { while(DHT11_IN==RESET); //DHT11拉低总线80us while(DHT11_IN!=RESET); //DHT11拉高总线80us for(i=0; i<5; i++) { buffer[i] = dht11_read_byte(); } while(DHT11_IN==RESET); //发送完最后1bit数据后,等待50us低电平结束 dht11_gpio_portOut(); DHT11_OUT_H; //主机拉高总线 if(buffer[0]+buffer[1]+buffer[2]+buffer[3]==buffer[4]) { return 1; //校验成功 } else { return 0; //校验失败 } } else { return 0; //DHT11未发出响应信号 } } 在读取字节里,先等待DHT11响应,然后开始接收数据,并且连续读取5次,存放在事先定义好的数组里,主机发出结束信号,最后对读取的数据进行校验。 (4)测量显示温湿度 主函数调用DHT11读数据函数,并调用lcd显示函数,将温度和湿度显示出来即可。 if(dht11_read_data()==1)//读取数据,前提是DHT11响应,并且数据校验成功 { humidity = buffer[0];//buffer[0]存放的是湿度整数部分 temperature = buffer[2];//buffer[2]存放的是温度整数部分 } lcd_display_string(2,0,"温度"); lcd_display_num_m(2,32,temperature/10); lcd_display_num_m(2,40,temperature%10); lcd_display_string(4,0,“湿度”); lcd_display_num_m(4,32,humidity/10); lcd_display_num_m(4,40,humidity%10); 至此,通过本章的讲解,我相信,大家应该对于DHT11模块有了大致的了解,当然,如果你只是看看文章的话,可能效果不怎么理想。这些东西,都需要亲自动手的,正所谓"实践出真知"。所以,你可以在网上买开发板,再买一些模块,不一定要和我的一样。当然,想要挑战自己的话,可以买块最小系统板,这样,外围的硬件电路可以由自己搭建(功能自定义),灵活性强的同时,也锻炼了自己的动手能力。如果你是会设计PCB的大佬,那更好,估计你的水平,就浏览一下我的文章即可。
温度相关的毕业设计 ·基于单片机的数字温度计的设计·基于MCS-51数字温度表的设计·单片机的数字温度计设计·基于单片机的空调温度控制器设计·基于数字温度计的多
SHT-31是一款低成本环境温湿度检测模块。DHT11是一款有已校准数字信号输出的温湿度传感器。DHT11数字温湿度传感器应用专用的数字模块采集技术和温湿度传感
如需代写 可联系。
已把我毕业论文的一部分发给你了,应该是你想要的。还需要其它的说一声
已把我毕业论文的一部分发给你了,应该是你想要的。还需要其它的说一声