求基于AT89C51单片机和DS18B20温度传感器和HS1101湿度传感器、Led显示的温湿度检测系统的汇编源程序代码

求基于AT89C51单片机和DS18B20温度传感器和HS1101湿度传感器、Led显示的温湿度检测系统的汇编源程序代码,第1张

A_BIT EQU 20H

B_BIT EQU 21H

FLAG EQU 38H

DQEQU P3.3

MAIN:

ACALL RE_TEMP

ACALL TURN

ACALL DISPLAY

JMP MAIN

RE_TEMP:

SETB DQ

ACALL RESET_1820

JB FLAG,ST

ST:

MOV A,#0CCH

ACALL WRITE_1820

MOV A,#44H

ACALL WRITE_1820

ACALL RESET_1820

MOV A,#0CCH

ACALL WRITE_1820

MOV A,#0BEH

ACALL WRITE_1820

ACALL READ_1820

RET

RESET_1820:

SETB DQ

NOP

CLR DQ

MOV R1,#3

DLY: MOV R0,#107

DJNZ R0,$

DJNZ R1,DLY

SETB DQ

NOP

NOP

NOP

MOV R0,#25

T2: JNB DQ,T3

DJNZ R0,T2

JMP T4

T3: SETB FLAG

JMP T5

T4: CLR FLAG

JMP T7

T5: MOV R0,#117

DJNZ R0,$

T7: SETB DQ

RET

WRITE_1820:

MOV R2,#8

CLR C

WR1: CLR DQ

MOV R3,#7

DJNZ R3,$

RRC A

MOV DQ,C

MOV R3,#23

DJNZ R3,$

SETB DQ

NOP

DJNZ R2,WR1

SETB DQ

RET

READ_1820:

MOV R4,#2

MOV R1,#29H

RE0: MOV R2,#8

RE1: CLR C

SETB DQ

NOP

NOP

CLR DQ

NOP

NOP

NOP

SETB DQ

MOV R3,#9

RE2: DJNZ R3,RE2

MOV C,DQ

MOV R3,#23

RE3: DJNZ R3,RE3

RRC A

DJNZ R2,RE1

MOV @R1,A

DEC R1

DJNZ R4,RE0

RET

TURN: MOV A,29H

MOV C,40H

RRC A

MOV C,41H

RRC A

MOV C,42H

RRC A

MOV C,43H

RRC A

MOV 29H,A

DISPLAY:

MOV A,29H

MOV B,#10

DIV AB

MOV B_BIT,A

MOV A_BIT,B

MOV R0,#4

DP1: MOV R1,#250

LOOP: MOV DPTR,#TABLE

MOV A,A_BIT

MOVC A,@A+DPTR

MOV P2,A

MOV P1,#0F7H

ACALL DELAY

MOV A,B_BIT

MOVC A,@A+DPTR

MOV P2,A

MOV P1,#0F6H

ACALL DELAY

DJNZ R1,LOOP

DJNZ R0,DP1

RET

DELAY:

MOV R7,#122

DJNZ R7,$

RET

TABLE:

DB 3FH,06H,5BH,4FH

DB 66H,6DH,7DH,07H,7FH

END

这个程序是DS18B20检测温度后,通过单片机驱动数码管显示,也就是你要求的LED显示。至于HS1101也特别简单我就不写了,我是无意中看到你的问题的,正好我以前也写过这个,我就回答了。我做单片机开发已经很多年了,针对这个程序给你几个建议:1用C语言写,简单、直观、可移植性好。2把DS18B20先搞出来,然后再把HS1101搞出来,然后整合。(当然,我已经给你了DS18B20的程序了)。顺便给你把C语言的也贴出来吧:#include <reg52.h>

#include <intrins.h>

#define uchar unsigned char

#define uint unsigned int

sbit DS=P3^3 //定义DS18B20接口

int temp

uchar flag1

void display(unsigned char *lp,unsigned char lc)//数字的显示函数;lp为指向数组的地址,lc为显示的个数

void delay()//延时子函数,5个空指令

code unsigned char table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40,0x08,0x00}

//共阴数码管 0-9 - _ 空 表

unsigned char l_tmpdate[8]={0,0,10,0,0,0,0,0}//定义数组变量,并赋值1,2,3,4,5,6,7,8,就是本程序显示的八个数

int tmp(void)

void tmpchange(void)

void tmpwritebyte(uchar dat)

uchar tmpread(void)

bit tmpreadbit(void)

void dsreset(void)

void delayb(uint count)

void main() //主函数

{

uchar i

int l_tmp

while(1)

{

tmpchange() //温度转换

l_tmp=tmp()

if(l_tmp<0)

l_tmpdate[0]=10 //判断温度为负温度,前面加"-"

else

{

l_tmpdate[0]=temp/1000 //显示百位,这里用1000,是因为我们之前乖以10位了

if(l_tmpdate[0]==0)

l_tmpdate[0]=12//判断温度为正温度且没有上百,前面不显示

}

l_tmp=temp%1000

l_tmpdate[1]=l_tmp/100//获取十位

l_tmp=l_tmp%100

l_tmpdate[2]=l_tmp/10//获取个位

l_tmpdate[3]=11

l_tmpdate[4]=l_tmp%10//获取小数第一位

for(i=0i<10i++){ //循环输出10次,提高亮度

display(l_tmpdate,5)

}

}

}

void display(unsigned char *lp,unsigned char lc)//显示

{

unsigned char i //定义变量

P2=0 //端口2为输出

P1=P1&0xF8 //将P1口的前3位输出0,对应138译门输入脚,全0为第一位数码管

for(i=0i<lci++){ //循环显示

P2=table[lp[i]] //查表法得到要显示数字的数码段

delay()

delay()

delay()

delay()

delay()

delay()

delay()

delay()

delay()

delay()

delay()

delay() //延时5个空指令

if(i==7) //检测显示完8位否,完成直接退出,不让P1口再加1,否则进位影响到第四位数据

break

P2=0 //清0端口,准备显示下位

P1++ //下一位数码管

}

}

void delay(void) //空5个指令

{

_nop_()_nop_()_nop_()_nop_()_nop_()

}

void delayb(uint count) //delay

{

uint i

while(count)

{

i=200

while(i>0)

i--

count--

}

}

void dsreset(void) //DS18B20初始化

{

uint i

DS=0

i=103

while(i>0)i--

DS=1

i=4

while(i>0)i--

}

bit tmpreadbit(void) // 读一位

{

uint i

bit dat

DS=0i++ //小延时一下

DS=1i++i++

dat=DS

i=8while(i>0)i--

return (dat)

}

uchar tmpread(void) //读一个字节

{

uchar i,j,dat

dat=0

for(i=1i<=8i++)

{

j=tmpreadbit()

dat=(j<<7)|(dat>>1) //读出的数据最低位在最前面,这样刚好//一个字节在DAT里

}

return(dat)//将一个字节数据返回

}

void tmpwritebyte(uchar dat)

{ //写一个字节到DS18B20里

uint i

uchar j

bit testb

for(j=1j<=8j++)

{

testb=dat&0x01

dat=dat>>1

if(testb) // 写1部分

{

DS=0

i++i++

DS=1

i=8while(i>0)i--

}

else

{

DS=0 //写0部分

i=8while(i>0)i--

DS=1

i++i++

}

}

}

void tmpchange(void) //发送温度转换命令

{

dsreset()//初始化DS18B20

delayb(1)//延时

tmpwritebyte(0xcc) // 跳过序列号命令

tmpwritebyte(0x44) //发送温度转换命令

}

int tmp() //获得温度

{

float tt

uchar a,b

dsreset()

delayb(1)

tmpwritebyte(0xcc)

tmpwritebyte(0xbe) //发送读取数据命令

a=tmpread() //连续读两个字节数据

b=tmpread()

temp=b

temp<<=8

temp=temp|a//两字节合成一个整型变量。

tt=temp*0.0625 //得到真实十进制温度值,因为DS18B20

//可以精确到0.0625度,所以读回数据的最低位代表的是

//0.0625度。

temp=tt*10+0.5 //放大十倍,这样做的目的将小数点后第一位

//也转换为可显示数字,同时进行一个四舍五入 *** 作。

return temp//返回温度值

}

void readrom() //read the serial 读取温度传感器的序列号

{ //本程序中没有用到此函数

uchar sn1,sn2

dsreset()

delayb(1)

tmpwritebyte(0x33)

sn1=tmpread()

sn2=tmpread()

}

void delay10ms()

{

uchar a,b

for(a=10a>0a--)

for(b=60b>0b--)

}

  该电路采取HS1101和单片机555组成。

  HS1101的电容答模毁量和湿度(0~70%)的线性关系比较好,从70%~100%以后就有1~12%的偏差了清备。因为是用单码搏片机来实现,所以要用查表的方式,可以做到精度不小于1%。

HS1100/HS1101电容传感器,在电路构成中等效于一个电容器件,其电容量随着所测空气湿度的增大而增大。如何将电容的变化量准确地转变为计算机易于接受的信号,常有两种方法:一是将该湿敏电容置于运方与租蓉组成的桥式振荡电路中,所产生的正弦波电压信号经整绝耐流、直流放大、再A/D转换为数字信号;另一种是将该湿敏电容置于555振荡电路中,将电容值的变化转为与之成反比的电压频率信号,可直接被计算机所采集

频率输出的555测量振荡电路如图3-7所示。集成定时器555芯片外接电阻R4、R2与湿敏电容C,构成了对C的充电回路。7端通过芯片内部的晶体管对地短路又构成了对C的放电回路,并将引脚2、6端相连引入到片内比较器,便成为一个典型的多谐振荡器,即方波宏漏发生器。另外,R3 是防止输出短路的保护电阻,R1 用于平衡温度系数。

图3-7、频率输出的555振荡电路

该振荡电路两个暂稳态的交替过程如下:首先电源Vs通过R4、R2 向C充电,经t充电时间后,Uc达到芯片内比较器的高触发电平,约0.67Vs,此时输出引脚3端由高电平突降为低电平,然后通过R2放电,经t放电时间后,Uc下降到比较器的低触发电平,约0.33Vs

此时输出,此时输出引脚3端又由低电平突降为高电平,如此翻来覆去,形成方波输出。其中,充放电时间为

   t充电=C(R4+R2)Ln2

   t放电=CR2 Ln2

因而,输出的方波频率为

f=1/(t放电+t充电)=1/[ C(R4+R2)Ln2]

可见,空气湿度通过555测量电路就转变为与蔽宏烂之呈反比的频率信号,表3-1给出了其中的一组典型测试值。

表3-1、空气湿度与电压频率的典型值


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

原文地址:https://54852.com/yw/12374160.html

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

发表评论

登录后才能评论

评论列表(0条)

    保存