大家所熟悉都用过的温湿度传感器应该是DHT11了吧,基本上学习单片机的都用过,但是DHT11的精度不是很高,湿度±5%RH,温度±1℃,而且测试的时候一般还要延时3S左右测一下,测试频率慢,而且体积大,价格大概3块多一个吧。在淘宝上搜索温湿度传感器,偶然发现AHT10传感器,价格2.5一个,体积小,精度湿度±2%RH,温度精度±0.3℃。这个是国产温湿度传感器,性价比是比较高的,所以在这里介绍一下AHT10温湿度传感器的使用。 关于AHT10温湿度传感器的数据手册在官方网站上面可以下载到:AHT10温湿度传感器的数据手册 引脚说明: 电路设计: AHT10通信协议为IIC协议驱动代码如下所示,采用的是STM32103C8T6单片机。 AHT10.H AHT10.c文件 这里需要注意的是我用的 IIC引脚:SCL PB3,SDA PB4,所以使用的时候需要将JTAG功能关闭,一开始调试的时候因为没注意所以弄了一下午,才发现这个问题。 u8 AHT10ReadData(float *temperature,u8 *humidity); 下图是获取到的温湿度数据,在我对传感器哈了一口气候效果如图所示,Temp表示温度,hum表示湿度。 关于整个例程的程序我上传到了我的博客上面,大家可以自行下载,采用的单片机是STM32F103C8T6单片机,就是淘宝上10块钱一个的那种,里面还带了一些别的驱动文件我懒得删掉了,大家不用就行了,下面是IIC的实现函数。 myiic.h myiic.c
AHT10温湿度传感器STM32驱动
#ifndef _AHT10_H__ #define _AHT10_H__ #include "sys.h" #define AHT10_ADDRESS 0x70 #define AHT10_WRITE 0x70 #define AHT10_READ 0x71 /*****************函数声明******************/ extern void AHT10Init(void); extern u8 AHT10Check(void); extern void AHT10Reset(void); extern u8 AHT10ReadData(float *temperature,u8 *humidity); #endif
#include "aht10.h" #include "myiic.h" #include "delay.h" /** brief AHT10初始化函数 param NONE return NONE */ void AHT10Init() { //IIC_Init(); GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO|RCC_APB2Periph_GPIOB, ENABLE); GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable , ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设置为推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOBA GPIO_SetBits(GPIOB,GPIO_Pin_3|GPIO_Pin_4); //PA4 输出高 IIC_Start(); IIC_Send_Byte(AHT10_ADDRESS); IIC_Send_Byte(0xe1); IIC_Send_Byte(0x08); IIC_Send_Byte(0x00); IIC_Stop(); delay_ms(40);//延时20ms让传感器稳定 } /** brief 检查AHT10是否存在 param NONE return 0存在 1不存在 */ u8 AHT10Check(void) { u8 ack=0; IIC_Start(); IIC_Send_Byte(AHT10_ADDRESS); ack=IIC_Wait_Ack(); IIC_Stop(); return ack; } /** brief AHT10软复位 param NONE return NONE */ void AHT10Reset(void) { IIC_Start(); IIC_Send_Byte(AHT10_WRITE); IIC_Wait_Ack(); IIC_Send_Byte(0xba); IIC_Wait_Ack(); IIC_Stop(); } /** brief 检查AHT10读温湿度数据 param *temperature:需要读出的温度数据,float指针类型,精度范围+-0.3C param *humidity:需要读出的湿度数据,u8指针类型,精度范围+-2RH return 0 读数据正常 1读数据失败 */ u8 AHT10ReadData(float *temperature,u8 *humidity) { u8 ack; u32 SRH=0,ST=0; u8 databuff[6]; IIC_Start(); IIC_Send_Byte(AHT10_WRITE); IIC_Wait_Ack(); IIC_Send_Byte(0xac); IIC_Wait_Ack(); IIC_Send_Byte(0x33); IIC_Wait_Ack(); IIC_Send_Byte(0x00); IIC_Wait_Ack(); IIC_Stop(); delay_ms(80);//延时一会等待数据读出 IIC_Start(); IIC_Send_Byte(AHT10_READ); IIC_Wait_Ack(); ack=IIC_Read_Byte(1); if((ack&0x40)==0) { databuff[0]=IIC_Read_Byte(1); databuff[1]=IIC_Read_Byte(1); databuff[2]=IIC_Read_Byte(1); databuff[3]=IIC_Read_Byte(1); databuff[4]=IIC_Read_Byte(0); IIC_Stop(); SRH=(databuff[0]<<12)+(databuff[1]<<4)+(databuff[2]>>4); ST=((databuff[2]&0X0f)<<16)+(databuff[3]<<8)+(databuff[4]); *humidity=(int)(SRH*100.0/1024/1024+0.5); *temperature=((int)(ST*2000.0/1024/1024+0.5))/10.0-50; return 0; } IIC_Stop(); return 1; }
读出温湿度数据只需通过这个函数就行了,需要输入定义的数据类型地址,温度为浮点型数据,精度范围到小数点后一位,湿度为无符号char型数据,因为本身传感器的精度就是±2%RH,如果精度再设置成浮点型数据也没啥意义了所以就弄了u8类型。
#ifndef __MYIIC_H #define __MYIIC_H #include "sys.h" //IO方向设置 #define SDA_IN() {GPIOB->CRL&=0XFFF0FFFF;GPIOB->CRL|=(u32)8<<16;} #define SDA_OUT() {GPIOB->CRL&=0XFFF0FFFF;GPIOB->CRL|=(u32)3<<16;} //IO操作函数 #define IIC_SCL PBout(3) //SCL #define IIC_SDA PBout(4) //SDA #define READ_SDA PBin(4) //输入SDA //IIC所有操作函数 void IIC_Init(void); //初始化IIC的IO口 void IIC_Start(void); //发送IIC开始信号 void IIC_Stop(void); //发送IIC停止信号 void IIC_Send_Byte(u8 txd); //IIC发送一个字节 u8 IIC_Read_Byte(unsigned char ack);//IIC读取一个字节 u8 IIC_Wait_Ack(void); //IIC等待ACK信号 void IIC_Ack(void); //IIC发送ACK信号 void IIC_NAck(void); //IIC不发送ACK信号 void IIC_Write_One_Byte(u8 daddr,u8 addr,u8 data); u8 IIC_Read_One_Byte(u8 daddr,u8 addr); #endif
#include "myiic.h" #include "delay.h" //初始化IIC void IIC_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE ); //使能GPIOB时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4; 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_3|GPIO_Pin_4); //PB6,PB7 输出高 } //产生IIC起始信号 void IIC_Start(void) { SDA_OUT(); //sda线输出 IIC_SDA=1; IIC_SCL=1; delay_us(4); IIC_SDA=0;//START:when CLK is high,DATA change form high to low delay_us(4); IIC_SCL=0;//钳住I2C总线,准备发送或接收数据 } //产生IIC停止信号 void IIC_Stop(void) { SDA_OUT();//sda线输出 IIC_SCL=0; IIC_SDA=0;//STOP:when CLK is high DATA change form low to high delay_us(4); IIC_SCL=1; IIC_SDA=1;//发送I2C总线结束信号 delay_us(4); } //等待应答信号到来 //返回值:1,接收应答失败 // 0,接收应答成功 u8 IIC_Wait_Ack(void) { u8 ucErrTime=0; SDA_IN(); //SDA设置为输入 IIC_SDA=1;delay_us(1); IIC_SCL=1;delay_us(1); while(READ_SDA) { ucErrTime++; if(ucErrTime>250) { IIC_Stop(); return 1; } } IIC_SCL=0;//时钟输出0 return 0; } //产生ACK应答 void IIC_Ack(void) { IIC_SCL=0; SDA_OUT(); IIC_SDA=0; delay_us(2); IIC_SCL=1; delay_us(2); IIC_SCL=0; } //不产生ACK应答 void IIC_NAck(void) { IIC_SCL=0; SDA_OUT(); IIC_SDA=1; delay_us(2); IIC_SCL=1; delay_us(2); IIC_SCL=0; } //IIC发送一个字节 //返回从机有无应答 //1,有应答 //0,无应答 void IIC_Send_Byte(u8 txd) { u8 t; SDA_OUT(); IIC_SCL=0;//拉低时钟开始数据传输 for(t=0;t<8;t++) { //IIC_SDA=(txd&0x80)>>7; if((txd&0x80)>>7) IIC_SDA=1; else IIC_SDA=0; txd<<=1; delay_us(2); //对TEA5767这三个延时都是必须的 IIC_SCL=1; delay_us(2); IIC_SCL=0; delay_us(2); } } //读1个字节,ack=1时,发送ACK,ack=0,发送nACK u8 IIC_Read_Byte(unsigned char ack) { unsigned char i,receive=0; SDA_IN();//SDA设置为输入 for(i=0;i<8;i++ ) { IIC_SCL=0; delay_us(2); IIC_SCL=1; receive<<=1; if(READ_SDA)receive++; delay_us(1); } if (!ack) IIC_NAck();//发送nACK else IIC_Ack(); //发送ACK return receive; }
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算