跪求基于单片机的温湿度监控系统代码?

跪求基于单片机的温湿度监控系统代码?,第1张

#include <reg51.h>

#include <intrins.h>//Keil library (is used for _nop()_ operation)

#include <math.h> //Keil library

#include <stdio.h> //Keil library

unsigned char Tem,Hum

unsigned char Set_Tem,Set_Hum

sbit SS = P1^0 //片选

sbit SCLK = P1^1 //ISD4003 时钟

sbit MOSI = P1^2 //数据输入

sbit MISO = P1^3 //数据输出

sbit LED = P1^7 //指示灯

sbit ISD_INT = P3^2//中断

sbit AN = P1^6//执行

sbit STOP = P1^5 //复位

sbit PR = P1^4 //PR=1 录音PR=0 放音

sbit DATA=P2^0

sbit SCK=P2^1

sbit SCL=P1^1

sbit SDA=P1^0

#define TEMP 0

#define HUMI 1

typedef union

{ unsigned int i

float f

} value

//enum {,EMP,HUMI}

//以上所示为系统的主程序结构,其中子程序可根据系统整个具体的要求进行添加代码,

//刷新LED显示子程序write_led()硬件采用译码器;按键检测子程序check_key()的执行通过读单片机I/O口高低电平识别按键。

//以下所示代码为读温湿度传感器子程序read_ sensor()的程序内容:

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

工程名 SHTxx demo program (V2.1)

文件名: SHTxx_Sample_Code.c

MCU:80C51 family

编译器: Keil Version 6.14

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

//-------------------------------------------------------------------

// modul-var

//-------------------------------------------------------------------

void warning(void)

void Delay(unsigned int time)

#define noACK 0

#define ACK 1

unsigned int *p_value

#define STATUS_REG_W 0x06 //000 00110

#define STATUS_REG_R 0x07 //000 00111

#define MEASURE_TEMP 0x03 //000 00011

#define MEASURE_HUMI 0x05 //000 00101

#define RESET0x1e //000 11110

//-------------------------------------------------------------------

char s_write_byte(unsigned char value)

//-------------------------------------------------------------------

// 写一个字节,检查应答信号

{

unsigned char idata i,error=0

for (i=0x80i>0i/=2)

{ if (i &value) DATA=1

else DATA=0

SCK=1

_nop_()_nop_()_nop_() //时钟脉冲宽度 5 us

SCK=0

}

DATA=1 //释放DATA

SCK=1 //9个CLK后应答

error=DATA//检查应答信号 (DATA 被拉低)

SCK=0

return error// 如果没有应答则error=1

}//

//-------------------------------------------------------------------

char s_read_byte(unsigned char ack)

//-------------------------------------------------------------------

// 读一个字节,检查应答信号

{

unsigned char i,val=0

DATA=1 //释放DATA信号

for (i=0x80i>0i/=2)

{ SCK=1

if (DATA) val=(val | i)

SCK=0

}

DATA=!ack //如果 "ack==1" ,拉低DATA

SCK=1 //clk #9 for ack

_nop_()_nop_()_nop_() //延时5微秒

SCK=0

DATA=1 //释放DATA

return val

}

//-------------------------------------------------------------------

void s_transstart(void)

//-------------------------------------------------------------------

// generates a transmission start

// _____ ________

// DATA: |_______|

// ___ ___

// SCK : ___| |___| |______

{

DATA=1SCK=0 //初始状态

_nop_()

SCK=1

_nop_()

DATA=0

_nop_()

SCK=0

_nop_()_nop_()_nop_()

SCK=1

_nop_()

DATA=1

_nop_()

SCK=0

}

//-------------------------------------------------------------------

void s_connectionreset(void)

//-------------------------------------------------------------------

//通讯复位: 至少在9 SCK 周期后,DATA=1 传输开始

// _____________________________________________________

// DATA: //|_______|

// ____________ ___

// SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______| |___|

{

unsigned char i

DATA=1SCK=0 //初始状态

for(i=0i<9i++) //9 SCK周期

{ SCK=1

SCK=0

}

s_transstart() //通讯开始

}

//-------------------------------------------------------------------

char s_softreset(void)

// resets the sensor by a softreset

{

unsigned char error=0

s_connectionreset() //复位通讯

error+=s_write_byte(RESET) //发送复位命令

return error//如果传感器没有响应则error=1

}

//-------------------------------------------------------------------

char s_read_statusreg(unsigned char *p_value,unsigned *p_checksum)

//-------------------------------------------------------------------

//读效验寄存器状态 (8-bit)

{

unsigned char error=0

s_transstart() //通讯开始

error=s_write_byte(STATUS_REG_R)//发送命令

*p_value=s_read_byte(ACK) //读状态寄存器(8-bit)

*p_checksum=s_read_byte(noACK) //读效验和

return error //如果传感器没有响应则error=1

}

//-------------------------------------------------------------------

char s_write_statusreg(unsigned char *p_value)

//-------------------------------------------------------------------

// writes the status register with checksum (8-bit)

{

unsigned char error=0

s_transstart() //通讯开始

error+=s_write_byte(STATUS_REG_W)// 发送命令

error+=s_write_byte(*p_value) //发送状态寄存器的值

return error//如果传感器没有响应则error=1

}

//-------------------------------------------------------------------

char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode)

//-------------------------------------------------------------------

// makes a measurement (humidity/temperature) with checksum

{

unsigned char idata error=0

unsigned int i

s_transstart() //通讯开始

switch(mode)

{ //发送名令

case TEMP : error+=s_write_byte(MEASURE_TEMP)break

case HUMI : error+=s_write_byte(MEASURE_HUMI)break

default : break

}

for (i=0i<65535i++) if(DATA==0) break//等待传感器完成测量

if(DATA) error+=1

*(p_value) =s_read_byte(ACK) //读取第一个字节

*(p_value+1)=s_read_byte(ACK) //读取第二个字节

*p_checksum =s_read_byte(noACK) //读取效验和

return error

}

//-------------------------------------------------------------------

//-------------------------------------------------------------------

void calc_sth11(float *p_humidity ,float *p_temperature)

//-------------------------------------------------------------------

// 计算温度和湿度

// input : humi [Ticks] (12 bit)

// temp [Ticks] (14 bit)

// output: humi [%RH]

// temp

{ const float xdata C1=-4.0

const float xdata C2=+0.0405

const float xdata C3=-0.0000028

const float xdata T1=+0.01

const float xdata T2=+0.00008

float rh=*p_humidity//计算湿度值

float t=*p_temperature // 计算温度值

float rh_lin

float rh_true

float t_C

t_C=t*0.01 - 40

rh_lin=C3*rh*rh + C2*rh + C1

rh_true=(t_C-25)*(T1+T2*rh)+rh_lin

if(rh_true>100)rh_true=100 //如果结果超出了可能的范围就取消

if(rh_true<0.1)rh_true=0.1

*p_temperature=t_C

*p_humidity=rh_true

}

//-------------------------------------------------------------------

float calc_dewpoint(float h,float t)

//-------------------------------------------------------------------

// calculates dew point

// input: humid,ty , temperature

// output: dew point

{ float dew_point,logEx

logEx=0.66077+7.5*t/(237.3+t)+(log10(h)-2)

dew_point = (logEx - 0.66077)*237.3/(0.66077+7.5-logEx)

return dew_point

}

//-------------------------------------------------------------------

void main_measure()

//-------------------------------------------------------------------

// 使用SHT10功能步骤:

// 1.通讯复位

// 2. 测量温度,湿度

// 3. 计算温度,湿度

// 45. 显示温度,湿度

{ value humi_val,temp_val

float dew_point,error

unsigned char checksum

unsigned int idata i

s_connectionreset()

while(1)

{ error=0

error+=s_measure((unsigned char*) &humi_val.i,&checksum,HUMI) //测量湿度

error+=s_measure((unsigned char*) &temp_val.i,&checksum,TEMP) //测量温度

if(error!=0) s_connectionreset()

//如果有错误就复位

else

{ humi_val.f=(float)humi_val.i//将整数转换成浮点数

temp_val.f=(float)temp_val.i

calc_sth11(&humi_val.f,&temp_val.f)

//计算温度,湿度

dew_point=calc_dewpoint(humi_val.f,temp_val.f)

//计算dew

//printf("temp:%5.1fC humi:%5.1f%% dew point:%5.1f,\n",temp_v,l.f,humi_v,l.f,dew_point)

}

for (i=0i<40000i++)//----------延时0.8s

}

}

//语音功能子程序

//下面代码为语音芯片使用范例,该功能放在主程序中的warning()子程序中执行。

void delay(unsigned int time) //延迟 n 微秒

{

while(time!=0)

{

time--

}

}

void delayms(unsigned int time) //延迟 n 毫秒

{

TMOD=0x01

for(timetime>0time--)

{

TH0 = 0xfc

TL0 = 0x18

TR0 = 1

while(TF0!=1)

{}

TF0=0

TR0=0

}

}

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

//ISD4002 spi 串行发送子程序,8 位数据

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

void spi_send(unsigned char isdx)

{

unsigned char idata k

SS=0//SS=0 //,s=0,打开 spi 通信端

SCLK=0

for(k=0k<8k++) //先发低位再发高位,依发送。 { i

{

if((isdx&0x01)==1)

MOSI=1

else

MOSI=0

isdx=isdx>>1

SCLK=1

delay(2)

SCLK=0

delay(2)

}

}

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

//发送 stop 指令

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

void isd_stop(void)

{

delay(10)

spi_send(0x30)

SS=1

delayms(50)

}

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

//发送上电指令,并延迟 50ms

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

void isd_pu(void)

{ delay(10)

SS=0

spi_send(0x20)

SS=1

delayms(50)

}

//发送掉电指令,并延迟 50ms

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

void isd_pd(void)

{

delay(10)

spi_send(0x10)

SS=1

delayms(50)

}

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

//发送 play 指令

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

void isd_play(void)

{

LED=0

spi_send(0xf0)

SS=1

}

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

//发送 rec 指令

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

void isd_rec(void)

{

LED=0

spi_send(0xb0)

SS=1

}

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

//发送 setplay 指令

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

void isd_setplay(unsigned char adl,unsigned char adh)

{

spi_send(adl) //发送放音起始地址低位

adh=adh||0xe0

spi_send(adh) //发送放音起始地址高位

SS=1

}

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

//发送 setrec 指令

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

void isd_setrec(unsigned char adl,unsigned char adh)

{

spi_send(adl) //发送放音起始地址低位

adh=adh||0xa0

spi_send(adh) //发送放音起始地址高位

SS=1

}

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

//芯片溢出,LED 闪烁提醒停止录音

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

void isd_overflow(void)

{

while(AN==0)

{

LED=1

delayms(300)

LED=0

delayms(300)

}

}

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

//检查芯片是否溢出(读,OVF,并返回 OVF 值)

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

unsigned char chk_isdovf(void)

{

SS=0

delay(2)

SCLK=0

delay(2)

SCLK=1

SCLK=0

delay(2)

if (MISO==1)

{

SCLK=0

SS =1 //关闭 spi 通信端

isd_stop() //发送 stop 指令

return 1 //OVF 为 1,返回 1

}

else

{

SCLK=0

SS =1 //关闭 spi 通信端

isd_stop()//发送 stop 指令

return 0 //OVF 为 0,返回 0

}

}

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

//主程序

//功能:1.录音时,按住 AN 键,LED 点亮开始录音,松开 AN 即可停止录音

// 再次按下 AN 键,LED 点亮开始录第二段音,依次类推,直到芯片溢出。

// 按 stop 键芯片复位

// 2.放音时,按一下 AN 键,即播放一段语音。按 stop 键芯片复位。

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

void voice(void)

{

unsigned char ovflog

while(1)

{

P0=P1=P2=P3=0xff//初始化

while (AN==1) //等待 AN 键按下

{

if (AN==0) //按键防抖动

{delayms(20)}

}

isd_pu() // AN 键按下,ISD 上电并延迟 50ms

isd_pd()

isd_pu()

if (PR==1) //如果 PR=1 则转入录音部分

{

delayms(500)//延迟录音

isd_setrec(0x00,0x00) //发送 0x0000h 地址的 setplay 指令

do

{

isd_rec() //发送 rec 指令

while(AN==0) //等待录音完毕

{

if (ISD_INT==0)//如果芯片溢出,进行 LED 闪烁提示,

isd_overflow()//如果取消录音(松开AN键)则停止录音,芯片复位

}

if (ISD_INT==0)

break

LED=1//录音完毕,LED 熄灭

isd_stop() //发送停止命令

while(AN==1) //如果 AN 再次按下,开始录制下一段语音

{

if(STOP==0) //如果按下 STOP 按键,则芯片复位

break

if (AN==0)

delayms(500)

}

}while(AN==0)

}

else //如果 PR==0 则转入放音部分

{

while(AN==0){}

isd_setplay(0x00,0x00)//发送 setplay 指令,从 0x0000 地址开始放音

do

{

isd_play()//发送放音指令

delay(20)

while(ISD_INT==1) //等待放音完毕的 EOM 中断信号

{}

LED=1

isd_stop() //放音完毕,发送 stop 指令

if (ovflog=chk_isdovf())//检查芯片是否溢出,如溢出则停止放音,芯片复位

break

while(AN==1)//等待 AN 键再次按下

{

if (STOP==0)

break

if(AN==0)

delayms(20)

}

}while(AN==0) // AN 键再次按下,播放下一段语音

}

isd_stop()

isd_pd()

}

}

#define ZLG7290 0x70

#define RADR 0x01

#define uchar unsigned char

#define uint unsigned int

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

void I2cStart(void)

{

SDA=1

SCL=1

Delay(10)

SDA=0

Delay(10)

SCL=0

}

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

void I2cStop(void)

{

SDA=0

SCL=1

Delay(10)

SDA=1

Delay(10)

SCL=0

}

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

void WriteI2cByte(uchar dat)

{

uchar k

SCL=0

for (k=0k<8k++)

{

SDA=(bit)(dat&0x80)

SCL=1

Delay(10)

SCL=0

dat<<=1

}

SCL=0

}

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

uchar ReadI2cByte(void)

{

uchar dat,k

for (k=0k<8k++)

{

SCL=0

SDA=1 //一定要将SDA置为高电平,否则不能正常连续取数据

Delay(10)

SCL=1

dat<<=1

if (SDA)

dat|=0x01

SCL=0

Delay(10)

}

SCL=0

return dat

}

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

void SendAck(void)

{

SDA=0

Delay(10)

SCL=1

Delay(10)

SCL=0

}

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

void SendNoAck(void)

{

SDA=1

SCL=1

Delay(10)

SCL=0

}

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

void I2cWaitAck(void)

{

uchar ack

SDA=1

SCL=1

Delay(10)

ack=SDA

SCL=0

}

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

void I2cReadSequence(uchar sla,uchar sbua,uchar *s,uchar len)

{

uchar l

I2cStart()

WriteI2cByte(sla)

I2cWaitAck()

WriteI2cByte(sbua)

I2cWaitAck()

I2cStart()

WriteI2cByte(sla+1)

I2cWaitAck()

for (l=0l<len-1l++)

{

*s=ReadI2cByte()

SendAck()

s++

}

*s=ReadI2cByte()

SendNoAck()

I2cStop()

}

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

void I2cWriteSequence(uchar sla,uchar sbua,uchar *s,uchar len) //wr

{

uchar k

I2cStart()

WriteI2cByte(sla)

I2cWaitAck()

WriteI2cByte(sbua)

I2cWaitAck()

for (k=0k<lenk++)

{

WriteI2cByte(*s)

I2cWaitAck()

s++

}

I2cStop()

}

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

void I2cWriteByteToSlaver(uchar sla,uchar sbua,uchar dat)

{

I2cStart()

WriteI2cByte(sla)

I2cWaitAck()

WriteI2cByte(sbua)

I2cWaitAck()

WriteI2cByte(dat)

I2cWaitAck()

I2cStop()

Delay(10)

}

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

uchar I2cReadByteFromSlaver(uchar sla,uchar sbua)

{

uchar dat

I2cStart()

WriteI2cByte(sla)

I2cWaitAck()

WriteI2cByte(sbua)

I2cWaitAck()

I2cStart()

WriteI2cByte(sla+1)

I2cWaitAck()

dat=ReadI2cByte()

SendAck()

SendNoAck()

I2cStop()

return dat

}

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

void main()

{

voice()//完成语音芯片的初始化 置入工作状态

s_softreset()

while(1)//进入程序主循环

{

main_measure()//读温湿度传感器 得到温度值Tem 湿度值Hum

/* if(Tem>Set_Tem &&Hum >Set_Hum)//设置报警区间

{

warning()//执行警告 启动报警

} */

}

}

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

*

文件名

温度采集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)

}

}


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

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

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

发表评论

登录后才能评论

评论列表(0条)

保存