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

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

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

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

// Target : M16

// Crystal: 16.000Mhz

#include <iom16v.h>

#include <macros.h>

#define uint unsigned int

#define uchar unsigned char

#include "xianshi.c"

#include "delay.h"

#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=0m<8m++)

{

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=0n<8n++)

{

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=0i<4i++)

{

ad[3-i]=tem%10

tem=tem/10

}

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

{

show1(ad[i],i)

delay(5)

}

}

}

显示函数

#include <iom16v.h>

#include <macros.h>

#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=0i<msi++)

{

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

}

}

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

{

PORTB = ~BIT(k)

PORTA = tab2[j]

delay(1)

}

void show(uint ada)

{

uint i,ad[4]

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

{

ad[3-i]=ada%10

ada = ada/10

}

while(1)

{

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

{

show1((ad[i]),i)

delay(100)

}

}

}

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

/********************************************************************

*

文件名

温度采集DS18B20.c

*

描述

:

该文件实现了用温度传感器件DS18B20对温度的采集,并在数码管上显示出来。

*

创建人

东流,2009年4月10日

*

版本号

2.0

***********************************************************************/

#include<reg52.h>

#define

uchar

unsigned

char

#define

uint

unsigned

int

#define

jump_ROM

0xCC

#define

start

0x44

#define

read_EEROM

0xBE

sbit

DQ

=

P2^3

//DS18B20数据口

unsigned

char

TMPH,TMPL

uchar

code

table[10]

=

{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}

/********************************************************************

*

名称

:

delay()

*

功能

:

延时,延时时间大概为140US。

*

输入

:

*

输出

:

***********************************************************************/

void

delay_1()

{

int

i,j

for(i=0

i<=10

i++)

for(j=0

j<=2

j++)

}

/********************************************************************

*

名称

:

delay()

*

功能

:

延时函数

*

输入

:

*

输出

:

***********************************************************************/

void

delay(uint

N)

{

int

i

for(i=0

i<N

i++)

}

/********************************************************************

*

名称

:

Delay_1ms()

*

功能

:

延时子程序,延时时间为

1ms

*

x

*

输入

:

x

(延时一毫秒的个数)

*

输出

:

***********************************************************************/

void

Delay_1ms(uint

i)//1ms延时

{

uchar

x,j

for(j=0j<ij++)

for(x=0x<=148x++)

}

/********************************************************************

*

名称

:

Reset()

*

功能

:

复位DS18B20

*

输入

:

*

输出

:

***********************************************************************/

uchar

Reset(void)

{

uchar

deceive_ready

DQ

=

0

delay(29)

DQ

=

1

delay(3)

deceive_ready

=

DQ

delay(25)

return(deceive_ready)

}

/********************************************************************

*

名称

:

read_bit()

*

功能

:

从DS18B20读一个位值

*

输入

:

*

输出

:

从DS18B20读出的一个位值

***********************************************************************/

uchar

read_bit(void)

{

uchar

i

DQ

=

0

DQ

=

1

for(i=0

i<3

i++)

return(DQ)

}

/********************************************************************

*

名称

:

write_bit()

*

功能

:

向DS18B20写一位

*

输入

:

bitval(要对DS18B20写入的位值)

*

输出

:

***********************************************************************/

void

write_bit(uchar

bitval)

{

DQ=0if(bitval==1)

DQ=1

delay(5)

DQ=1

}

/********************************************************************

*

名称

:

read_byte()

*

功能

:

从DS18B20读一个字节

*

输入

:

*

输出

:

从DS18B20读到的值

***********************************************************************/

uchar

read_byte(void)

{

uchar

i,m,receive_data

m

=

1

receive_data

=

0

for(i=0

i<8

i++)

{

if(read_bit())

{

receive_data

=

receive_data

+

(m

<<

i)

}

delay(6)

}

return(receive_data)

}

/********************************************************************

*

名称

:

write_byte()

*

功能

:

向DS18B20写一个字节

*

输入

:

val(要对DS18B20写入的命令值)

*

输出

:

***********************************************************************/

void

write_byte(uchar

val)

{

uchar

i,temp

for(i=0

i<8

i++)

{

temp

=

val

>>

i

temp

=

temp

&

0x01

write_bit(temp)

delay(5)

}

}

/********************************************************************

*

名称

:

Main()

*

功能

:

主函数

*

输入

:

*

输出

:

***********************************************************************/

void

main()

{

float

tt

uint

temp

P2

=

0x00

while(1)

{

Reset()

write_byte(jump_ROM)

write_byte(start)

Reset()

write_byte(jump_ROM)

write_byte(read_EEROM)

TMPL

=

read_byte()

TMPH

=

read_byte()

temp

=

TMPL

/

16

+

TMPH

*

16

P0

=

table[temp/10%10]

P2

=

6

Delay_1ms(5)

P0

=

table[temp%10]

P2

=

7

Delay_1ms(5)

}

}

#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++

}


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

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

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

发表评论

登录后才能评论

评论列表(0条)

    保存