|
實(shí)用STC12C5A60S2型號(hào)的單片機(jī),實(shí)現(xiàn)三檔風(fēng)速,利用單片機(jī)內(nèi)部定時(shí)器智能定時(shí),可切換自然風(fēng)和正常風(fēng),使用市場(chǎng)上常見(jiàn)的小遙控器。
電路原理圖如下:
紅外風(fēng)扇原理圖1.png (79.68 KB, 下載次數(shù): 88)
下載附件
2019-5-22 08:53 上傳
制作出來(lái)的實(shí)物圖如下:
A8ACBCF79EF7B93395A3E0B707AF4CA7.png (703.7 KB, 下載次數(shù): 77)
下載附件
2019-5-22 08:53 上傳
單片機(jī)源程序如下:
- #include<STC12C5A60S2.H> //頭文件
- #include <stc_pwm.H>
- /*====================================
- 自定義類型名
- ====================================*/
- typedef unsigned char INT8U;
- typedef unsigned char uchar;
- typedef unsigned int INT16U;
- typedef unsigned int uint;
- sbit PWM_1 = P1^4; //PWM1_Boost/Buck
- sbit enlarge = P3^0; //增大
- sbit reduce = P3^1; //減小
- /*====================================
- 硬件接口位聲明
- ====================================*/
- sbit IR = P3^2; //定義紅外脈沖數(shù)據(jù)接口 外部中斷O輸入口
- sbit beep = P2^3; //蜂鳴器的位置
- sbit NPN1 = P1^1; //電機(jī) 低檔
- sbit NPN2 = P1^2; //電機(jī) 中檔
- sbit NPN3 = P1^3; //電機(jī) 高檔
- sbit NPNhuxi = P1^5; //電機(jī) 呼吸風(fēng)
- /**************************************
- 1602液晶
- **************************************/
- sbit RS = P2^5;
- sbit RW = P2^6;
- sbit E = P2^4;
- uchar IRtime; //檢測(cè)紅外高電平持續(xù)時(shí)間(脈寬)
- uchar IRcord[4]; //此數(shù)組用于儲(chǔ)存分離出來(lái)的4個(gè)字節(jié)的數(shù)據(jù)(用戶碼2個(gè)字節(jié)+鍵值碼2個(gè)字節(jié))
- uchar IRdata[33]; //此數(shù)組用于儲(chǔ)存紅外的33位數(shù)據(jù)(第一位為引導(dǎo)碼用戶碼16+鍵值碼16)
- bit IRpro_ok, IRok; //第一個(gè)用于紅外接收4個(gè)字節(jié)完畢。IRok用為檢測(cè)脈寬完畢
- void delay4(uchar t)
- {
- uint j;
- uchar i;
- for(i=0;i<t;i++)
- for(j=0;j<1000;j++);
- }
- //毫秒級(jí)延時(shí)
- void delay(unsigned int z)
- {
- unsigned int x,y;
- for(x = z; x > 0; x--)
- for(y = 114; y > 0 ; y--);
- }
- void time0() interrupt 1 //定義定時(shí)器0
- {
- IRtime++; //檢測(cè)脈寬,1次為278us
- }
- void int0() interrupt 0 //定義外部中斷0
- {
- static uchar i; // 聲明靜態(tài)變量(在跳出函數(shù)后在回來(lái)執(zhí)行的時(shí)候不會(huì)丟失數(shù)值)i用于把33次高電平的持續(xù)時(shí)間存入IRdata
- static bit startflag; //開(kāi)始儲(chǔ)存脈寬標(biāo)志位
- if(startflag) //開(kāi)始接收脈寬檢測(cè)
- {
- if( (IRtime < 53) && (IRtime >= 32) ) /*判斷是否是引導(dǎo)碼,底電平9000us+高4500us
- 這個(gè)自己可以算我以11.0592來(lái)算了NEC協(xié)議的引導(dǎo)碼低8000-10000+高4000-5000
- 如果已經(jīng)接收了引導(dǎo)碼那么i不會(huì)被置0就會(huì)開(kāi)始依次存入脈寬*/
- i = 0; //如果是引導(dǎo)碼那么執(zhí)行i=0把他存到IRdata的第一個(gè)位
- IRdata[i] = IRtime; //以T0的溢出次數(shù)來(lái)計(jì)算脈寬,把這個(gè)時(shí)間存到數(shù)組里面到后面判斷
- IRtime = 0; //計(jì)數(shù)清零,下一個(gè)下降沿的時(shí)候在存入脈寬
- i++; //計(jì)數(shù)脈寬存入的次數(shù)
- if(i == 33) //如果存入34次 數(shù)組的下標(biāo)是從0開(kāi)始i等于33表示執(zhí)行了34次
- {
- IRok = 1; //那么表示脈寬檢測(cè)完畢
- i = 0; //把脈寬計(jì)數(shù)清零準(zhǔn)備下次存入
- }
- }
- else
- {
- IRtime = 0; //引導(dǎo)碼開(kāi)始進(jìn)入把脈寬計(jì)數(shù)清零開(kāi)始計(jì)數(shù)
- startflag = 1; //開(kāi)始處理標(biāo)志位置1
- }
- }
- void IRcordpro() //提取它的33次脈寬進(jìn)行數(shù)據(jù)解碼
- {
- uchar i, j, k, cord, value; /*i用于處理4個(gè)字節(jié),j用于處理一個(gè)字節(jié)中每一位,k用于33次脈寬中的哪一位
- cord用于取出脈寬的時(shí)間判斷是否符合1的脈寬時(shí)間*/
- k = 1; //從第一位脈寬開(kāi)始取,丟棄引導(dǎo)碼脈寬
- for(i = 0; i < 4; i++)
- {
- for(j = 0; j < 8; j++)
- {
- cord = IRdata[k]; //把脈寬存入cord
- if(cord > 5) //如果脈寬大于我11.0592的t0溢出率為約278us*5=1390那么判斷為1
- value = value | 0x80; /*接收的時(shí)候是先接收最低位,
- 把最低位先放到value的最高位在和0x08按位或一下
- 這樣不會(huì)改變valua的其他位的數(shù)值只會(huì)讓他最高位為1*/
- if(j < 7)
- {
- value = value >> 1; //value位左移依次接收8位數(shù)據(jù)。
- }
- k++; //每執(zhí)行一次脈寬位加1
- }
- IRcord[i] = value; //每處理完一個(gè)字節(jié)把它放入IRcord數(shù)組中。
- value = 0; //清零value方便下次在存入數(shù)據(jù)
- }
- IRpro_ok = 1; //接收完4個(gè)字節(jié)后IRpro ok置1表示紅外解碼完成
- }
- void init_pwm()
- {
- CCON = 0;
- CL = 0;
- CH = 0;
- CMOD = 0X08; //0X08:43KHZ // 0X02,22KHZ // 0X0A,10KHZ //
- CCAPM1 =0x42;//8位PWM輸出,無(wú)中斷
- CCAP1H=255;//占空比控制
- CCAP1L=255;
- CR=1;
- }
- //呼吸風(fēng)
- /**************************************
- 短延時(shí)
- **************************************/
- void delay5ms()
- {
- uchar i,v,k;
- for(i=1;i>0;i--)
- for(v=168;v>0;v--)
- for(k=22;k>0;k--);
- }
- /**************************************
- 寫(xiě)指令
- **************************************/
- void lcd_Write_com(uchar com)
- {
- RS=0; //定義指令寄存器
- RW=0; //寫(xiě)允許
- P0=com; //寫(xiě)指令
- delay5ms(); E=1; //片選端上拉
- delay5ms(); E=0; //下降沿鎖存
- }
- /**************************************
- 寫(xiě)數(shù)據(jù)
- **************************************/
- void lcd_write_date(uchar date)
- {
- RS=1; //定義數(shù)據(jù)寄存器
- RW=0; //寫(xiě)允許
- P0=date; //寫(xiě)數(shù)據(jù)
- delay5ms(); E=1; //片選端上拉
- delay5ms(); E=0; //下降沿鎖存
- }
- /**************************************
- 顯示程序
- **************************************/
- void dis_lcd1602(uchar x,uchar y,uchar dat)
- {
- uchar add;
- if(y==1) add=(0x80+x);
- if(y==2) add=(0xc0+x);
- lcd_Write_com(add); //寫(xiě)指令
- lcd_write_date(dat); //寫(xiě)數(shù)據(jù)
- }
- /**************************************
- 液晶初始化
- **************************************/
- void lcd1602_init()
- {
- lcd_Write_com(0x38); //設(shè)置8位格式,2行,5*7
- lcd_Write_com(0x01); //清屏
- lcd_Write_com(0x0c); //整體顯示,關(guān)光標(biāo),不閃爍
- lcd_Write_com(0x06); //設(shè)定輸入方式,增量不移位
- lcd_Write_com(0x80); //初始坐標(biāo)
- }
- /**************************************
- 液晶顯示漢字程序
- **************************************/
- void hz_lcdDis(uchar x,uchar y,uchar *p) //漢字顯示
- {
- uchar i=0,temp;
- if(x)temp = 0x40; else temp = 0;
- for(i=y;*p!='\0';i++,p++)
- {
- lcd_Write_com(i|0x80+temp);
- lcd_write_date(*p);
- delay5ms();
- }
- }
- /**************************************
- 液晶顯示數(shù)字程序
- **************************************/
- void num_lcdDis(uchar X,uchar Y,uint num,uchar n)
- {
- uint i=0,temp,hang;
- n +=1;
- if(X)hang = 0x40;else hang = 0;
- for(i=(n-1);i>0;i--)
- {
- lcd_Write_com((i+Y-1)|0x80+hang); //從個(gè)位開(kāi)始顯示
- temp = num%10+0x30;
- lcd_write_date(temp);
-
- num/=10;
- }
- }
- void displayTime30(unsigned int z){
- uchar a=0; //50次數(shù)計(jì)數(shù)
- uchar b=0;//秒計(jì)數(shù)
- TR1 = 1;//啟動(dòng)T1
- beep = 0; delay(15); beep = 1;
- while(1)
- {
- if(TF1 == 1)//判斷T1是否溢出
- {
- TH1 = 0x4b;
- TL1 = 0xfc;//0x4bfc 定時(shí)50ms
- TF1 = 0;//清零便于下次判斷
- a++;//50毫秒計(jì)數(shù)加1
- }
- if(a == 20)//判斷是否到1秒
- {
- a = 0;//清零便于下次記錄50ms的次數(shù)
- b++;//秒加1
- }
- num_lcdDis(1,12,b,3);
- // display(b);//顯示秒的值
- if(b == z)//檢查是否到20秒
- {
- TR1 = 0;//時(shí)間到關(guān)閉定時(shí)器1
- NPN1=0; NPN2=0; NPN3=0;; //引腳高電平
- CCAP1H=255;//占空比控制
- CCAP1L=255;
- delay(10);
- break ;
- }
- if(IRok) //判斷脈寬是否檢測(cè)完畢
- {
- IRcordpro();//根據(jù)脈寬解碼出4個(gè)字節(jié)的數(shù)據(jù)
- IRok = 0; //重新等待脈寬檢測(cè)
- if(IRpro_ok) //判斷是否解碼完畢
- {
- if(IRcord[2]==0x18)
- {
-
-
- NPN1=0; NPN2=0; NPN3=0;
- CCAP1H=255;//占空比控制
- CCAP1L=255;
- hz_lcdDis(0,0,"Close");
- beep = 0; delay(15); beep = 1; //按鍵 上 按鍵返回
- break;
- }
- IRpro_ok = 0;
- }
- }
-
- }
- }
- void displayTime30huxi(unsigned int z){
- uchar a=0; //50次數(shù)計(jì)數(shù)
- uchar b=0;//秒計(jì)數(shù)
- TR1 = 1;//啟動(dòng)T1
- beep = 0; delay(15); beep = 1;
- while(1)
- {
- if(TF1 == 1)//判斷T1是否溢出
- {
- TH1 = 0x4b;
- TL1 = 0xfc;//0x4bfc 定時(shí)50ms
- TF1 = 0;//清零便于下次判斷
- a++;//50毫秒計(jì)數(shù)加1
- NPN1=1; NPN2=0; NPN3=0;
- delay(100);
- NPN1=0; NPN2=1; NPN3=0;
- delay(100);
- NPN1=0; NPN2=0; NPN3=1;
- delay(100);
-
- }
- if(a == 20)//判斷是否到1秒
- {
- NPN1=0; NPN2=0; NPN3=1;
- delay(100);
- NPN1=0; NPN2=1; NPN3=0;
- delay(100);
- NPN1=1; NPN2=0; NPN3=0;
- delay(100);
- a = 0;//清零便于下次記錄50ms的次數(shù)
- b++;//秒加1
- }
- num_lcdDis(1,12,b,3);
- // display(b);//顯示秒的值
- if(b == z)//檢查是否到20秒
- {
- TR1 = 0;//時(shí)間到關(guān)閉定時(shí)器1
- NPN1=0; NPN2=0; NPN3=0; NPNhuxi=0;
- CCAP1H=255;//占空比控制
- CCAP1L=255;
- delay(10);
- break ;
- }
- if(IRok) //判斷脈寬是否檢測(cè)完畢
- {
- IRcordpro();//根據(jù)脈寬解碼出4個(gè)字節(jié)的數(shù)據(jù)
- IRok = 0; //重新等待脈寬檢測(cè)
- if(IRpro_ok) //判斷是否解碼完畢
- {
- if(IRcord[2]==0x18)
- {
-
-
- NPN1=0; NPN2=0; NPN3=0; NPNhuxi=0;
- CCAP1H=255;//占空比控制
- CCAP1L=255;
- hz_lcdDis(0,0,"Close");
- beep = 0; delay(15); beep = 1; //按鍵 上 按鍵返回
- break;
- }
- IRpro_ok = 0;
- }
- }
-
- }
- }
- void huxi(){
- NPN1=0; NPN2=0; NPN3=0;
- beep = 0; delay(15); beep = 1;
- while(1){
- NPN1=1; NPN2=0; NPN3=0;
- CCAP1H=254;//占空比控制
- CCAP1L=254;
- delay(1000);
- NPN1=0; NPN2=1; NPN3=0;
- CCAP1H=200;//占空比控制
- CCAP1L=200;
- delay(1000);
- NPN1=0; NPN2=0; NPN3=1;
- CCAP1H=70;//占空比控制
- CCAP1L=70;
- delay(1000);
- NPN1=0; NPN2=0; NPN3=1;
- CCAP1H=70;//占空比控制
- CCAP1L=70;
- delay(1000);
- NPN1=0; NPN2=1; NPN3=0;
- CCAP1H=200;//占空比控制
- CCAP1L=200;
- delay(1000);
- NPN1=1; NPN2=0; NPN3=0;
- CCAP1H=254;//占空比控制
- CCAP1L=254;
- delay(1000);
- if(IRok) //判斷脈寬是否檢測(cè)完畢
- {
- IRcordpro();//根據(jù)脈寬解碼出4個(gè)字節(jié)的數(shù)據(jù)
- IRok = 0; //重新等待脈寬檢測(cè)
- if(IRpro_ok) //判斷是否解碼完畢
- {
- if(IRcord[2]==0x18)
- {
-
-
- NPN1=0; NPN2=0; NPN3=0; NPNhuxi=0;
- hz_lcdDis(0,0,"Close");
- beep = 0; delay(15); beep = 1; //按鍵 上 按鍵返回
- break;
- }
- if(IRcord[2]==0x45){
- beep = 0; delay(15); beep = 1;
- displayTime30huxi(5);
- beep = 0; delay(15); beep = 1;
- break;
- }
- if(IRcord[2]==0x46){
- beep = 0; delay(15); beep = 1;
- displayTime30huxi(10);
- beep = 0; delay(15); beep = 1;
- break;
- }
- if(IRcord[2]==0x47){
- beep = 0; delay(15); beep = 1;
- displayTime30huxi(15);
- beep = 0; delay(15); beep = 1;
- break;
- }
- IRpro_ok = 0;
- }
- }
- }
- }
- void main()
- {
- init_pwm();
- lcd1602_init();
- NPN1=0; NPN2=0; NPN3=0;NPNhuxi=0;
- delay(750);
- lcd_Write_com(0x01); //清屏
- hz_lcdDis(0,0,"Close Timer Z");
- hz_lcdDis(1,0,"LV=0 Long=000s");
- TR1 = 0;//時(shí)間到關(guān)閉定時(shí)器1
- TR1 = 1;//啟動(dòng)T1
- TMOD |= 0x10;//T1為定時(shí)器,工作模式1 16位計(jì)數(shù)器
- TH1 = 0x4b;
- TL1 = 0xfc;//0x4bfc 定時(shí)50ms
- EA = 1;//總中斷允許
- TMOD |= 0x02; //定時(shí)器0工作方式2,8位自動(dòng)重裝
- TH0 = 0x00; //高8位裝入0那么定時(shí)器溢出一次的時(shí)間是256個(gè)機(jī)器周期
- TL0 = 0x00;
- ET0 = 1; //定時(shí)器0中斷
- TR0 = 1; //啟動(dòng)定時(shí)器0
- IT0 = 1; //設(shè)置外部中斷0為跳沿觸發(fā)方式,來(lái)一個(gè)下降沿觸發(fā)一次
- EX0 = 1; //啟動(dòng)外部中斷0
- //delay(2000);
- while(1)
- {
-
- if(IRok) //判斷脈寬是否檢測(cè)完畢
- {
- IRcordpro();//根據(jù)脈寬解碼出4個(gè)字節(jié)的數(shù)據(jù)
- IRok = 0; //重新等待脈寬檢測(cè)
- if(IRpro_ok) //判斷是否解碼完畢
- {
- switch(IRcord[2])
- {
- case 0x45: //按鍵1 定時(shí)30分鐘
- displayTime30(5);
- beep = 0; delay(15); beep = 1;
- break;
- case 0x46: //按鍵2 定時(shí)1小時(shí)
- displayTime30(10);
- beep = 0; delay(15); beep = 1;
- break;
- case 0x47: //按鍵3 定時(shí)1.5小時(shí)
- displayTime30(15);
- beep = 0; delay(15); beep = 1;
- break;
-
- case 0x18: NPN1=0; NPN2=0; NPN3=0; NPNhuxi=0;
- CCAP1H=255;//占空比控制
- CCAP1L=255;
- hz_lcdDis(0,0,"Close Timer Z");
- hz_lcdDis(1,0,"LV=0 Long=000s");
- beep = 0; delay(15); beep = 1; //按鍵 上 關(guān)機(jī)按鍵
- break;
- case 0x08: NPN1=1; NPN2=0; NPN3=0; NPNhuxi=0;
- CCAP1H=140;//占空比控制
- CCAP1L=140;
- hz_lcdDis(0,0,"Open ");
- hz_lcdDis(1,3,"1");
- beep = 0; delay(15); beep = 1; //按鍵 左 抵擋速度
- break;
- case 0x1C: NPN1=0; NPN2=1; NPN3=0; NPNhuxi=0;
- CCAP1H=190;//占空比控制
- CCAP1L=190;
- hz_lcdDis(0,0,"Open ");
- hz_lcdDis(1,3,"2");
- beep = 0; delay(15); beep = 1; //按鍵 中 中擋速度
- break;
- case 0x5A: NPN1=0; NPN2=0; NPN3=1; NPNhuxi=0;
- CCAP1H=254;//占空比控制
- CCAP1L=254;
- hz_lcdDis(0,0,"Open ");
- hz_lcdDis(1,3,"3");
- beep = 0; delay(15); beep = 1; //按鍵 右 高檔速度
- break;
- case 0x52:
- hz_lcdDis(0,0,"Open ");
- hz_lcdDis(0,15,"H");
- hz_lcdDis(1,3,"S");
- huxi();
- beep = 0; delay(15); beep = 1; //按鍵 右 呼吸
- break;
- }
- IRpro_ok = 0;
- }
- }
-
- }
- }
復(fù)制代碼
所有資料51hei提供下載:
stc12c5a60s2紅外PWM可調(diào)占空比.zip
(52.18 KB, 下載次數(shù): 125)
2019-5-22 08:56 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
|
評(píng)分
-
查看全部評(píng)分
|