#define uchar unsigned char
#define uint unsigned int
uint hum,temp,i //定义湿度、温度(全局)
uchar hum_h,hum_l,temp_h,temp_l,check,cnt=0 //湿度高、低8位,温度高、低8位,校验位
uchar bai,shi,ge,bai1,shi1,ge1//数码管 ,cnt=0
uchar code table[]={0xfb,0xfd,0xfe}//位选数组
uchar code table1[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f} //无小数点
uchar code table2[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef} //有小数点
sbit dht=P2^4
/******************************
邮保╱s级)函数
******************************/
void delay_us(uint i)
{
while(i--)
}
/******************************
延时(ms级)函数
******************************/
void delay(uint z)
{
uint x,y
for (x=zx>0x--)
for(y=100y>0y--)
}
/***********************************
温湿度初始化(准备传送数据)函数
***********************************/
void dht_init()
{
dht=0
delay_us(50)//拉低延时500微秒,发送开始信号
dht=1 //释放总线,延时30微秒
delay_us(4)
while(!dht)//拉低等待
while(dht)// 拉高等待,即将传送数据
}
/************************************
读取字节函数
************************************/
uchar read_byte()
{
uchar n,byte=0,dat
for(n=0n<8n++)
{
while(!dht)
delay_us(4) //理论上28us<延时<70us,此处写2--6都可以
dat=0
if(dht)
dat=1
while(dht)
byte<<=1
byte|=dat
}
return byte
}
/********************************
读40位数据函数
********************************/
void read_hum_temp()
{
dht_init()
hum_h=read_byte() //读湿度
hum_l=read_byte()
temp_h=read_byte()//读温度
temp_l=read_byte()
check=read_byte()//读校验
while(!dht)// 等待低电平结束
dht=1 //最后拉高总线
}
/************************************
数据转化函数
提取各位数字
************************************/
void zhuanhuan()
{
uchar a
a=hum_h+hum_l+temp_h+temp_l
if(a==check)
{
hum=temp=0
hum=((hum|hum_h)<<8)|hum_l
temp=((temp|temp_h)<<8)|temp_l
bai=temp/100
shi=temp%100/10
ge=temp%10
bai1=hum/100
shi1=hum%100/10
ge1=hum%10
}
else bai=shi=ge=bai1=shi1=ge1=0
}
void saomiao1()//温度
{
P2=table[0]
P0=table1[ge]
delay(1)
P0=0X00
P2=table[1]
P0=table2[shi]
delay(1)
P0=0X00
P2=table[2]
P0=table1[bai]
delay(1)
P0=0X00
}
void saomiao2()//湿度
{
P2=table[0]
P0=table1[ge1]
delay(1)
P2=table[1]
P0=table2[shi1]
delay(1)
P2=table[2]
P0=table1[bai1]
delay(1)
}
//===================================================
void main()
{
delay(200)
while(1)
{
read_hum_temp()
zhuanhuan()
for(i=0i<1500i++)
{
saomiao1()
}
delay(500)
}
}
#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++
}
#include<reg51.h>#define uchar unsigned char
#define uint unsigned int
sbit DQ=P3^7//ds18b20与单片机连接口
sbit RS=P3^0
sbit RW=P3^1
sbit EN=P3^2
unsigned char code str1[]={"temperature: "}
unsigned char code str2[]={" "}
uchar data disdata[5]
uint tvalue//温度值
uchar tflag//温度正负标志
/*************************lcd1602程序**************************/
void delay1ms(unsigned int ms)//延时1毫秒(不够精确的)
{unsigned int i,j
for(i=0i<msi++)
for(j=0j<100j++)
}
void wr_com(unsigned char com)//写指令//
{ delay1ms(1)
RS=0
RW=0
EN=0
P2=com
delay1ms(1)
EN=1
delay1ms(1)
EN=0
}
void wr_dat(unsigned char dat)//写数据//
{ delay1ms(1)
RS=1
RW=0
EN=0
P2=dat
delay1ms(1)
EN=1
delay1ms(1)
EN=0
}
void lcd_init()//初始化设置//
{delay1ms(15)
wr_com(0x38)delay1ms(5)
wr_com(0x08)delay1ms(5)
wr_com(0x01)delay1ms(5)
wr_com(0x06)delay1ms(5)
wr_com(0x0c)delay1ms(5)
}
void display(unsigned char *p)//显示//
{
while(*p!='\0')
{
wr_dat(*p)
p++
delay1ms(1)
}
}
init_play()//初始化显示
{ lcd_init()
wr_com(0x80)
display(str1)
wr_com(0xc0)
display(str2)
}
/******************************ds1820程序***************************************/
void delay_18B20(unsigned int i)//延时1微秒
{
while(i--)
}
void ds1820rst()/*ds1820复位*/
{ unsigned char x=0
DQ = 1 //DQ复位
delay_18B20(4) //延时
DQ = 0 //DQ拉低
delay_18B20(100)//精确延时大于480us
DQ = 1 //拉高
delay_18B20(40)
}
uchar ds1820rd()/*读数据*/
{ unsigned char i=0
unsigned char dat = 0
for (i=8i>0i--)
{ DQ = 0//给脉冲信号
dat>>=1
DQ = 1//给脉冲信号
if(DQ)
dat|=0x80
delay_18B20(10)
}
return(dat)
}
void ds1820wr(uchar wdata)/*写数据*/
{unsigned char i=0
for (i=8i>0i--)
{ DQ = 0
DQ = wdata&0x01
delay_18B20(10)
DQ = 1
wdata>>=1
}
}
read_temp()/*读取温度值并转换*/
{uchar a,b
ds1820rst()
ds1820wr(0xcc)//*跳过读序列号*/
ds1820wr(0x44)//*启动温度转换*/
ds1820rst()
ds1820wr(0xcc)//*跳过读序列号*/
ds1820wr(0xbe)//*读取温度*/
a=ds1820rd()
b=ds1820rd()
tvalue=b
tvalue<<=8
tvalue=tvalue|a
if(tvalue<0x0fff)
tflag=0
else
{tvalue=~tvalue+1
tflag=1
}
tvalue=tvalue*(0.625)//温度值扩大10倍,精确到1位小数
return(tvalue)
}
/*******************************************************************/
void ds1820disp()//温度值显示
{ uchar flagdat
disdata[0]=tvalue/1000+0x30//百位数
disdata[1]=tvalue%1000/100+0x30//十位数
disdata[2]=tvalue%100/10+0x30//个位数
disdata[3]=tvalue%10+0x30//小数位
if(tflag==0)
flagdat=0x20//正温度不显示符号
else
flagdat=0x2d//负温度显示负号:-
if(disdata[0]==0x30)
{disdata[0]=0x20//如果百位为0,不显示
if(disdata[1]==0x30)
{disdata[1]=0x20//如果百位为0,十位为0也不显示
}
}
wr_com(0xc0)
wr_dat(flagdat)//显示符号位
wr_com(0xc1)
wr_dat(disdata[0])//显示百位
wr_com(0xc2)
wr_dat(disdata[1])//显示十位
wr_com(0xc3)
wr_dat(disdata[2])//显示个位
wr_com(0xc4)
wr_dat(0x2e)//显示小数点
wr_com(0xc5)
wr_dat(disdata[3])//显示小数位
}
/********************主程序***********************************/
void main()
{ init_play()//初始化显示
while(1)
{read_temp()//读取温度
ds1820disp()//显示
}
}
这个是测温度的(18b20),你可以参考一下啊!!!!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)