3个回答
展开全部
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
//数码管位定义
sbit dula = P2^6;
sbit wela = P2^7;
#define OK 1
#define ERROR 0
#define NUMBER 20
#define SIZE 5
sbit dht11 = P2^0;
uchar status;
//存放五字节数据的数组
uchar value_array[SIZE];
/*可在其他的文件引用温湿度值,实际是温度的整数的10 倍
如dht11 读回的温度是26,则temp_value = 260, 湿度同理*/
uchar flag;
//数码管编码
uchar code array[]= {
0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x07,0x7f,0x6f
};
int temp_value, humi_value;
void InitTime(void);
//void Delay_1ms(uint ms);
void SMG_Display(uint value);
void Delay_1ms(uint ms)
{
uint x, y;
for(x = ms; x > 0; x--)
{
for(y = 124; y > 0; y--);
}
}
void Delay_10us(void)
{
unsigned char i;
i--;
i--;
i--;
i--;
i--;
i--;
}
/*读一个字节的数据*/
uchar ReadValue(void)
{
uchar count, value = 0, i;
status = OK; //设定标志为正常状态
for(i = 8; i > 0; i--)
{
//高位在先
value <<= 1;
count = 0;
//每一位数据前会有一个50us 的低电平时间.等待50us 低电平结束
while(dht11 == 0 && count++ < NUMBER);
if(count >= NUMBER)
{
status = ERROR; //设定错误标志
return 0; //函数执行过程发生错误就退出函数
}
//26-28us 的高电平表示该位是0,为70us 高电平表该位1
Delay_10us();
Delay_10us();
Delay_10us();
//延时30us 后检测数据线是否还是高电平
if(dht11 != 0)
{
//进入这里表示该位是1
value++;
//等待剩余(约40us)的高电平结束
while(dht11 != 0 && count++ < NUMBER)
{
dht11 = 1;
}
if(count >= NUMBER)
{
status = ERROR; //设定错误标志
return 0;
}
}
}
return (value);
}
//读一次的数据,共五字节
uchar ReadTempAndHumi(void)
{
uchar i = 0, check_value = 0,count = 0;
EA = 0;
dht11 = 0; //拉低数据线大于18ms 发送开始信号
Delay_1ms(20); //需大于18 毫秒
dht11 = 1; //释放数据线,用于检测低电平的应答信号
//延时20-40us,等待一段时间后检测应答信号,应答信号是从机拉低数据线80us
Delay_10us();
Delay_10us();
Delay_10us();
Delay_10us();
if(dht11 != 0) //检测应答信号,应答信号是低电平
{
//没应答信号
EA = 1;
return ERROR;
}
else
{
//有应答信号
while(dht11 == 0 && count++ < NUMBER); //等待应答信号结束
if(count >= NUMBER) //检测计数器是否超过了设定的范围
{
dht11 = 1;
EA = 1;
return ERROR; //读数据出错,退出函数
}
count = 0;
dht11 = 1;//释放数据线
//应答信号后会有一个80us 的高电平,等待高电平结束
while(dht11 != 0 && count++ < NUMBER);
if(count >= NUMBER)
{
dht11 = 1;
EA = 1;
return ERROR; //退出函数
}
//读出湿.温度值
for(i = 0; i < SIZE; i++)
{
value_array[i] = ReadValue();
if(status == ERROR)//调用ReadValue()读数据出错会设定status 为ERROR
{
dht11 = 1;
EA = 1;
return ERROR;
}
//读出的最后一个值是校验值不需加上去
if(i != SIZE - 1)
{
//读出的五字节数据中的前四字节数据和等于第五字节数据表示成功
check_value += value_array[i];
}
}//end for
//在没用发生函数调用失败时进行校验
if(check_value == value_array[SIZE - 1])
{
//将温湿度扩大10 倍方便分离出每一位
humi_value = value_array[0] * 10;
temp_value = value_array[2] * 10;
dht11 = 1;
EA = 1;
return OK; //正确的读出dht11 输出的数据
}
else
{
//校验数据出错
EA = 1;
return ERROR;
}
}
}
void main(void)
{
uchar mark = 0;
//先等上电稳定
Delay_1ms(1000);
//因为读一次数据dht11 才会触发一次采集数据.
//即在先使用数据时采集一次数据
ReadTempAndHumi();
//因为在两次采集数据需一定的时间间隔,这里还可减少
Delay_1ms(3000);
//设定定时器
InitTime();
while(1)
{
//三秒读一次温湿度
if(flag == 60)
{
flag = 0;
mark++;
/*
//读温湿度,可检测函数调用是否失败,
//函数返回OK(1)表示成功,返回ERROR(0)表示失败
//OK和ERROR是在DHT11.H中定义的宏
*/
ReadTempAndHumi();
}
if(mark % 2 == 0)
{
//显示温度
SMG_Display(temp_value);
}
else
{
//显示湿度
SMG_Display(humi_value);
}
}
}
//设定定时器
void InitTime(void)
{
TH0 = (65535 - 50000)/256;
TL0 = (65535 - 50000)%256 ;
TMOD = 0X01;
TR0 = 1;
ET0 = 1;
EA = 1;
}
//数码管显示函数
void SMG_Display(uint value)
{
uchar ge, bai, shi;
ge = value % 10;
shi = value % 100 / 10;
bai = value % 1000 / 100;
wela=1;
P0 = 0XFE;
wela=0;
P0 = 0XFF;
dula=1;;
P0 = array[bai];
dula=0;
Delay_1ms(2);
wela=1;
P0 = 0XFD;
wela=0;
P0 = 0XFF;
dula=1;
P0 = array[shi];
P0 |= 0x80; /*显示小数点*/
dula=0;
Delay_1ms(2);
wela=1;
P0 = 0XFB;
wela=0;
P0 = 0XFF;
dula=1;
P0 = array[ge];
dula=0;
Delay_1ms(2);
}
//中断函数
void timer(void) interrupt 1
{
TH0 = (65535 - 50000)/256;
TL0 = (65535 - 50000)%256;
flag++;
}
#define uchar unsigned char
#define uint unsigned int
//数码管位定义
sbit dula = P2^6;
sbit wela = P2^7;
#define OK 1
#define ERROR 0
#define NUMBER 20
#define SIZE 5
sbit dht11 = P2^0;
uchar status;
//存放五字节数据的数组
uchar value_array[SIZE];
/*可在其他的文件引用温湿度值,实际是温度的整数的10 倍
如dht11 读回的温度是26,则temp_value = 260, 湿度同理*/
uchar flag;
//数码管编码
uchar code array[]= {
0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x07,0x7f,0x6f
};
int temp_value, humi_value;
void InitTime(void);
//void Delay_1ms(uint ms);
void SMG_Display(uint value);
void Delay_1ms(uint ms)
{
uint x, y;
for(x = ms; x > 0; x--)
{
for(y = 124; y > 0; y--);
}
}
void Delay_10us(void)
{
unsigned char i;
i--;
i--;
i--;
i--;
i--;
i--;
}
/*读一个字节的数据*/
uchar ReadValue(void)
{
uchar count, value = 0, i;
status = OK; //设定标志为正常状态
for(i = 8; i > 0; i--)
{
//高位在先
value <<= 1;
count = 0;
//每一位数据前会有一个50us 的低电平时间.等待50us 低电平结束
while(dht11 == 0 && count++ < NUMBER);
if(count >= NUMBER)
{
status = ERROR; //设定错误标志
return 0; //函数执行过程发生错误就退出函数
}
//26-28us 的高电平表示该位是0,为70us 高电平表该位1
Delay_10us();
Delay_10us();
Delay_10us();
//延时30us 后检测数据线是否还是高电平
if(dht11 != 0)
{
//进入这里表示该位是1
value++;
//等待剩余(约40us)的高电平结束
while(dht11 != 0 && count++ < NUMBER)
{
dht11 = 1;
}
if(count >= NUMBER)
{
status = ERROR; //设定错误标志
return 0;
}
}
}
return (value);
}
//读一次的数据,共五字节
uchar ReadTempAndHumi(void)
{
uchar i = 0, check_value = 0,count = 0;
EA = 0;
dht11 = 0; //拉低数据线大于18ms 发送开始信号
Delay_1ms(20); //需大于18 毫秒
dht11 = 1; //释放数据线,用于检测低电平的应答信号
//延时20-40us,等待一段时间后检测应答信号,应答信号是从机拉低数据线80us
Delay_10us();
Delay_10us();
Delay_10us();
Delay_10us();
if(dht11 != 0) //检测应答信号,应答信号是低电平
{
//没应答信号
EA = 1;
return ERROR;
}
else
{
//有应答信号
while(dht11 == 0 && count++ < NUMBER); //等待应答信号结束
if(count >= NUMBER) //检测计数器是否超过了设定的范围
{
dht11 = 1;
EA = 1;
return ERROR; //读数据出错,退出函数
}
count = 0;
dht11 = 1;//释放数据线
//应答信号后会有一个80us 的高电平,等待高电平结束
while(dht11 != 0 && count++ < NUMBER);
if(count >= NUMBER)
{
dht11 = 1;
EA = 1;
return ERROR; //退出函数
}
//读出湿.温度值
for(i = 0; i < SIZE; i++)
{
value_array[i] = ReadValue();
if(status == ERROR)//调用ReadValue()读数据出错会设定status 为ERROR
{
dht11 = 1;
EA = 1;
return ERROR;
}
//读出的最后一个值是校验值不需加上去
if(i != SIZE - 1)
{
//读出的五字节数据中的前四字节数据和等于第五字节数据表示成功
check_value += value_array[i];
}
}//end for
//在没用发生函数调用失败时进行校验
if(check_value == value_array[SIZE - 1])
{
//将温湿度扩大10 倍方便分离出每一位
humi_value = value_array[0] * 10;
temp_value = value_array[2] * 10;
dht11 = 1;
EA = 1;
return OK; //正确的读出dht11 输出的数据
}
else
{
//校验数据出错
EA = 1;
return ERROR;
}
}
}
void main(void)
{
uchar mark = 0;
//先等上电稳定
Delay_1ms(1000);
//因为读一次数据dht11 才会触发一次采集数据.
//即在先使用数据时采集一次数据
ReadTempAndHumi();
//因为在两次采集数据需一定的时间间隔,这里还可减少
Delay_1ms(3000);
//设定定时器
InitTime();
while(1)
{
//三秒读一次温湿度
if(flag == 60)
{
flag = 0;
mark++;
/*
//读温湿度,可检测函数调用是否失败,
//函数返回OK(1)表示成功,返回ERROR(0)表示失败
//OK和ERROR是在DHT11.H中定义的宏
*/
ReadTempAndHumi();
}
if(mark % 2 == 0)
{
//显示温度
SMG_Display(temp_value);
}
else
{
//显示湿度
SMG_Display(humi_value);
}
}
}
//设定定时器
void InitTime(void)
{
TH0 = (65535 - 50000)/256;
TL0 = (65535 - 50000)%256 ;
TMOD = 0X01;
TR0 = 1;
ET0 = 1;
EA = 1;
}
//数码管显示函数
void SMG_Display(uint value)
{
uchar ge, bai, shi;
ge = value % 10;
shi = value % 100 / 10;
bai = value % 1000 / 100;
wela=1;
P0 = 0XFE;
wela=0;
P0 = 0XFF;
dula=1;;
P0 = array[bai];
dula=0;
Delay_1ms(2);
wela=1;
P0 = 0XFD;
wela=0;
P0 = 0XFF;
dula=1;
P0 = array[shi];
P0 |= 0x80; /*显示小数点*/
dula=0;
Delay_1ms(2);
wela=1;
P0 = 0XFB;
wela=0;
P0 = 0XFF;
dula=1;
P0 = array[ge];
dula=0;
Delay_1ms(2);
}
//中断函数
void timer(void) interrupt 1
{
TH0 = (65535 - 50000)/256;
TL0 = (65535 - 50000)%256;
flag++;
}
展开全部
#define DATA P1_1
#define SCK P1_0
#define ACK 1
#define noACK 0
#define MEASURE_TEMP 0x03 //测量温度命令
#define MEASURE_HUMI 0x05 //测量湿度命令
//读温湿度数据
char s-measure(unsigned char *p- value, un-signed char *p_checksum, unsigned char mode)
{
unsigned char error=0;
unsigned int i;
s_transstart(); //传输开始
switch(mode){
case
TEMP:error+=s_write_byte(measure_temp);
break;
case
HUMI:error+=s_write_byte(measure_humi);break;
default:break;
}
for(i=0;i<65535;i++) if(DATA==0) break;
if (DATA) reeor+=1;
*(p_value)=s_read_byte(ACK);
*(p_value+1)=s_read_byte(ACK);
*p_checksum=s_read_byte(noACK);
return error;
}
//温湿度值标度变换及温度补偿
void calc_sth15(float *p_humidity,float *p_tempera-ture)
{
const float c1=-4.0;
const float c2=0.0405;
const float c3=-0.0000028;
const float t1=-0.01;
const float t2=0.00008;
float rh=×p_humidity;
float t=×p_temperature;
float rh_lin;
float th_ture;
float t_c;
t_c=t×0.01-40;
rh_lin=c3×rh×rh+c2×rh+c1;
trh_ture=(t_c-25)×(t1+t2×rh)+rh_lin;
×p_temperature=t-c;
×p_humidity=rh_ture;
}
//从相对温度和湿度计算露点
char calc_dewpoint(float h,float t)
{float logex,dew_point;
logex=0.66077+7.5×t/(237.3+t)+[log10(h)-2];
dew_point=(logex-0.66077)×237.3/(0.66077+7.5-logex);
return dew_point;
}
#define SCK P1_0
#define ACK 1
#define noACK 0
#define MEASURE_TEMP 0x03 //测量温度命令
#define MEASURE_HUMI 0x05 //测量湿度命令
//读温湿度数据
char s-measure(unsigned char *p- value, un-signed char *p_checksum, unsigned char mode)
{
unsigned char error=0;
unsigned int i;
s_transstart(); //传输开始
switch(mode){
case
TEMP:error+=s_write_byte(measure_temp);
break;
case
HUMI:error+=s_write_byte(measure_humi);break;
default:break;
}
for(i=0;i<65535;i++) if(DATA==0) break;
if (DATA) reeor+=1;
*(p_value)=s_read_byte(ACK);
*(p_value+1)=s_read_byte(ACK);
*p_checksum=s_read_byte(noACK);
return error;
}
//温湿度值标度变换及温度补偿
void calc_sth15(float *p_humidity,float *p_tempera-ture)
{
const float c1=-4.0;
const float c2=0.0405;
const float c3=-0.0000028;
const float t1=-0.01;
const float t2=0.00008;
float rh=×p_humidity;
float t=×p_temperature;
float rh_lin;
float th_ture;
float t_c;
t_c=t×0.01-40;
rh_lin=c3×rh×rh+c2×rh+c1;
trh_ture=(t_c-25)×(t1+t2×rh)+rh_lin;
×p_temperature=t-c;
×p_humidity=rh_ture;
}
//从相对温度和湿度计算露点
char calc_dewpoint(float h,float t)
{float logex,dew_point;
logex=0.66077+7.5×t/(237.3+t)+[log10(h)-2];
dew_point=(logex-0.66077)×237.3/(0.66077+7.5-logex);
return dew_point;
}
参考资料: http://www.elecfans.com/article/82/2006/20060311141.html
本回答被提问者采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
你好!
我的博客里有<<SHT11温度湿度传感器的详细资料包获C代码和使用方法>>
请留下邮箱!
我的博客里有<<SHT11温度湿度传感器的详细资料包获C代码和使用方法>>
请留下邮箱!
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询