|
/*P0口段输出,P2口位控制,前两位数码管显示湿度,后三位显示温度,温度值为-19.9度至99.9度之间,显示负温度时要在前面加负号,小数点随温度变化要改变他的位置。下面程序数码管不显示,请高手指教!*/
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define TEMP_MEASURE 0x03 //000 00011 测试温度命令
#define HUMI_MEASURE 0x05 //000 00101 测试温度命令
sbit DHT_DATA=P1^6;
sbit DHT_SCK=P1^7;
uchar code SEGMENT_CODE[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00,0x40,0x46,0x79,0x38,0x76};//0,1,2,3,4,5,6,7,8,9,熄灭,-,-1,E,L,H
uchar code BIT_CODE[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,0xff,0x3f,0xc7,0x00};
uchar wen,a,shan,tt,sec_point,shift,shi_12,shi_a,sec_point_flag,DHT_TIME,TEMP_LOW,TEMP_HIGH;
uchar k_d_s;
uchar tab1[9];
uchar tab2[9];
uchar DHT_L,DHT_H,DHT_ACK,DHT_ERROR;
unsigned int VALUE_TEMP,VALUE_HUMI,DIS_TEMP,DIS_HUMI;//湿度显示值
uchar TEMP_SIGNS;
uchar TEMP_L_BYTE,TEMP_H_BYTE,TEMP_DECIMAL;
/*************************************************
延时程序
**************************************************/
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=60;y>0;y--);
}
/*************************************************
DHT61读高低两个字节,返回应答信号
**************************************************/
void DHT61_READ_TWO_BYTE()
{
unsigned char i,val=0;
DHT_L=0;
DHT_H=0;
DHT_DATA=1; //释放数据总线
for (i=0x80;i>0;i/=2) //位移8位
{ DHT_SCK=1; //上升沿读入
if (DHT_DATA) val=(val | i); //确定值
DHT_SCK=0;
}
DHT_DATA=0; //读应答信号,有应答为1,无应答为0 通过CPU下拉为应答
DHT_SCK=1; //第9个脉冲
_nop_(); _nop_(); _nop_(); //pulswith approx. 5 us
DHT_SCK=0;
DHT_DATA=1; //释放数据总线
DHT_H=val;
val=0;
////低8位/////////////////////////////
DHT_DATA=1; //释放数据总线
for (i=0x80;i>0;i/=2) //位移8位
{ DHT_SCK=1; //上升沿读入
if (DHT_DATA) val=(val | i); //确定值
DHT_SCK=0;
}
DHT_DATA=1;//0; //不需要应答 通过CPU下拉为应答
DHT_SCK=1; //第9个脉冲
_nop_(); _nop_(); _nop_(); //pulswith approx. 5 us
DHT_SCK=0;
DHT_DATA=1; //释放数据总线
DHT_L=val;
}
/**************************************************
向DHT61写一个字节 返回应答信号
*****************************************************/
char WRITE_DHT61_BYTE(unsigned char value)
{
unsigned char i ;
DHT_ACK=0;
for (i=0x80;i>0;i/=2) //释放数据总线
{ if (i & value) DHT_DATA=1; //写入值
else DHT_DATA=0;
DHT_SCK=1; //上升沿写入
_nop_(); _nop_(); _nop_(); //延时
DHT_SCK=0;
}
DHT_DATA=1; //释放数据总线
DHT_SCK=1; //第9个脉冲
if (DHT_DATA==1) DHT_ACK=1;
//读应答信号
DHT_SCK=0;
return DHT_ACK; //error=1 表示没有应答
}
/**************************
函数功能:DHT61启动时序
***************************/
void DHT_START(void)
{
DHT_DATA=1; DHT_SCK=0; //数据为1,SCK=0
_nop_();
DHT_SCK=1; //第一个脉冲
_nop_();
DHT_DATA=0; //数据跌落
_nop_ ();
DHT_SCK=0; //完成一个脉冲
_nop_(); _nop_(); _nop_();
DHT_SCK=1; //再一个脉冲
_nop_();
DHT_DATA=1; //数据变为1
_nop_();
DHT_SCK=0; //完成该脉冲
}
/**************************
DHT61复位时序
***************************/
void DHT_RESET(void)
{
unsigned char i;
DHT_DATA=1; DHT_SCK=0; //数据为1 时钟为0
for(i=0;i<9;i++) //9 个脉冲为 复位
{ DHT_SCK=1;
DHT_SCK=0;
}
DHT_START(); //启动
}
/***********************************************
DHT61测量温度或者是温度,返回校验值
***********************************************/
void DHT_MEASURE(unsigned char ml)
{
DHT_START(); //启动
WRITE_DHT61_BYTE(ml);//写入测温度
if (DHT_ACK==1)
{
DHT_RESET() ;//复位
WRITE_DHT61_BYTE(ml);//写入测温度
}
}
/**************************
DHT61温度处理
/***************************/
void PROCESS_DHT_TEMP()
{
float aa=0,bb=0,temp_zi;
int abcd=0;
aa=(float)DHT_H*256+(float)DHT_L;
temp_zi=0.01*aa-40;
if (temp_zi<0)
{TEMP_SIGNS=1;
temp_zi=-temp_zi*10;
VALUE_TEMP=(int)temp_zi;
if(VALUE_TEMP>=200) TEMP_LOW=1;
else TEMP_LOW=0;
}
else {TEMP_SIGNS=0;
temp_zi=temp_zi*10;
VALUE_TEMP=(int)temp_zi;//给显示值
}
}
/**************************
DHT61湿度处理
***************************/
void PROCESS_DHT_HUMI()
{
float aa=0,bb=0,humi_zi;
int abcd=0;
aa=(float)DHT_H*256+(float)DHT_L;
bb=aa*aa*2.8/1000000;
aa=0.0405*aa;
aa=aa-4-bb;
humi_zi=aa;
if (humi_zi>99.9)
{
humi_zi=99.9;
}
humi_zi=humi_zi*10;
VALUE_HUMI=(int)humi_zi;
}
/*************************************************
万年历显示子程序
**************************************************/
void display()
{
DIS_HUMI=VALUE_HUMI;
P0=SEGMENT_CODE[DIS_HUMI/100];
P2=BIT_CODE[12];
DIS_HUMI=DIS_HUMI%100;
P0=SEGMENT_CODE[DIS_HUMI/10];
P2=BIT_CODE[12];
DIS_TEMP=VALUE_TEMP;
DIS_TEMP=DIS_TEMP%1000;
/* 下为修正负温度显示而加 可显示-19.9~99.9温度 下 */
if(TEMP_SIGNS==1)
{
if((DIS_TEMP/100)==0)
P0=SEGMENT_CODE[11];
if((DIS_TEMP/100)==1)
P0=SEGMENT_CODE[12];
if((DIS_TEMP/100)>1)
P0=SEGMENT_CODE[13];
}
/* 上 为修正负温度显示而加 可显示-19.9~99.9温度 上 */
else
P0=SEGMENT_CODE[DIS_TEMP/100];
P2=BIT_CODE[12];
/* 为修正负温度显示而加 温度低于-20摄氏度时,显示E-L */
if(TEMP_LOW==1)
{
P0=SEGMENT_CODE[11];
P0=SEGMENT_CODE[14];
}
else
{
DIS_TEMP=DIS_TEMP%100;
P0=SEGMENT_CODE[DIS_TEMP/10]|0x80;
DIS_TEMP=DIS_TEMP%10;
P0=SEGMENT_CODE[DIS_TEMP%10];
}
P2=BIT_CODE[12];
P0=SEGMENT_CODE[10];
P2=BIT_CODE[12];
}
/*************************************************
主程序
**************************************************/
void main()
{
TMOD=1;
TH0=(65536-10000)/256;
TL0=(65536-10000)%256;
EA=1;
ET0=1;
TR0=1;
shan=0x00;
DHT_DATA=1;
DHT_SCK=1;
while(1)
{
}
DHT_ERROR=0;
DHT_ACK=0;
DHT_RESET() ;//复位
DHT_MEASURE(TEMP_MEASURE);
while (DHT_DATA)
{
}
DHT61_READ_TWO_BYTE();//读温度
PROCESS_DHT_TEMP();
DHT_MEASURE(HUMI_MEASURE);
while(DHT_DATA)
{
}
DHT61_READ_TWO_BYTE();//读温度
PROCESS_DHT_HUMI();
}
/*************************************************
定时中断子程序
**************************************************/
void time0() interrupt 1
{
TH0=(65536-10000)/256;
TL0=(65536-10000)%256;
display();
tt++;
sec_point++;
if(tt==50) //设置闪烁
{tt=0;
shan=~shan;
}
if(sec_point==100) //秒点闪烁
{ sec_point=0;
sec_point_flag=~sec_point_flag;
}
}
|
|