當手動控制時:可以控制電機手動反轉,手動正轉,并伴隨有正反轉的LED燈亮。
并且加有正反轉限位開關,當按下限位開關后,電機將不能相同方向的正反轉。
調整為自動模式時:根據檢測的光照強度和溫度來控制電機的運動。
達到百葉窗的效果。
Proteus仿真圖:
單片機程序:
- /*****頭文件聲明*****/
- #include <reg51.h>
- #include "lcd.h"
- #include "ds1302.h"
- #include <intrins.h>
- /*數據類型聲明定義*/
- typedef unsigned int u16;
- typedef unsigned char u8;
- /*******I/O口定義*******/
- sbit IN1 = P3^0;
- sbit IN2 = P3^1;
- sbit LED1 = P3^2;
- sbit LED2 = P3^3;
- sbit LED3 = P3^4;
- sbit K1 = P3^5;
- sbit K2 = P3^6;
- sbit K3 = P3^7;
- sbit K4 = P1^5;
- sbit MOTOR = P2^4;
- sbit Data = P2^0;//定義DHT11數據線
- sbit CS = P1^0;//片選使能端
- sbit DI = P1^1;//數據信號輸入端
- sbit DO = P1^1;//數據輸出端
- sbit CLK = P1^2;//時鐘脈沖
- sbit YS = P1^3;
- /*******變量定義*******/
- u8 TEMP,HUMI;//DHT11采集值
- u16 Flag_num;
- u16 Flag_n=3;
- bit Flag_t;
- u16 LDR_Val;//測量的電壓值
- bit Flag_Auto;
- bit Flag_DHT;
- bit Flag_MOTOR;
- bit Flag_ZHUAN;
- /*******程序段*******/
- void delay(u16 i)//延時函數
- {
- while(i--);
- }
- void DHT11_delay_ms(u16 z)
- {
- u16 i,j;
- for(i=z;i>0;i--)
- for(j=110;j>0;j--);
- }
- void DHT11_delay_us(u8 n)
- {
- while(--n);
- }
- void DHT11_start()
- {
- Data=1;
- DHT11_delay_us(2);
- Data=0;
- DHT11_delay_ms(30); //延時18ms以上
- Data=1;
- DHT11_delay_us(30);
- }
- u8 DHT11_rec_byte() //接收一個字節
- {
- u8 i,dat=0;
- for(i=0;i<8;i++) //從高到低依次接收8位數據
- {
- while(!Data); ////等待50us低電平過去
- DHT11_delay_us(8); //延時60us,如果還為高則數據為1,否則為0
- dat<<=1; //移位使正確接收8位數據,數據為0時直接移位
- if(Data==1) //數據為1時,使dat加1來接收數據1
- dat+=1;
- while(Data); //等待數據線拉低
- }
- return dat;
- }
- void DHT11_Receive() //接收40位的數據
- {
- u8 R_H,R_L,T_H,T_L,RH,RL,TH,TL,revise;
- DHT11_start();
- if(Data==0)
- {
- while(Data==0); //等待拉高
- DHT11_delay_us(40); //拉高后延時80us
- R_H=DHT11_rec_byte(); //接收濕度高八位
- R_L=DHT11_rec_byte(); //接收濕度低八位
- T_H=DHT11_rec_byte(); //接收溫度高八位
- T_L=DHT11_rec_byte(); //接收溫度低八位
- revise=DHT11_rec_byte(); //接收校正位
- DHT11_delay_us(25); //結束
- if((R_H+R_L+T_H+T_L)==revise) //校正
- {
- RH=R_H;
- RL=R_L;
- TH=T_H;
- TL=T_L;
- }
- TEMP=TH;//溫度
- HUMI=RH;//濕度
- }
- }
- /***讀ADC0832函數***/
- unsigned int Get_ADC0832(unsigned char CHAANEL) //AD轉換,返回結果
- {
- unsigned long Volt;//測量的電壓值
- u8 i=0;
- u8 j;
- u16 dat=0; //正向輸入
- u8 ndat=0; //反向輸入
- if(CHAANEL==0)CHAANEL=2;
- if(CHAANEL==1)CHAANEL=3;
- DI=1; _nop_();_nop_(); //發起始位,固定為1(1位)
- CS=0; _nop_();_nop_(); //拉低CS端,讓ADC0832使能
- CLK=1;_nop_();_nop_(); //拉高CLK端,DI端的數據移入ADC0832內部的多路移位寄存器
- CLK=0;_nop_();_nop_(); //拉低CLK端,形成下降沿1,第一個周期開始
- CLK=1; //拉高CLK端,在第一個時鐘周期內,DI為高電平,表示啟動位
- DI=CHAANEL&0x1;_nop_();_nop_(); //假設選取通道0,則10&01=0,即SGL/DIF=0,為差分輸入(2位)
- CLK=0;_nop_();_nop_(); //拉低CLK端,形成下降沿2,第二個周期開始
- CLK=1; //拉高CLK端
- DI=(CHAANEL>>1)&0x1;_nop_();_nop_(); //選取通道0,則01&01=1,ODD/EVEN=1,表示通道0
- CLK=0; //拉低CLK端
- DI=1;_nop_();_nop_();
- dat=0;
- for(i=0;i<8;i++) //每一個CLK下降沿輸出一位數,先輸出高位
- {
- dat|=DO;
- CLK=1;_nop_();_nop_();
- CLK=0;_nop_();_nop_();
- dat<<=1;
- if(i==7)dat|=DO;
- }
- for(i=0;i<8;i++) //每一個CLK下降沿輸出一位數,先輸出低位
- {
- j=0;
- j=j|DO; //收數據
- CLK=1;_nop_();_nop_();
- CLK=0;_nop_();_nop_(); //形成一次時鐘脈沖
- j=j<<7;
- ndat=ndat|j;
- if(i<7)ndat>>=1;
- }
- CS=1; //拉低CS端口
- CLK=0; //拉低CLK端口
- DO=1; //拉高數據端
- dat<<=8;
- dat|=ndat;
- Volt=dat*0.0763;//8位
- return(Volt); //返回數據
- }
- void Key_Control(void)
- {
- }
- void Conotrol(void)
- {
- }
- void Init_Timer0()
- {
- TMOD|=0X01;//選擇為定時器0模式,工作方式1,僅用TR0打開啟動。
- TH0 = 0xD8;//給定時器賦初值,定時10ms
- TL0 = 0xF0;
- ET0=1;//打開定時器1中斷允許
- EA=1;//打開總中斷
- TR0=1;//打開定時器
- }
- void main(void)
- {
- LcdInit();
- Init_Timer0();
- MOTOR=1;
- LDR_Val=Get_ADC0832(0);//關照檢測
- Flag_num=LDR_Val;
- LcdWriteCom(0x01);
- DisplayListChar(0,0,"T:"); DisplayOneChar(6,0,'C'); DisplayListChar(8,0,"H:"); DisplayOneChar(14,0,'%');//T:25C H:85%
- DisplayListChar(0,1,"LUX:");
- while(1)
- {
- Key_Control();
- Conotrol();
- if(Flag_DHT == 1)
- {
- TR0=0;
- DHT11_Receive();//溫濕度采集
- DisplayOneChar(3,0,TEMP/10+'0');
- DisplayOneChar(4,0,TEMP%10+'0');
- DisplayOneChar(11,0,HUMI/10+'0');
- DisplayOneChar(12,0,HUMI%10+'0');
- LDR_Val=Get_ADC0832(0);//關照檢測
- DisplayOneChar(4,1,LDR_Val/1000+'0');
- DisplayOneChar(5,1,LDR_Val%1000/100+'0');
- DisplayOneChar(6,1,LDR_Val%100/10+'0');
- DisplayOneChar(7,1,LDR_Val%10+'0');
- TR0=1;
- }
- if(YS == 0)
- {
- DisplayListChar(9,1,"No Auto");
- if(K1 == 0)
- {
- Flag_ZHUAN=1;//正轉
- if(Flag_n==1)
- {
- Flag_n=Flag_n;
- }else{Flag_n=3;Flag_MOTOR=1;
- }
-
- while(!K1);
- }
- if(K2 == 0)
- {
- Flag_ZHUAN=0;//反轉
- if(Flag_n==0)
- {
- Flag_n=Flag_n;
- }else{Flag_n=3;Flag_MOTOR=1;
- }
- while(!K2);
- }
- if(K3 == 0)
- {
- Flag_MOTOR=0;
- Flag_n=0;
- while(!K3);
- }
- if(K4 == 0)
- {
- Flag_n=1;
- Flag_MOTOR=0;
-
- while(!K4);
- }
- }else{
- DisplayListChar(9,1,"!! Auto");
- if(Flag_num!=LDR_Val)
- {Flag_n=3;
- if(Flag_num>LDR_Val)
- {
- Flag_MOTOR=1;
- Flag_ZHUAN=0;//反轉
- }
- if(Flag_num<LDR_Val)
- {
- Flag_MOTOR=1;
- Flag_ZHUAN=1;//正轉
- }
- Flag_num=LDR_Val;
- }
- }
-
- }
- }
- void Timer0() interrupt 1//定時器0的中斷函數
- {
- static u16 p,t;
- TH0 = 0xD8;//定時10ms
- TL0 = 0xF0;
- p++;
- if(P == 50)
- {
- p=0;
- Flag_DHT=1;
- }
- if(Flag_MOTOR == 1)//旋轉信號
- {
- t++;
- if(Flag_ZHUAN == 0&&(Flag_n==3||Flag_n==0))
- {
- LED1=1;LED2=0; LED3=1;
- IN1 = 0;IN2 = 1;//反轉
- }else{
- LED1=0;LED2=1;LED3=1;
- IN1 = 1;IN2 = 0;//正轉
- }
- if(YS == 0)
- {
- if(t==100)
- {
- t=0;
- LED3=0;
- LED1=1;LED2=1;
- IN1 = 0;IN2 = 0;//停止
- Flag_MOTOR=0;
- }
- }else
- {
- if(t==10)
- {
- t=0;
- LED3=0;
- LED1=1;LED2=1;
- IN1 = 0;IN2 = 0;//停止
- Flag_MOTOR=0;
- }
- }
- }
- else{
- t=0;
- LED3=0;
- LED1=1;LED2=1;
- IN1 = 0;IN2 = 0;//停止
- Flag_MOTOR=0;
- }
- }
復制代碼 Keil代碼與Proteus8.13仿真下載:
百葉扇帶DHT11.7z
(483.04 KB, 下載次數: 95)
2023-3-17 17:51 上傳
點擊文件名下載附件
|