<reg51.h>#include <intrins.h>// typedef unsigned char U8位整型变量 */ typedef signed char S8号 8 位整型变量 */ typedef unsigned int U16位整型变量 */ typedef signed int S16位整型变量 */ typedef unsigned long U32号 32 位整型变量 */ typedef signed long S32位整型变量 */ typedef float F32点数(32 位长度) */ typedef double F64浮点数(64 位长度) */ // #define uchar unsigned char #define uint unsigned int #define Data_0_time 4 /* defined for unsigned 8-bits integer variable /* defined for signed 8-bits integer variable /* defined for unsigned 16-bits integer variable /* defined for signed 16-bits integer variable /* defined for unsigned 32-bits integer variable /* defined for signed 32-bits integer variable 无符号 8 有 符 无符号 16 有符号 16 无 符 有符号 32 /* single precision floating point variable (32bits) 单精度浮 /* double precision floating point variable (64bits) 双精度 //----------------------------------------------// //----------------IO 口定义区--------------------// //----------------------------------------------// sbit P2_0 = P2^0 sbit P2_1 = P2^1 sbit P2_2 = P2^2 sbit P2_3 = P2^3 //----------------------------------------------// //----------------定义区--------------------// //----------------------------------------------// U8 U8FLAG,kU8 U8count,U8tempU8 U8T_data_H,U8T_data_L,U8RH_data_H,U8RH_data_L,U8checkdataU8 U8T_data_H_temp,U8T_data_L_temp,U8RH_data_H_temp,U8RH_data_L_temp,U8checkdata_t empU8 U8comdataU8 outdata[5]//定义发送的字节数 U8 indata[5]U8 count, count_r=0U8 str[5]={"RS232"}U16 U16temp1,U16temp2SendData(U8 *a) { outdata[0] = a[0]outdata[1] = a[1]outdata[2] = a[2]outdata[3] = a[3]outdata[4] = a[4]count = 1SBUF=outdata[0]} void Delay(U16 j) U8 ifor(j>0j--) { for(i=0i<27i++)} } void Delay_10us(void) { U8 ii--i--i--i--i--i--} void COM(void) { { U8 ifor(i=0i<8i++) { U8FLAG=2//---------------------P2_1=0 //T P2_1=1 //T //---------------------while((!P2_0)&&U8FLAG++)Delay_10us()Delay_10us()// Delay_10us()U8temp=0if(P2_0)U8temp=1U8FLAG=2while((P2_0)&&U8FLAG++)//---------------------P2_1=0 //T P2_1=1 //T //---------------------//超时则跳出 for 循环 if(U8FLAG==1)break//判断
数据位是 0 还是 1 // 如果高电平高过预定 0 高电平值则数据位为 1 U8comdata<<=1U8comdata|=U8temp}//rof } //-------------------------------//-----湿度读取子程序 -----------//-------------------------------//----以下变量均为全局变量-------//----温度高 8 位== U8T_data_H-----//----温度低 8 位== U8T_data_L-----//----湿度高 8 位== U8RH_data_H----//----湿度低 8 位== U8RH_data_L----- //0 //----校验 8 位 == U8checkdata----//----调用相关子程序如下---------//---- Delay(), Delay_10us(),COM()//-------------------------------void RH(void) { //主机拉低 18ms P2_0=0Delay(180)P2_0=1//总线由上拉电阻拉高 主机延时 20us Delay_10us()Delay_10us()Delay_10us()Delay_10us()//主机设为输入 判断从机响应
信号 P2_0=1//判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行 if(!P2_0) //T ! { U8FLAG=2//判断从机是否发出 80us 的低电平响应信号是否结束 while((!P2_0)&&U8FLAG++)U8FLAG=2//判断从机是否发出 80us 的高电平,如发出则进入数据接收状态 while((P2_0)&&U8FLAG++)//数据接收状态 COM()U8RH_data_H_temp=U8comdataCOM()U8RH_data_L_temp=U8comdataCOM()U8T_data_H_temp=U8comdataCOM()U8T_data_L_temp=U8comdataCOM()U8checkdata_temp=U8comdataP2_0=1//数据校验 U8temp=(U8T_data_H_temp+U8T_data_L_temp+U8RH_data_H_temp+U8RH_data_L_temp)if(U8temp==U8checkdata_temp) { U8RH_data_H=U8RH_data_H_tempU8RH_data_L=U8RH_data_L_tempU8T_data_H=U8T_data_H_tempU8T_data_L=U8T_data_L_tempU8checkdata=U8checkdata_temp}//fi }//fi } //---------------------------------------------//main()功能描述: AT89C51 11.0592MHz //送
温湿度数据,波特率 9600 //---------------------------------------------void main() { U8 i,j串口发 //uchar str[6]={"RS232"}/* 系统初始化 */ TMOD = 0x20//定时器 T1 使用工作方式 2 TH1 = 253// 设置初值 TL1 = 253TR1 = 1// 开始计时 SCON = 0x50//工作方式 1,波特率 9600bps,允许接收 ES = 1EA = 1// 打开所以中断 TI = 0RI = 0SendData(str) //发送到串口 Delay(1)//延时 100US(12M 晶振) while(1) { //-----------------------//调用温湿度读取子程序 RH()//串口显示程序 //-------------------------str[0]=U8RH_data_Hstr[1]=U8RH_data_Lstr[2]=U8T_data_Hstr[3]=U8T_data_Lstr[4]=U8checkdataSendData(str) //发送到串口 //读取模块数据周期不易小于 2S Delay(20000)}//elihw }// main void RSINTR() interrupt 4 using 2 { U8 InPut3if(TI==1) //发送中断 { TI=0if(count!=5) //发送完 5 位数据 { SBUF= outdata[count]count++} } if(RI==1) //接收中断 { InPut3=SBUFindata[count_r]=InPut3count_r++RI=0if (count_r==5)//接收完 4 位数据 { //数据接收完毕处理。 count_r=0str[0]=indata[0]str[1]=indata[1]str[2]=indata[2]str[3]=indata[3]str[4]=indata[4]P0=0} } }#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++
}
评论列表(0条)