基于单片机的温湿度采集与控制程序(C语言)

基于单片机的温湿度采集与控制程序(C语言),第1张

给你一个DS18B20的温度采集程序!

//ICC-AVR application builder : 2009-10-25 10:43:39

// Target : M16

// Crystal: 16000Mhz

#include <iom16vh>

#include <macrosh>

#define uint unsigned int

#define uchar unsigned char

#include "xianshic"

#include "delayh"

#define CLR_DIR_1WIRE DDRD&=~BIT(4) //只要修改这里的参数就可以了

#define SET_DIR_1WIRE DDRD|=BIT(4) //里面什么都不用该!

#define CLR_OP_1WIRE PORTD&=~BIT(4)

#define SET_OP_1WIRE PORTD|=BIT(4)

#define CHECK_IP_1WIRE (PIND&0x10) //检测

unsigned char wmh,wml;

void init_1820()

{

SET_DIR_1WIRE; //设置PD4 为输出

SET_OP_1WIRE;

CLR_OP_1WIRE;

delay_nus(480); //480us以上

SET_OP_1WIRE;

CLR_DIR_1WIRE;

delay_nus(20); //15~60us

while(CHECK_IP_1WIRE);

SET_DIR_1WIRE;

SET_OP_1WIRE;

delay_nus(140); //60~240us

}

void write_1820(unsigned char x)

{

unsigned char m;

for(m=0;m<8;m++)

{

CLR_OP_1WIRE;

if(x&(1<<m)) //写数据了,先写低位的!

SET_OP_1WIRE;

else

{CLR_OP_1WIRE;}

delay_nus(40); //15~60us

SET_OP_1WIRE;

}

SET_OP_1WIRE;

}

unsigned char read_1820()

{

unsigned char temp,k,n;

temp=0;

for(n=0;n<8;n++)

{

CLR_OP_1WIRE;

SET_OP_1WIRE;

CLR_DIR_1WIRE;

k=(CHECK_IP_1WIRE); //读数据,从低位开始

if(k)

temp|=(1<<n);

else

temp&=~(1<<n);

delay_nus(50); //60~120us

SET_DIR_1WIRE;

}

return (temp);

}

unsigned int gettemp() //读取温度值

{

unsigned char temh,teml,wm0,wm1,wm2,wm3;

init_1820(); //复位18b20

write_1820(0xcc); // 发出转换命令

write_1820(0x44);

// delay_nms(800); //不延时也好使,不知道怎么回事!

init_1820();

write_1820(0xcc); //发出读命令

write_1820(0xbe);

teml=read_1820(); //读数据

temh=read_1820();

wm0=teml>>4; //只要高8位的低四位和低8位的高四位,温度范围0~99啦!

wm1=temh<<4;

wm2=wm1+wm0; //16进制转10进制

return wm2;

}

void main()

{

uint tem,ad[4],i;

port_init();

while(1)

{

tem = gettemp();

for(i=0;i<4;i++)

{

ad[3-i]=tem%10;

tem=tem/10;

}

for(i=0;i<4;i++)

{

show1(ad[i],i);

delay(5);

}

}

}

显示函数:

#include <iom16vh>

#include <macrosh>

#define uint unsigned int

#define uchar unsigned char

#pragma data:code

const uint tab1[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,

0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E,0x00}; //共阳数码管代码表

const uint tab2[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,

0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0X00};//共阴数码管代码表

void port_init(void)

{

DDRA = 0xFF;

DDRB = 0xFF;

DDRC = 0xFF;

DDRD = 0x00;

}

void delay(uint ms)

{

uint i,j;

for(i=0;i<ms;i++)

{

for(j=0;j<1141;j++);

}

}

void show1(uchar j,uchar k)//显示函数

{

PORTB = ~BIT(k);

PORTA = tab2[j];

delay(1);

}

void show(uint ada)

{

uint i,ad[4];

for(i=0;i<4;i++)

{

ad[3-i]=ada%10;

ada = ada/10;

}

while(1)

{

for(i=0;i<4;i++)

{

show1((ad[i]),i);

delay(100);

}

}

}

程序我都调试过的,都是好的,有不会再问我。可以给分了吗?嘿嘿

这是我自己用过的DS18B20的程序,有什么问题可以百度HI我,我这个是把温度显示到电脑上了,如果你要显示到LCD上的话可以在里面加一些子程序

#include<reg52h>

#include<stdioh>

#define uint unsigned int

#define uchar unsigned char

sbit ds=P1^0;

bit flag;

uchar count_t0;

float f_temp;

void delay(uint z)

{

uint x,y;

for(x=z;x>0;x--)

for(y=122;y>0;y--);

}

void init() // 串口初始化

{

TMOD=0x21;

SCON=0x50;

TH0=0x4c;

TL0=0x00;

TH1=0xf3;

TL1=0xf3;

EA=1;

ET0=1;

TR0=1;

TR1=1;

}

void timer0() interrupt 1

{

TH0=0x4c;

TL0=0x00;

if(++count_t0>=20)

{

count_t0=0;

flag=1;

}

}

void dsreset()

{

uint i;

ds=0;

i=103;

while(i>0)

i--;

ds=1;

i=4;

while(i>0)

i--;

}

bit read_bit()

{

uint i;

bit dat;

ds=0;i++;

ds=1;i++;i++;

dat=ds;

i=8;

while(i>0)

i--;

return dat;

}

uchar read_byte()

{

uchar i,j,dat;

dat=0;

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

{

j=read_bit();

dat=(j<<7)|(dat>>1);

}

return dat;

}

void write_byte(uchar dat)

{

uint i;

uchar j;

bit testb;

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

{

testb=dat&0x01;

dat=dat>>1;

if(testb)

{

ds=0;

i++;i++;

ds=1;

i=8;

while(i>0)

i--;

}

else

{

ds=0;

i=8;

while(i>0)

i--;

ds=1;

i++;i++;

}

}

}

void begin_change()

{

dsreset();

delay(1);

write_byte(0xcc);

write_byte(0x44);

}

float get_temp()

{

uchar a,b;

uint temp;

float f_temp;

dsreset();

delay(1);

write_byte(0xcc);

write_byte(0xbe);

a=read_byte();

b=read_byte();

temp=b;

temp<<=8;

temp=temp|a;

f_temp=temp00625;

temp=f_temp10+05;

f_temp=f_temp+005;

return f_temp;

}

void main()

{

init();

while(1)

{

if(flag==1)

{

flag=0;

begin_change();

TI=1;

printf("The tempeature is %f\n",get_temp());

while(!TI);

TI=0;

}

}

}

0KG 0000H

AJMP MAIN

;单片机内存分配申明!

TEMPER— L EOU 29H :用于保存读出温度的低8位

TEMPER— H EOU 28H :用于保存读出温度的高8位

FLAG1 EOU 38H ;是否检测到DS18B20标志位

PNFLAG EOU 68H :数据正负标志位

A

— BIT EQU 20H :数码管个位数存放内存位置

B—

BIT EOU 21H :数码管十位数存放内存位置

C

— BIT EOU 22H :数码管小数位数存放内存位置

T

— INTEGER EOU 26H :FORMAT后的整数部分

(integer),将两字节的温度整合成1字节

T—

DF EOU 27H :FORMAT后的小数部分(decimal

fraction),半字节的温度小数(存在低四位)

MAIN:

LCALL GET— TEMPER :调用读温度子程序

LCALL T— FORMAT:将读出的2字节温度格式化

LCALL ALARM :调用报警子程序

LCALL DISPLAY :调用数码管显示子程序

LCALL D1S:延时0.5秒后再测

AJMP MAIN

:这是DS18B20复位初始化子程序

INIT

1820: SETB P3.5

NOP

CLR P3.5

:主机发出延时537微秒的复位低脉冲

MOV R1.#2

TSR1: MOV RO.#250

DJNZ RO,$

DJNZ R1,TSR1

SETB P3.5 :然后拉高数据线

NOP

NOP

NOP

MOV RO.#25H

TSR2: JNB P3.5,TSR3 :等待DS18B20回应

DJNZ RO,TSR2 :延时

LJMP TSR4

TSR3: SETB FLAG1 :置标志位,表示DS1820存在

LJMP TSR5

TSR4: CLR FLAG1:清标志位,表示DS1820不存在

LJMP TSR7

TSR5: MOV RO,#120

TSR6: DJNZ RO,TSR6 :时序要求延时一段时间

TSR7: SETB P3.5

RFT

:读出转换后的温度值

GET TEMPER: :SETB P3.5

LCALL INIT

一1820 :先复位DS18B20

JB FLAG1,TSS2

RET :判断DS1820是否存在若DS18B20不存在

则返回

TSS2: MOV A,#OCCH :跳过ROM匹配

LCALL WRITE 1820

MOV A,#44H :发出温度转换命令

LCALL WRITE— — 1820

LCALL DISPLAY

LCALL INIT

一1820 :准备读温度前先复位

MOV A,#OCCH :跳过ROM匹配

LCALL WRITE l820

MOV A,#OBEH :发出读温度命令

LCALL WRITE 1820

LCALL READ

一18200 :将读出的温度数据保存到

28H/29H

RET

:写DS18B20的子程序(有具体的时序要求)

WRITE

一1820:MOV R2,#8 :一共8位数据

:CLR C

WR1: CLR P3.5

MOV R3.#6

DJNZ R3,$

RRC A

MOV P3.5,C

MOV R3.#23

DJNZ R3,$

SETB P3.5

NOP

DJNZ R2,WR1

SETB P3.5

RET

;读DS18B20的程序,从DS18B20中读出两个字节的温

度数据

READ一 18200:MOV 36H,#2 :将温度高位和低位

从DS18B20中读出

MOV R1,#29H :低位存人29H(TEMPER—L),高位

存人28H(TEMPER—H)

REO0: MOV R2,#8 :数据一共有8位

REO1: :CLR C

SETB P3.5

NOP

NOP

CLR P3.5

NOP

NOP

NOP

SETB P3.5

MOV R3.#9

RE10: DJNZ R3,RE10

MOV C.P3.5

MOV R3.#23

RE20: DJNZ R3,RE20

RRC A

DJNZ R2,REO1

MOV @R1.A

DEC Rl

DJNZ 36H,REO0

RET

⋯ 一整合读出的两字节温度(关于DS18B20读出的

2字节温度格式请参考资料)______⋯ 一

T FORMAT:

报警子程序

ALARM:

:显示子程序

DISPLAY:

:1MS延时(按12MHZ算)

D1MS: MOV R7.#250

11mm:nop

nop

DJNZ R7,11mm

RET

:1MS延时(按12MHZ算)

D1S: Mov R6.#4

LOOP2: mov R5,#l25: 一一---一一一一一一~ 250

LOOP1: LCALL D1mS

DJNZ R5,LOOP1

DJNZ R6,LOOP2

RET

:7段数码管0~9数字的共阳显示代码

NUMTAB: DB

OCOH,Of9H,Oa4H,ObOH,99H,92H,82H,Of8H,80H,90H

, 0ffH

XIAOSHU:DB

OOH,01H,01H,02H,03H,03H,04H,04H,05H,06H,06H,

07H,08H,08H,09H,09H

END

应用时直接调用发送接收子程就够了,数据处理可以用周航慈编制的

浮点数运算子程,很好用

以上就是关于基于单片机的温湿度采集与控制程序(C语言)全部的内容,包括:基于单片机的温湿度采集与控制程序(C语言)、51单片机系列温度采集LCD162显示温度系统C程序、做过DS18B20温度采集的请help me等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

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

原文地址: http://outofmemory.cn/zz/10121943.html

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

发表评论

登录后才能评论

评论列表(0条)

保存