电路原理图如下:
制作说明:
这个电路采用15W104单片机通过红外遥控器控制电风扇。
在初次使用时,首先进行按键学码。
学码方法:找一个闲置的红外遥控器,选择两个好用的按键,按住其中一个遥控
按键不放约6秒,蜂鸣器响一声,表明学习完成。同样方法学习另外一个遥控按键。
正常使用时,短按一下已学习的按键即可控制对应的开关反转,蜂鸣器会响一声。
第一个学习的按键为风扇开关,开后吹风3小时会自动关闭,防止长开。第二个学
习的按键为自然风开关,自然风启动后电扇吹7秒停3秒,再按关闭自然风。由于使用
延时控制,开自然风后遥控反应会延迟。
如果需要换别的遥控按键或另外一个遥控器,重新上述操作,即可删除旧的按键,
使用新的按键。
红外接收端为1脚。输出端为5脚,低电平为工作态。蜂鸣器接8脚,低电平为工作
态。
落地扇或台扇一般有3个档位,实际制作时可将其中一个档位改成遥控,另外两个
仍用手动。我是将最慢的1档改成了遥控。
电路图是借用别人的,程序也是应邀修改的,只要把8脚的led指示灯换成蜂鸣器即
可。当然不换也行,看各人爱好。程序不会冲突,指示灯和蜂鸣器都是低电平工作。
单片机源程序如下:
- #define CPU_Fosc 11059200uL //定义时钟,自适应解码和延时用
- #include <REG51.h>
- #include<EROM_STC10_11_15.h>
- #include<intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define USER_H 0x80 //用户码高8位
- #define USER_L 0x7F //用户码低8位
- #define Check_EN 0 //是否要校验16位用户码:不校验填0,校验则填1
- #define CA_S 40 //长按时间设置,单位:108mS(即 108mS整数倍,10倍以上为宜)
- /*┈┈┈┈┈┈┈┈┈┈ 基准 ┈┈┈┈┈┈┈┈┈┈┈*/
- #define Boot_Limit (((9000+4500) +2000)/Step) //引导码周期上限
- #define Boot_Lower (((9000+4500) -2000)/Step) //引导码周期下限
- #define Bit1_Limit ((2250 +800)/Step) //“1”周期上限
- #define Bit0_Limit ((1125 +400)/Step) //“0”周期上限
- #define Step 400//红外采样步长:400us
- #define TH_H ((65536-Step*(CPU_Fosc/300)/40000)/256) //定时器高8位基准赋值
- #define TH_L ((65536-Step*(CPU_Fosc/300)/40000)%256) //定时器低8位基准赋值
- sfr P3M0 = 0xB2; //0000,0000 端口3模式寄存器0
- sfr P3M1 = 0xB1; //0000,0000 端口3模式寄存器1
- uint IR_BT; //解码效果返回:0无效,1有效,2短按,3长按
- uchar NEC[4]; //解码存放:16位用户码、操作码正反码
- uint cntCA; //长按计数
- uint cntStep; //步数计
- bit IRa,IRb; //电位状态保存
- bit IRsync; //同步标志
- bit bz1,bz2,bz3,bz4;
- bit m1,m2; //红外输入键值变量
- uint BitN; //位码装载数
- uchar num1,num2,num3,num4;
- uchar aa;
- float tm;
- /********************************************/
- sbit out_1 = P3^0; //输出1
- sbit BE = P3^3; //蜂鸣器
- sbit IR = P3^4; //定义红外线接口(任意引脚)
- /************************************************/
- //========================================================================
- // 函数: void delayms(unsigned int ms)
- // 描述: 延时函数。
- // 参数: ms,要延时的ms数, 这里只支持1~65535ms. 自动适应主时钟.
- // 返回: none.
- // 版本: VER1.0
- // 日期: 2013-4-1
- // 备注:
- //========================================================================
- void DelayMs(unsigned int ms)
- {
- unsigned int i;
- do{
- i = CPU_Fosc / 13000;
- while(--i) ; //14T per loop
- }while(--ms);
- }
- /****************蜂鸣器*************************/
- void beep()
- {
- BE=0;
- DelayMs(500);
- BE=1;
- }
- /***************写数据 ***************************/
- void W_W_1(void)//写数据
- {
- num1 = NEC[2];
- EA = 0; //关中断
- EROM_C(0); //读擦除EPPROM
- EROM_W(0,5,num1); //写EPPROM
- num2 = EROM_R(0,5); //读EPPROM
- EA = 1; //开中断
- }
- /**************写数据 ****************************/
- void W_W_2(void)//写数据
- {
- num3 = NEC[2];
- EA = 0; //关中断
- EROM_C(1); //读擦除EPPROM
- EROM_W(1,10,num3); //写EPPROM
- num4 = EROM_R(1,10); //读EPPROM
- EA = 1; //开中断
- }
- /****************遥控短按处理*************************/
- void KZ0()//函数:遥控短按处理
- {
- beep();
- num2 = EROM_R(0,5); //读EPPROM
- num4 = EROM_R(1,10);
- if(num2 == num1)
- {
- // bz3 = m1;
- // out_1 = ~out_1;
- m1=~m1;
- }
- if(num4 == num3)
- {
- m2=~m2;
- }
- }
- /*****************遥控长按处理********************/
- void KZ1()//函数:遥控长按处理
- {
- beep();
- //m2 = 1;
- //m1 = 1;
- aa ++;
- if(aa == 1)
- {
- W_W_1();//读写程序
- }
- if(aa == 2)
- {
- W_W_2();//读写程序
- aa = 0;
- }
-
- }
- /****************红外解码初始化************************/
- void IR_Init() //红外线解码初始化
- {
- TMOD &= 0xF0; //清定时器0
- TMOD |= 0x01; //定时器0:16位定时器
- TL0 = TH_L; //每步时间
- TH0 = TH_H;
- ET0 = 1;
- EA = 1;
- TR0 = 1;
- }
- /****************主函数*************************/
- void main(void)
- {
- P3M0 = 0x03; //
- P3M1 = 0x00; //
- m1 = 0;
- m2 = 0;
- BE=1;
- IR_Init(); //红外线解码初始化
- num2 = EROM_R(0,5); //读EPPROM
- num4 = EROM_R(1,10); //读EPPROM
- while(1)
- {
- if((IR_BT == 2) || (IR_BT == 3))//遥控检测
- {
- tm=0; //有操作,开机时间清0
- if(IR_BT == 2)
- KZ0(); //短按处理
- else
- KZ1(); //长按处理
- IR_BT = 0; //清有效标志
- }
- if(tm>27000000) //风扇开启3小时后关闭(3*3600*1000000us/400us=27000000次)
- {
- m1=1; //风扇停电
- tm=27000001; //停止计时防止溢出
- }
- out_1=~m1;
- if(m1==1)
- {
- if(m2==1)
- {
- DelayMs(7000); //风扇通电7s
- out_1=1;
- DelayMs(3000); //风扇停电3s
- }
- }
- }
- }
- /********************** 定时器0中断函数************************/
- void time0(void) interrupt 1
- {
- TL0 = TH_L; //重赋值
- TH0 = TH_H;
- IRb = IRa; //上次电位状态
- IRa = IR; //当前电位状态
- tm ++;
- cntStep ++;
- if(IR_BT == 1)
- if(cntStep > 300)
- IR_BT = 2;//解码有效后,如果无长按,120ms(400us×300)后默认短按
- if(IRb && !IRa) //是否下降沿(上次高,当前低)
- {
- if(cntStep > Boot_Limit) //超过同步时间?
- {
- if(IR_BT == 1) //解码有效后,继续按住遥控>CA_S即长按
- if(++ cntCA > CA_S)
- IR_BT = 3;
- IRsync = 0; //同步位清0
- }
- else
- if(cntStep > Boot_Lower)
- {
- IRsync = 1; //同步位置1,装载位码数
- BitN = 32;
- }
- else
- if(IRsync) //如果已同步
- {
- if(cntStep > Bit1_Limit)
- IRsync = 0;
- else
- {
- NEC[3] >>= 1;
- if(cntStep > Bit0_Limit)NEC[3] |= 0x80; //“0”与“1”
- if(-- BitN == 0)
- {
- IRsync = 0; //同步位清0
- #if (Check_EN == 1)
- if((NEC[0] == USER_H) && (NEC[1] == USER_L) && (NEC[2] == ~NEC[3])) //校验16位用户码、操作码正反码
- {
- IR_BT = 1; //解码有效,接下来判断:短按?长按?
- cntCA = 0;
- }
- #else
- if(NEC[2] == ~NEC[3])//校验操作码正反码
- {
- IR_BT = 1;
- cntCA = 0;
- }
- #endif
- }
- else
- if((BitN & 0x07) == 0)//NEC[3]每装满8位,移动保存一次(即 BitN%8 == 0)
- {
- NEC[0] = NEC[1];
- NEC[1] = NEC[2];
- NEC[2] = NEC[3];
- }
- }
- }
- cntStep = 0; //步数计清0
- }
- /******************************************/
- if(IR_BT == 1)//写键值指示
- {
- num1 = NEC[2];
- }
- /*****************************************/
- if(IR_BT == 1)//写键值指示
- {
- num3 = NEC[2];
- }
- }
复制代码
所有资料51hei提供下载:
两路学习型风扇遥控开关带自然风6.rar
(51.48 KB, 下载次数: 150)
|