温度传感器实验
实验内容:
单片机通过代码模拟1-Wire总线并对DS18B20进行读写,并在TFTLCD屏幕上显示当前实时温度。
电路原理图:
1-Wire总线
1-Wire总线:即单总线协议,采用单根信号线,既传输时钟,又传输数据,而且数据传输是双向的。节省I/O口线资源、结构简单、成本低廉。
DS18B20
一种数字温度传感器,提供 9 位(二进制)温度读数,指示器件的温度。信息经过单线接口送入 DSl8B20 或从 DSl8B20 送出,因此从主机 CPU 到 DSl8B20 仅需一条线(和地线)。DSl8B20 的测量范围从-55℃到+125℃,增量值为 0.5℃,可在 l s(典型值)内把温度变换成数字。
- DS18B20 时序:
复位脉冲和应答脉冲:
单总线上的所有通信都是以初始化序列开始主机输出低电平,保持低电平时间至少480us,以产生复位脉冲。接着主机释放总线,10K的上拉电阻将单总线拉高,延时15~60us,并进入接收模式(Rx)。接着DS18B20拉低总线60~240us,以产生低电平应答脉冲,若为低电平,再延时480us。
写时序:
写时序包括写0时序和写1时序所有写时序至少需要 60us,且在2次独立的写时序之间至少需要1us的恢复时间,两种写时序均起始于主机拉低总线。写1时序:主机输出低电平,延时2us然后释放总线,延时60us写0时序:主机输出低电平,延时60us,然后释放总线,延时2us。
读时序:
单总线器件仅在主机发出读时序时,才向主机传输数据,所以,在主机发出读数据命令后,必须马上产生读时序,以便从机能够传输数据。所有读时序至少需要60us,且在2次独立的读时序之间至少需要1us 的恢复时间。每个读时序都由主机发起,至少拉低总线1us。主机在读时序期间必须释放总线, 并且在时序起始后的15us之内采样总线状态。典型的读时序过程为:主机输出低电平延时2us,然后主机转入输入模式延时12us,然后读取单总线当前的电平,然后延时50us。
程序代码
1、 DS18B20先读取一个位,再用for循环读取一个字节。
2、 写一个字节到DS18B20数字温度计
void DS18B20_Write_Byte(u8 dat) { u8 j;u8 testb;DS18B20_IO_OUT(); //SET PG11 OUTPUT;for (j=1;j<=8;j++) {testb=dat&0x01;dat=dat>>1;if (testb) {DS18B20_DQ_OUT=0; // Write 1delay_us(2); DS18B20_DQ_OUT=1;delay_us(60); }else {DS18B20_DQ_OUT=0; // Write 0delay_us(60); DS18B20_DQ_OUT=1;delay_us(2); }}
}
3、随后进行开始温度转换,再获取温度值,最后在主函数中调用,这里仅对主函数进行展示。
int main(void){ u8 t=0; short temperature; delay_init(); //延时函数初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级uart_init(115200); //串口初始化为 115200
// LED_Init(); //初始化与LED连接的硬件接口LCD_Init(); //初始化LCD POINT_COLOR=RED; //设置字体为红色 LCD_ShowString(30,50,200,16,16,"STM32"); LCD_ShowString(30,70,200,16,16,"DS18B20 TEST"); LCD_ShowString(30,90,200,16,16,"STM32F103ZET6");LCD_ShowString(30,110,200,16,16,"2015/1/16"); while(DS18B20_Init()) //DS18B20初始化 {LCD_ShowString(30,130,200,16,16,"DS18B20 Error");delay_ms(200);LCD_Fill(30,130,239,130+16,WHITE);delay_ms(200);} LCD_ShowString(30,130,200,16,16,"DS18B20 OK");POINT_COLOR=BLUE;//设置字体为蓝色 LCD_ShowString(30,150,200,16,16,"Temp: . C"); while(1){ if(t%10==0) //每100ms读取一次{ temperature=DS18B20_Get_Temp(); if(temperature<0){LCD_ShowChar(30+40,150,'-',16,0); //显示负号temperature=-temperature; //转为正数}else LCD_ShowChar(30+40,150,' ',16,0); //去掉负号LCD_ShowNum(30+40+8,150,temperature/10,2,16); //显示正数部分 LCD_ShowNum(30+40+32,150,temperature%10,1,16); //显示小数部分 } delay_ms(10);t++;if(t==20){t=0;LED0=!LED0;}}
}
温度湿度传感器实验
与上面温度传感器实验不同的是,温度湿度传感器实验采用的传感器是DHT11温湿度传感器。
实验内容:
单片机通过读写DHT11的寄存器实现对温湿度实时检测并通过TFTLCD屏实时显示。
电路原理图:
DHT11
DHT11 数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。相比于 DS18B20 只能测量温度,DHT11 既能检测温度又能检测湿度,不过 DHT11 的精度和测量范围都要低于 DS18B20,其温度测量范围为 0~50℃,误差在±2℃;湿度的测量范围为 20%~90%RH(Relative Humidity 相对湿度—指空气中水汽压与饱和水汽压的百分比),误差在±5%RH。
- 数据格式为:8bit 湿度整数数据+8bit 湿度小数数据+8bit 温度整数数据+8bit 温度小数数据+8bit 校验和,一共 5 字节(40bit)数据。由于 DHT11 分辨率只能精确到个位,所以小数部分是数据全为 0。校验和为前 4 个字节数据相加,校验的目的是为了保证数据传输的准确性。
DHT11 不主动进行温湿度采集。DHT11 只有在接收到开始信号后才触发一次温湿度采集,如果没有接收到主机发送复位信号。当数据采集完毕且无开始信号后,DHT11 自动切换到低速模式。 - 数据传输:
DHT11 在拉高总线 80us 后开始传输数据。每 1bit 数据都以 50us 低电平时隙开始,告诉主机开始传输一位数据了。DHT11 以高电平的长短定义数据位是 0 还是 1,当 50us 低电平时隙过后拉高总线,高电平持续 26~28us 表示数据“0”;持续 70us 表示数据“1”。
当 最后 1bit 数据传送完毕后,DHT11 拉低总线 50us,表示数据传输完毕,随后总线由上拉电阻拉高进入空闲状态。
程序代码
这里仅对主函数代码进行展示
int main(void){ u8 t=0; u8 temperature; u8 humidity; delay_init(); //延时函数初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级uart_init(115200); //串口初始化为115200LED_Init(); //初始化与LED连接的硬件接口LCD_Init(); //初始化LCD POINT_COLOR=RED; //设置字体为红色 LCD_ShowString(30,50,200,16,16,"STM32"); LCD_ShowString(30,70,200,16,16,"DHT11 TEST"); LCD_ShowString(30,90,200,16,16,"STM32F103ZET6");LCD_ShowString(30,110,200,16,16,"2015/1/16"); while(DHT11_Init()) //DHT11初始化 {LCD_ShowString(30,130,200,16,16,"DHT11 Error");delay_ms(200);LCD_Fill(30,130,239,130+16,WHITE);delay_ms(200);} LCD_ShowString(30,130,200,16,16,"DHT11 OK");POINT_COLOR=BLUE;//设置字体为蓝色 LCD_ShowString(30,150,200,16,16,"Temp: C"); LCD_ShowString(30,170,200,16,16,"Humi: %"); while(1){ if(t%10==0) //每100ms读取一次{ DHT11_Read_Data(&temperature,&humidity); //读取温湿度值 LCD_ShowNum(30+40,150,temperature,2,16); //显示温度 LCD_ShowNum(30+40,170,humidity,2,16); //显示湿度 } delay_ms(10);t++;if(t==20){t=0;LED0=!LED0;}}
}