stc90c51单片机开发板和sht11温湿度传感器连接测量温湿度的具体程序

stc90c51单片机开发板和sht11温湿度传感器连接测量温湿度的具体程序,第1张

#include<reg52.h>

#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),你可以参考一下啊!!!!


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/7768356.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-09
下一篇 2023-04-09

发表评论

登录后才能评论

评论列表(0条)

保存