/***********************************************
// //
// 以下为SHT75驱动程序 //
// //
***********************************************/
#include <string.h>
#include <stdlib.h>
#include <absacc.h>
#include <intrins.h>
/*******************宏定义部分*****************/
sfr P4 = 0xc0
sfr WDT_CONTR = 0xc1
#define Measure_TEMP 0x03 //温度
#define Measure_HUMI 0x05 //湿度
sbit TH_SCK = P3^6
sbit TH_DAT = P3^7
unsigned char TH_Array[3]
bit Error
/*****************************************************
函数功能:SHT75启动传输
入口参数:无
出口参数:无
***************************************************/
void Start(void)
{
TH_SCK = 1 //拉高SCK
TH_DAT = 0 //拉低DAT
_nop_() //短时间延时,给硬件反应时间
TH_SCK = 0 //拉低SCK
_nop_()_nop_()_nop_() //短时间延时,给硬件反应时间
TH_SCK = 1 //上拉SCK
TH_DAT = 1 //上拉DAT
_nop_() //短时间延时,给硬件反应时间
TH_SCK = 0 //拉低SCK
}
/*****************************************************
函数功能:向SHT75中写入一个数据
入口参数:Value
出口参数:Error
***************************************************/
void Write_Byte(unsigned char Value)
{
unsigned char i
for (i = 0x80i >0i /= 2) //8 个SCK 时钟的下降沿
{
if (i &Value)
TH_DAT = 1
else
TH_DAT = 0
TH_SCK = 1
_nop_()_nop_()_nop_()
TH_SCK = 0
} // 在第8 个SCK 时钟的下降沿之后,将DATA 下拉低电平,
// 在第9 个SCK 时钟的下降沿之后,释放DATA(恢复高电平)。
TH_DAT = 1
TH_SCK = 1
Error = TH_DAT//读SHT75的应答
TH_SCK = 0//第九脉冲后上拉数据线
//return Error//为1就错
}
/*****************************************************
函数功能:向SHT75中读入一个数据
入口参数:无
出口参数:val
***************************************************/
unsigned char Read_Byte (bit ack)
{
unsigned char i,val = 0
TH_DAT = 1
for (i = 0x80i >0i /= 2)
{
TH_SCK = 1
if (TH_DAT) val = (val | i)
TH_SCK = 0
}
TH_DAT = !ack//MCU要在每个字节后应答SHT75
TH_SCK = 1
_nop_()_nop_()_nop_()
TH_SCK = 0
TH_DAT = 1
return val
}
/*****************************************************
函数功能:温度湿度测试
入口参数:无
出口参数:无
***************************************************/
void Measure(unsigned char Mode)
{
unsigned int Wait_i
Start() //初始化启动时序
switch(Mode)
{
case 0x00:
Write_Byte(Measure_TEMP)
break //0x00:温度测试
case 0x01:
Write_Byte(Measure_HUMI)
break //0x01:湿度测试
default: break
}
for (Wait_i = 0Wait_i <65535Wait_i++)
{
WDT_CONTR = 0x35
if(TH_DAT == 0)
break//延时等待转换完成
}
if(Wait_i == 0xffff)
{
Error = 1
return
}
TH_Array[0] = Read_Byte(1)
TH_Array[1] = Read_Byte(1)
TH_Array[2] = Read_Byte(0)
}
/*****************************************************
函数功能:温度湿度补偿
入口参数:无
出口参数:TH_Result_Bk
***************************************************/
unsigned int Calc_SHT90(void)
{
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_lin
float rh_ture
float t_c
unsigned int Temp_T
unsigned int Temp_H
unsigned char T_End // 最后 温度
unsigned char H_End //最后 湿度
unsigned int TH_Result
unsigned int TH_Result_Bk//最后温度,湿度
Error = 0
Measure(0x00)//温度
memcpy(&Temp_T,TH_Array,2)
Measure(0x01)//湿度
memcpy(&Temp_H,TH_Array,2)
if(Error)
return(TH_Result_Bk)
t_c = Temp_T * 0.01 - 40 + 128 //温度
rh_lin = c2 * Temp_H - c3 * Temp_H * Temp_H - c1 //相对湿度
rh_ture = (t_c - 25 - 128) * (t1 + t2 * Temp_H) + rh_lin// 相对湿度对于温度依赖性的补偿
T_End = t_c//保存温度
H_End = rh_ture//保存湿度
TH_Result = 0
TH_Result = T_End
TH_Result = TH_Result <<8 //读高8位温度数据
TH_Result = TH_Result + H_End // 读低8位湿度数据
TH_Result_Bk = TH_Result //最后高8位温度,低8位湿度
return(TH_Result)//高8位温度,低8位湿度
}
#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 = msx >0x--)
{
for(y = 124y >0y--)
}
}
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 = 8i >0i--)
{
//高位在先
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 = 0i <SIZEi++)
{
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++
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)