DHT11的温度值控制电机转速
时间:10-02
整理:3721RD
点击:
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
uchar DHT11[5],RTflag=0;
uchar FLAG; //超时标志位
uchar a,b;
sbit dat=P1^5;//DHT11
sbit RS=P2^6;//1602显示
sbit RW=P2^5;
sbit EN=P2^7;
sbit IN1 = P1^0;//电机
sbit IN2 = P1^1;
sbit IN3 = P1^2;
sbit IN4 = P1^3;
sbit ENA = P1^4;
bit Run_Status;
unsigned char CYCLE;
unsigned char DUTY;
uchar table[5];
uint wd,sd;
/*void Delay(uint cnt)
{
while(--cnt);
} */
void motor1()
{
if(DHT11[2]>=20&&DHT11[2]<=24)
{
TR0=1;
if(DUTY<CYCLE)
DUTY=2; //增加占空比
else
DUTY=0;
Run_Status=1;
IN1=1;
IN2=0;
ENA=0;
}
if(DHT11[2]>=25&&DHT11[2]<=29)
{
TR0=1;
if(DUTY<CYCLE)
DUTY=4; //增加占空比
else
DUTY=0;
Run_Status=1;
IN1=1;
IN2=0;
ENA=0;
}
if(DHT11[2]>=30&&DHT11[2]<=34)
{
TR0=1;
if(DUTY<CYCLE)
DUTY=6; //增加占空比
else
DUTY=0;
Run_Status=1;
IN1=1;
IN2=0;
ENA=0;
}
if(DHT11[2]>=35&&DHT11[2]<=40)
{
TR0=1;
if(DUTY<CYCLE)
DUTY=8; //增加占空比
else
DUTY=0;
Run_Status=1;
IN1=1;
IN2=0;
ENA=0;
}
}
void motor2()//湿控
{
if(DHT11[0]+DHT11[1]<=70 )
{
IN3=1;IN4=0;
}
else
{
IN3=0;IN4=0;
}
}
void Delay_t(uint j)
{ uchar i;
for(;j>0;j--)
{
for(i=0;i<27;i++);
}
}
void Delay_10us(void) //10us延时函数
{
uchar i;
i--;
i--;
i--;
i--;
i--;
i--;
}
void delay(uint z)//1毫秒延时函数
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void lcd_write_com(uchar com) //1602写指令
{
RS=0;
RW=0;
EN=1;
P0=com;
delay(1);
EN=0;
}
void lcd_init() //1602初始化
{
lcd_write_com(0x38);
delay(1);
lcd_write_com(0x08);
delay(1);
lcd_write_com(0x01);//1602清屏
delay(1);
lcd_write_com(0x06);
delay(1);
lcd_write_com(0x0C);
delay(1);
}
void lcd_write_data(uchar date)//1602写数据
{
RS=1;
RW=0;
EN=1;
P0=date;
delay(1);
EN=0;
}
void write_str(uchar x,uchar y,uchar *s)//在任意地址写符号
{
if(y==0)
lcd_write_com(0x80+x);
else
lcd_write_com(0xc0+x);
while(*s)
{
lcd_write_data(*s);
s++;
}
}
void write_shu(uchar x,uchar y,uchar num)//数据显示函数
{
uchar s,g;
if(y==0)
lcd_write_com(0x80+x);
else
lcd_write_com(0xc0+x);
s=num/10;// 数据分离显示
lcd_write_data(0x30+s);
g=num%10;//数据分离显示
lcd_write_data(0x30+g);
}
uchar write_byte1() //读一个字节
{
uchar i,comdata,temp1;
for(i=0;i<8;i++)
{
FLAG=2;
while((!dat)&&FLAG++);//判断数据位是1还是0
Delay_10us();
Delay_10us();
Delay_10us();
temp1=0;
if(dat)temp1=1;
FLAG=2;
while((dat)&&FLAG++);
if(FLAG==1)break;
comdata<<=1;
comdata|=temp1;
}
return (comdata);
}
void DHT11_5() //dht11读5个字节
{
uchar i,temp;
//主机拉低18MS
dat=0;
Delay_t(180);
dat=1;
//总线由上拉电阻拉高,主机延时20us
Delay_10us();
Delay_10us();
Delay_10us();
Delay_10us();
dat=1;
if(!dat)
{
FLAG=2;
while((!dat)&&FLAG++);
FLAG=2;
while((dat)&&FLAG++);
for(i=0;i<5;i++)
{
DHT11=write_byte1();
}
dat=1;
temp=(DHT11[0]+DHT11[1]+DHT11[2]+DHT11[3]);
if(temp==DHT11[4]) //数据校验位
{
RTflag=1;
}
if(RTflag==1) //如果RTflag=1说明读到的数据正确
{
RTflag=0;
write_str(0,0,"measurement ");//第一行显示湿度
write_shu(12,0,DHT11[0]);
write_str(14,0,"RH");
write_str(0,1,"Temperature ");//第二行显示温度
write_shu(12,1,DHT11[2]);
write_str(14,1,"^C");
}
}
}
void timerinit()
{
TMOD |=0x01; //定时器设置1MS
TH0=(65536-1000)/256;
TL0=(65536-1000)%256;//定时1ms
IE= 0x82; //′打开中断
Run_Status=0;
IN1=1;
IN2=1;
ENA=0;
CYCLE=10; //?ü?ú10ms周期10ms
DUTY=0; //占空比=0
}
void main()
{
lcd_init(); //1602初始化
delay(1000); //等待DHT11传感器数据稳定开始激活DHT11
timerinit();
while(1)
{
delay(1000);//等待DHT11传感器数据稳定开始激活DHT11
write_byte1();//读一个字节
DHT11_5(); //读数据
delay(1000); //延时等待
motor1();
motor2();
}
}
void Timer0(void) interrupt 1 using 1
{
static unsigned char Cnt;
TH0=(65536-1000)/256;
TL0=(65536-1000)%256;//定时1mS
if(DUTY==0) {Cnt=0; TR0=0;Run_Status=0;} //占空比为0时停止中断
else if(DUTY==CYCLE) Cnt=CYCLE;
else Cnt++;
if(Cnt==DUTY) //高电平时间到
{
ENA = 0;
}
if(Cnt == CYCLE) //低电平时间到
{
ENA = 1;
Cnt=0;
}
}
#define uint unsigned int
#define uchar unsigned char
uchar DHT11[5],RTflag=0;
uchar FLAG; //超时标志位
uchar a,b;
sbit dat=P1^5;//DHT11
sbit RS=P2^6;//1602显示
sbit RW=P2^5;
sbit EN=P2^7;
sbit IN1 = P1^0;//电机
sbit IN2 = P1^1;
sbit IN3 = P1^2;
sbit IN4 = P1^3;
sbit ENA = P1^4;
bit Run_Status;
unsigned char CYCLE;
unsigned char DUTY;
uchar table[5];
uint wd,sd;
/*void Delay(uint cnt)
{
while(--cnt);
} */
void motor1()
{
if(DHT11[2]>=20&&DHT11[2]<=24)
{
TR0=1;
if(DUTY<CYCLE)
DUTY=2; //增加占空比
else
DUTY=0;
Run_Status=1;
IN1=1;
IN2=0;
ENA=0;
}
if(DHT11[2]>=25&&DHT11[2]<=29)
{
TR0=1;
if(DUTY<CYCLE)
DUTY=4; //增加占空比
else
DUTY=0;
Run_Status=1;
IN1=1;
IN2=0;
ENA=0;
}
if(DHT11[2]>=30&&DHT11[2]<=34)
{
TR0=1;
if(DUTY<CYCLE)
DUTY=6; //增加占空比
else
DUTY=0;
Run_Status=1;
IN1=1;
IN2=0;
ENA=0;
}
if(DHT11[2]>=35&&DHT11[2]<=40)
{
TR0=1;
if(DUTY<CYCLE)
DUTY=8; //增加占空比
else
DUTY=0;
Run_Status=1;
IN1=1;
IN2=0;
ENA=0;
}
}
void motor2()//湿控
{
if(DHT11[0]+DHT11[1]<=70 )
{
IN3=1;IN4=0;
}
else
{
IN3=0;IN4=0;
}
}
void Delay_t(uint j)
{ uchar i;
for(;j>0;j--)
{
for(i=0;i<27;i++);
}
}
void Delay_10us(void) //10us延时函数
{
uchar i;
i--;
i--;
i--;
i--;
i--;
i--;
}
void delay(uint z)//1毫秒延时函数
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void lcd_write_com(uchar com) //1602写指令
{
RS=0;
RW=0;
EN=1;
P0=com;
delay(1);
EN=0;
}
void lcd_init() //1602初始化
{
lcd_write_com(0x38);
delay(1);
lcd_write_com(0x08);
delay(1);
lcd_write_com(0x01);//1602清屏
delay(1);
lcd_write_com(0x06);
delay(1);
lcd_write_com(0x0C);
delay(1);
}
void lcd_write_data(uchar date)//1602写数据
{
RS=1;
RW=0;
EN=1;
P0=date;
delay(1);
EN=0;
}
void write_str(uchar x,uchar y,uchar *s)//在任意地址写符号
{
if(y==0)
lcd_write_com(0x80+x);
else
lcd_write_com(0xc0+x);
while(*s)
{
lcd_write_data(*s);
s++;
}
}
void write_shu(uchar x,uchar y,uchar num)//数据显示函数
{
uchar s,g;
if(y==0)
lcd_write_com(0x80+x);
else
lcd_write_com(0xc0+x);
s=num/10;// 数据分离显示
lcd_write_data(0x30+s);
g=num%10;//数据分离显示
lcd_write_data(0x30+g);
}
uchar write_byte1() //读一个字节
{
uchar i,comdata,temp1;
for(i=0;i<8;i++)
{
FLAG=2;
while((!dat)&&FLAG++);//判断数据位是1还是0
Delay_10us();
Delay_10us();
Delay_10us();
temp1=0;
if(dat)temp1=1;
FLAG=2;
while((dat)&&FLAG++);
if(FLAG==1)break;
comdata<<=1;
comdata|=temp1;
}
return (comdata);
}
void DHT11_5() //dht11读5个字节
{
uchar i,temp;
//主机拉低18MS
dat=0;
Delay_t(180);
dat=1;
//总线由上拉电阻拉高,主机延时20us
Delay_10us();
Delay_10us();
Delay_10us();
Delay_10us();
dat=1;
if(!dat)
{
FLAG=2;
while((!dat)&&FLAG++);
FLAG=2;
while((dat)&&FLAG++);
for(i=0;i<5;i++)
{
DHT11=write_byte1();
}
dat=1;
temp=(DHT11[0]+DHT11[1]+DHT11[2]+DHT11[3]);
if(temp==DHT11[4]) //数据校验位
{
RTflag=1;
}
if(RTflag==1) //如果RTflag=1说明读到的数据正确
{
RTflag=0;
write_str(0,0,"measurement ");//第一行显示湿度
write_shu(12,0,DHT11[0]);
write_str(14,0,"RH");
write_str(0,1,"Temperature ");//第二行显示温度
write_shu(12,1,DHT11[2]);
write_str(14,1,"^C");
}
}
}
void timerinit()
{
TMOD |=0x01; //定时器设置1MS
TH0=(65536-1000)/256;
TL0=(65536-1000)%256;//定时1ms
IE= 0x82; //′打开中断
Run_Status=0;
IN1=1;
IN2=1;
ENA=0;
CYCLE=10; //?ü?ú10ms周期10ms
DUTY=0; //占空比=0
}
void main()
{
lcd_init(); //1602初始化
delay(1000); //等待DHT11传感器数据稳定开始激活DHT11
timerinit();
while(1)
{
delay(1000);//等待DHT11传感器数据稳定开始激活DHT11
write_byte1();//读一个字节
DHT11_5(); //读数据
delay(1000); //延时等待
motor1();
motor2();
}
}
void Timer0(void) interrupt 1 using 1
{
static unsigned char Cnt;
TH0=(65536-1000)/256;
TL0=(65536-1000)%256;//定时1mS
if(DUTY==0) {Cnt=0; TR0=0;Run_Status=0;} //占空比为0时停止中断
else if(DUTY==CYCLE) Cnt=CYCLE;
else Cnt++;
if(Cnt==DUTY) //高电平时间到
{
ENA = 0;
}
if(Cnt == CYCLE) //低电平时间到
{
ENA = 1;
Cnt=0;
}
}
我找了段DHT11传感器并用1602显示的程序,现在我利用里面读到温度值DHT11[2]来控制直流电机的转速,可是程序加了进去后1602和DHT11都有点问题,,能不能帮忙看看
感觉小编写的真棒,但我想要一个电路图,本人刚开始学习单片机,想做一个温湿度传感器,谢谢。