|
/************************************************
项 目:温、湿度测量程序
单片机:STC12C5A60S2
传感器:DHT11
日 期:2015.04.09
************************************************/
#include <stc12c5a60s2.h>
#define uint unsigned int
#define uchar unsigned char
sbit io = P2^0; //定义数据端口
uchar data_byte; //定义全局变量
uchar RH,RL,TH,TL; //定义全局变量
unsigned char code DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; // 显示段码值0~9
uchar TempData[5]; //存储显示值的全局变量
/*------------------------------------------------
uS延时函数,含有输入参数 unsigned char t,无返回值
unsigned char 是定义无符号字符变量,其值的范围是
0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
长度如下 T=tx2+5 uS
------------------------------------------------*/
void delayus(unsigned char t)
{
while(--t);
}
/*------------------------------------------------
mS延时函数,含有输入参数 unsigned char t,无返回值
unsigned char 是定义无符号字符变量,其值的范围是
0~255 这里使用晶振12M,精确延时请使用汇编
------------------------------------------------*/
void delayms(unsigned char t)
{
while(t--)
{
//大致延时1mS
delayus(245);
delayus(245);
}
}
/******************** DHT11测试模块**********************/
void start() //开始信号
{
io=1;
delayus(10);
io=0;
delayms(30); //10~60之间
io=1;
delayus(100); //关键时间:35-250之间
}
/**********************接收一个字节**********************/
uchar receive_byte()
{
uchar i,temp,count;
for(i=0;i<8;i++)
{
count=2;
while((!io)&&count++)
temp=0;
delayus(150); //关键时间:10~23之间
if(io==1)temp=1;
count=2;
while((io)&&count++);
if(count==1)break;
data_byte<<=1;
data_byte|=temp;
}
return data_byte;
}
/************************接收数据************************/
void receive()
{
uchar T_H,T_L,R_H,R_L,check,num_check;
uchar count;
start(); //开始信号
io=1;
if(!io) //读取DHT11响应信号
{
count=2;
while((!io)&&count++); //DHT11高电平80us是否结束
count=2;
while((io)&&count++);
R_H=receive_byte();
R_L=receive_byte();
T_H=receive_byte();
T_L=receive_byte();
check=receive_byte();
io=0;
delayms(1); //拉低延时
io=1;
num_check=R_H+R_L+T_H+T_L;
if(num_check=check)
{
RH=R_H;
RL=R_L;
TH=T_H;
TL=T_L;
check=num_check;
}
}
}
/**********************************************************************
显示子函数
**********************************************************************/
void display()
{
P2=0xef;
P0=TempData[0];
delayms(20);
P2=0xff;
P2=0xdf;
P0=TempData[1];
delayms(20);
P2=0xff;
P2=0xbf;
P0=TempData[2];
delayms(20);
P2=0xff;
P2=0x7f;
P0=TempData[3];
delayms(20);
P2=0xff;
}
/*******************************************************************
定时器初始化子函数
*******************************************************************/
void InitTimer(void)
{
TMOD |= 0x01; //定义定时器T0,工作方式1
TH0=(65536-20000)/256;
TL0=(65536-20000)%256; //50ms
ET0=1;
TR0=1;
EA = 1; //开总中断
}
/***************************主函数**************************/
void main()
{
P0M0=0xFF; //定义P0口为推挽输出 1111 1111
// P2M0=0xF0; //定义P2.4 ~ P2.7口为推挽输出 1111 0000
InitTimer();
delayms(10);
while(1)
{
receive();
TempData[0]=DuanMa[RH/10];
TempData[1]=DuanMa[RH%10];
TempData[2]=DuanMa[TH/10];
TempData[3]=DuanMa[TH%10];
delayms(20);
display();
}
}
/***********************************************************************
定时器T1中断子函数
***********************************************************************/
void timer0(void) interrupt 1
{
uchar ms;
TH0=(65536-20000)/256;
TL0=(65536-20000)%256;
ms++; //ms++
if(ms==50) //如果等于10*500us=5ms
{
ms=0; //ms清0
}
// display(); //调用显示子函数
}
|
|