标题:
单片机温湿度检测系统设计DHT22,HC-06,OLED(SPI)
[打印本页]
作者:
cokesu
时间:
2019-5-16 14:34
标题:
单片机温湿度检测系统设计DHT22,HC-06,OLED(SPI)
DHT22程序是在百度文库找的DHT11程序修改过来的,OLED程序为中景园OLED给的参考程序
电路原理图如下:
0.png
(39.14 KB, 下载次数: 48)
下载附件
2019-5-17 04:02 上传
单片机源程序如下:
#include "STC12C5a60s2.H"
#include "oled.h"
#include "dht11.h"
#include "intrins.h"
extern unsigned int F16T,F16RH;
unsigned long vot = 0;
unsigned int _125us =0;
unsigned int _100ms=0;
unsigned int a;
bit _1s_flag = 0;
bit _100ms_flag=0;
bit flag=0;
unsigned int temp;
unsigned int temp1;
unsigned char AD_cnt=0;
unsigned int AD_max,AD_sum,AD_data,AD_value=0;
unsigned int AD_min=0xffff;
//-------------------------------------------------
#define SAMPLE_CNT 10
#define ADC_POWER 0x80 // ADC电源
#define ADC_FLAG 0x10 // ADC转换结束标志
#define ADC_START 0x08 // ADC启动控制位
#define ADC_SPEEDLL 0X00 // 540 clocks
#define ADC_SPEEDL 0X20 // 360 clocks
#define ADC_SPEEDH 0X40 // 180 clocks
#define ADC_SPEEDHH 0X60 // 90 clocks
#define AUXR1_ADRJ 0x04 // 转换结果数据格式控制
/*------------------------------------------------
ADC初始化函数
------------------------------------------------*/
void ADC_Init(void)
{
P1ASF=0x07; // P1.0→P1.3为模拟量输入通道
ADC_RES=0;
ADC_RESL=0;
ADC_CONTR=ADC_CONTR|ADC_POWER|ADC_SPEEDLL; // 开启AD转换器电源,设定转换速度为540 clocks
AUXR1&=~AUXR1_ADRJ; // 转换结果高8位放ADC_RES,低2位放ADC_RESL,左对齐
}
/*------------------------------------------------
AD转换函数
------------------------------------------------*/
unsigned int AD_Read(unsigned char channel)
{
ADC_CONTR=ADC_CONTR|ADC_START|channel; // 启动AD转换,选择转换通道
_nop_(); _nop_(); _nop_(); _nop_(); // 等待成功设置ADC_CONTR
while(!(ADC_CONTR&ADC_FLAG)); // 等待转换结束
ADC_CONTR=ADC_CONTR&(~ADC_FLAG)&(~ADC_START); // 清转换结束标志,关闭AD转换
//ADC_CONTR&=0xef; // 清除ADC_FLAG位
return(ADC_RES*4+ADC_RESL); // 转换结果高8位放ADC_RES,低2位放ADC_RESL,左对齐
}
//-------------------------------------------------
//-------------------------------------------------
void UsartInit()
{
SCON=0X50; //设置为工作方式1
TMOD=0X20; //设置计数器工作方式2
PCON=0X80; //波特率加倍
TH1=0XF3; //计数器初始值设置,注意波特率是4800的
TL1=0XF3;
ES=1; //打开接收中断
EA=1; //打开总中断
TR1=1; //打开计数器
}
void InitTimer0(void)
{
TMOD = TMOD|0x01;
TH0 = 0x0FA;
TL0 = 0x24;
EA = 1;
ET0 = 1;
TR0 = 1;
}
void timetable()
{
if(_100ms>=800)
{
_100ms=0;
_100ms_flag=1;
}
if(_125us>=8000)
{
_125us=0;
_1s_flag=1;
}
}
void display ()
{
u8 t;
u8 x;
u8 y;
if(flag==0) //温度正数
{
OLED_ShowChar(0,2,32);
OLED_ShowChar(18,2,32);
OLED_ShowChar(36,2,32);
OLED_ShowChar(72,2,32); ////清屏
t=F16T/100+48;
if(t<=48) t=' ';
OLED_ShowChar(18,2,t); //10位
t=F16T%100/10+48;
OLED_ShowChar(36,2,t); //个位
t=F16T%10+48;
OLED_ShowChar(72,2,t); //小数点后一位
}
else //温度负数
{
OLED_ShowChar(0,2,32);
OLED_ShowChar(18,2,32);
OLED_ShowChar(36,2,32);
OLED_ShowChar(72,2,32); ////清屏
OLED_ShowChar(0,2,'-');
t=F16T/100+48;
if(t<=48) t=' ';
OLED_ShowChar(18,2,t); //10位
t=F16T%100/10+48;
OLED_ShowChar(36,2,t); //个位
t=F16T%10+48;
OLED_ShowChar(72,2,t); //小数点后一位
}
//湿度
OLED_ShowChar(0,4,32);
OLED_ShowChar(18,4,32);
OLED_ShowChar(54,4,32); ////清屏
x=F16RH/100+48;
if(x<=48) x=' ';
OLED_ShowChar(0,4,x); //10位
x=F16RH%100/10+48;
OLED_ShowChar(18,4,x); //个位
x=F16RH%10+48;
OLED_ShowChar(54,4,x); //小数点后一位
//电压
OLED_ShowChar(0,6,32);
OLED_ShowChar(18,6,32);
OLED_ShowChar(54,6,32); //清屏
OLED_ShowChar(72,6,32); //xx.xx
y=(unsigned char)(temp1/1000+48);
if(y<=48) y=' ';
OLED_ShowChar(0,6,y); //10位
y=(unsigned char)(temp1%1000/100+48);
OLED_ShowChar(18,6,y); //个位
y=(unsigned char)(temp1%1000%100/10+48);
OLED_ShowChar(54,6,y); //小数点后一位
y=(unsigned char)(temp1%10+48);
OLED_ShowChar(72,6,y); //小数点后两位
}
void main(void)
{
// bitinit ();
//ADinit();
AUXR = AUXR|0x80; // T0, 1T Mode
ADC_Init();
OLED_Init(); //初始化OLED
OLED_Clear();
UsartInit();
InitTimer0(); //初始化定时器0
OLED_ShowCHinese(0,0,0);//温 0 18 36 54 72 90 108
OLED_ShowCHinese(18,0,1);//湿
OLED_ShowCHinese(36,0,2);//度
OLED_ShowCHinese(54,0,3);//检
OLED_ShowCHinese(72,0,4);//测
OLED_ShowCHinese(90,0,5);//系
OLED_ShowCHinese(108,0,6);//统
OLED_ShowString(90,6,"V"); //V
OLED_ShowChar(36,6,46); //. 电压
OLED_ShowChar(54,2,46); //. 温度
OLED_ShowChar(36,4,46); //. 湿度
OLED_ShowString(72,4,"%RH"); //%RH
OLED_ShowString(90,2,"C");//C
while(1)
{
timetable();
if(_100ms_flag==1)
{
_100ms_flag=0;
if(AD_cnt<10) // 多次读AD进行数字滤波
{
AD_value=AD_Read(1);
if(AD_value>AD_max) AD_max=AD_value;
if(AD_value<AD_min) AD_min=AD_value;
AD_sum=AD_sum+AD_value;
AD_cnt++;
}
else
{
AD_sum=AD_sum-AD_max-AD_min;
AD_value=AD_sum/8;
temp=AD_value;
vot=(unsigned long)(temp)*5*100*2;
temp1=(unsigned int)(vot/1023);
AD_max=0;
AD_min=0xffff;
AD_value=0;
AD_cnt=0;
AD_sum=0;
}
}
if(_1s_flag==1)
{
_1s_flag=0;
getDHT11();
if(F16T>0x8000) //用于判断DHT22温度是否为负数 1xxx xxxx xxxx xxxx
{
flag=1;
F16T=F16T&0x7fff;
}
else {flag=0;}
display();
}
}
}
void Timer0Interrupt(void) interrupt 1 //定时中断
{
//125us
TH0 = 0x0FA;
TL0 = 0x24;
_125us++;
_100ms++;
}
void Usart() interrupt 4 //串口中断
{
u8 receiveData;
receiveData=SBUF;//出去接收到的数据
RI = 0;//清除接收中断标志位
if(receiveData=='1') //湿度
{
SBUF=' ';
while(!TI); //等待发送数据完成
TI=0; //清除发送完成标志位
SBUF='\n';
while(!TI); //等待发送数据完成
TI=0;
SBUF=F16RH/100+'0'; //十位
while(!TI); //等待发送数据完成
TI=0;
SBUF=F16RH%100/10+'0'; //个位
while(!TI); //等待发送数据完成
TI=0;
SBUF='.';
while(!TI); //等待发送数据完成
TI=0;
SBUF=F16RH%10+'0';
while(!TI); //等待发送数据完成
TI=0;
SBUF='%';
while(!TI); //等待发送数据完成
TI=0;
}
if(receiveData=='2') //温度
{
if(flag==0)
{
SBUF=' ';
while(!TI); //等待发送数据完成
TI=0; //清除发送完成标志位
SBUF='\n';
while(!TI); //等待发送数据完成
TI=0;
SBUF=F16T/100+'0'; //十位
while(!TI); //等待发送数据完成
TI=0;
SBUF=F16T%100/10+'0'; //个位
while(!TI); //等待发送数据完成
TI=0;
SBUF='.';
while(!TI); //等待发送数据完成
TI=0;
SBUF=F16T%10+'0';
while(!TI); //等待发送数据完成
TI=0;
SBUF='C';
while(!TI); //等待发送数据完成
TI=0;
}
if(flag==1)
{
SBUF=' ';
while(!TI); //等待发送数据完成
TI=0; //清除发送完成标志位
SBUF='\n';
while(!TI); //等待发送数据完成
TI=0;
SBUF='-';
while(!TI); //等待发送数据完成
TI=0; //清除发送完成标志位
SBUF=F16T/100+'0'; //十位
while(!TI); //等待发送数据完成
TI=0;
SBUF=F16T%100/10+'0'; //个位
while(!TI); //等待发送数据完成
TI=0;
SBUF='.';
while(!TI); //等待发送数据完成
TI=0;
SBUF=F16T%10+'0';
while(!TI); //等待发送数据完成
TI=0;
SBUF='C';
while(!TI); //等待发送数据完成
TI=0;
}
}
if(receiveData=='3') //电压
{
SBUF=' ';
while(!TI); //等待发送数据完成
TI=0; //清除发送完成标志位
SBUF='\n';
while(!TI); //等待发送数据完成
TI=0;
a=temp1/1000+48;
if(a==48)
{
SBUF=' ';
}
else {SBUF=temp1/1000+48;}
while(!TI); //等待发送数据完成
TI=0;
SBUF=temp1%1000/100+48;
while(!TI); //等待发送数据完成
TI=0;
SBUF='.';
while(!TI); //等待发送数据完成
TI=0;
SBUF=temp1%1000%100/10+48;
while(!TI); //等待发送数据完成
TI=0;
SBUF=temp1%10+48;
while(!TI); //等待发送数据完成
TI=0;
SBUF='V';
while(!TI); //等待发送数据完成
TI=0;
}
}
复制代码
所有资料51hei提供下载:
新建文件夹.rar
(90.04 KB, 下载次数: 73)
2019-5-16 14:34 上传
点击文件名下载附件
程序原理图
下载积分: 黑币 -5
作者:
jemery1030
时间:
2019-7-26 15:14
感謝無私分享
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1