完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
这个东西吧,就是单片机红外解码,然后控制继电器吸合从而控制灯产品,其实挺简单的,
我都在犹豫要不要发出来,想了想还是发上来吧,毕竟还是很实用的(我一直在用,因为床头没开关,这样随手遥控开关灯还是很方便的)。 其实遥控方式多种多样,蓝牙,WIFI,RF433,ZigBee,红外等等。 考虑到实用,以及成本等各种因素,最终选择了红外遥控。 因为不管是蓝牙,WIFI,RF433还是ZigBee,都需要手机遥控或者单独做一个遥控器,比如用蓝牙或者WIFI的时候,着急开灯,还得找到手机,解锁手机,打开APP,连接上设备,开灯。。。 太繁琐了,RF433和ZigBee呢则需要专门的遥控器,成本高,待机时间也不一定长。 红外则简单多了,这种遥控器简单又实惠,学单片机的几乎人人都有,对于开关灯这种只需要几个信号的设计来说是最好不过的了 同样接收电路也是相当的简单,一个接收头就搞定了。 选定了方案,接下来就是单片机了,这个设计太简单了,性能方面是没要求的,直接考虑最便宜又小巧的芯片。 说到价格和体积小巧,首先想到的就是STC8,STM8S003F3还有它的新唐替代品N76E003。 合计了一下还是选择STC8F2K08S2了,毕竟51太熟悉了,工程也简单。 然后就是代码,红外解析,串口打印,确保解码正确。。。 /******************************************************************************** * 描述: * * 遥控器接p3.2 * * *******************************************************************************/ #include #include #define PD 0x02 //PCON.1 ***it IRIN = P3 ^ 2; //红外接收器数据线 //***it RELAY= P1^4; //继电器驱动线 //***it BEEP = P1^5; //蜂鸣器驱动线 ***it lr = P1 ^ 1; //红外接收器数据线 ***it lr1 = P1 ^ 2; //红外接收器数据线 extern char flag; void IRdelay(char x); //x*0.14MS //void beep(); unsigned char IRCOM[7]; //extern unsigned char Y0; //extern char busy; /*******************************************************************/ void IRInit() { IT0 = 1; //使能INT1下降沿中断 EX0 = 1; //使能INT1中断 // IE |= 0x81; //允许总中断中断,使能 INT0 外部中断 // TCON |= 0x01; //触发方式为脉冲负边沿触发 IRIN = 1; //I/O口初始化 // RELAY=1; } /**********************************************************/ void IR_IN(void) interrupt 0 { unsigned char j, k, N = 0; EX0 = 0; IRdelay(15); if (IRIN == 1) { EX0 = 1; return; } //确认IR信号出现 while (!IRIN) //等IR变为高电平,跳过9ms的前导低电平信号。 { IRdelay(1); } for (j = 0; j < 4; j++) //收集四组数据 { for (k = 0; k < 8; k++) //每组数据有8位 { while (IRIN) //等 IR 变为低电平,跳过4.5ms的前导高电平信号。 { IRdelay(1); } while (!IRIN) //等 IR 变为高电平 { IRdelay(1); } while (IRIN) //计算IR高电平时长 { IRdelay(1); N++; if (N >= 30) { EX0 = 1; return; } //0.14ms计数过长自动离开。 } //高电平计数完毕 IRCOM[j] = IRCOM[j] >> 1; //数据最高位补“0” if (N >= 8) { IRCOM[j] = IRCOM[j] | 0x80; //数据最高位补“1” } N = 0; } } if (IRCOM[2] != ~IRCOM[3]) { EX0 = 1; return; } IRCOM[5] = IRCOM[2] & 0x0F; //取键码的低四位 IRCOM[6] = IRCOM[2] >> 4; //右移4次,高四位变为低四位 if(IRCOM[5] > 9) { IRCOM[5] = IRCOM[5] + 0x37; } else IRCOM[5] = IRCOM[5] + 0x30; if(IRCOM[6] > 9) { IRCOM[6] = IRCOM[6] + 0x37; } else IRCOM[6] = IRCOM[6] + 0x30; /* ;================================ ;****** 红外遥控器键值表 ****** ; 4c 0e 4d 0d ; 0f 4f 4e 0c ; 0b 4b 4a 08 ; 48 12 16 4C ; 40 48 04 00 ; 02 05 54 4D ; 0A 1E 0E 1A ; 1C 14 0F 0C 0x45 0x46 0x47 0x44 0x40 0x43 0x07 0x15 0x09 0x16 0x19 0x0d 0x0c 0x18 0x5e 0x08 0x1c 0x5a 0x42 0x52 0x4a ;================================ */ //SBUF=IRCOM[2]; switch(IRCOM[2]) { case 0x45: // case 0x46: // case 0x47: lr=1;lr1=1;flag=1; break; case 0x44: case 0x07: //lr=1;lr1=1;flag=1; break; case 0x16: if(flag == 1) { lr = 0; lr1 = 0; flag = 0; } else { lr = 1; lr1 = 1; flag = 1; } break; default: lr = 0; lr1 = 0; flag = 0; } EX0 = 1; _nop_(); _nop_(); // PCON = IDL; //MCU进入IDLE模式 PCON = PD; //MCU进入掉电模式 _nop_(); _nop_(); } /**********************************************************/ void IRdelay(unsigned char x) //x*0.14MS { unsigned char i; while(x--) { for (i = 0; i < 100; i++) {} } } 然后就是去掉串口程序(不去也没事儿,考虑到没啥用处了,本着低功耗原则就去掉了)加上继电器,指示灯(继电器吸合时,指示灯熄灭,继电器断开时,指示灯点亮),进行吸合判断,进入低功耗。。。 /******************************************************************************** * 描述: * * 遥控器接p3.2 * * LED接p1.1 继电器接p1.2 * * * *******************************************************************************/ #include #include #define NOP() _nop_() /* 定义空指令 */ sfr VOCTRL = 0xbb; #define IDL 0x01 //PCON.0 #define PD 0x02 //PCON.1 //测试工作频率为6MHz sfr T2L = 0xd7; sfr T2H = 0xd6; sfr AUXR = 0x8e; sfr P1M0 = 0x92; sfr P1M1 = 0x91; ***it lr = P1 ^ 1; //红外接收器数据线 ***it lr1 = P1 ^ 2; //红外接收器数据线 ***it key = P3 ^ 3; //红外接收器数据线 char flag = 0; extern void IRdelay(unsigned char x); //函数声名 extern void IRInit(); //extern 是引用IR.C中的函数 void IR_IN1(void) interrupt 2 { IRdelay(10); if(key == 0) { if(flag) { lr = 0; lr1 = 0; flag = 0; } else { lr = 1; lr1 = 1; flag = 1; } } while(key == 0); } main() { lr = 0; lr1 = 0; VOCTRL = 0x00; //掉电模式时使用内部SCC模块,功耗约1.5uA // VOCTRL = 0x80; //掉电模式时使用外部SCC模块,功耗约0.15u IRInit(); P1M0 = 0xff; //设置P1.0~P1.7为推挽输出模式 P1M1 = 0x00; IT1 = 1; //使能INT1下降沿中断 EX1 = 1; //使能INT1中断 key = 1; EA = 1; lr = 0; lr1 = 0; while(1) { _nop_(); _nop_(); // PCON = IDL; //MCU进入IDLE模式 PCON = PD; //MCU进入掉电模式 _nop_(); _nop_(); } } 就这么简单,完事儿啦,接着进行画PCB,集成化,小型化 因为涉及到220V家庭用电,所以还得考虑安全性,于是使用了集成封装的220转5V电源模块,继电器使用的是10A 250VAC SRD-05VDC 焊接好实物图如下 测试功能没问题,由于程序功能简单,使用STC8的内部IRC晶振频率6MHz,如果使用其他频率,修改红外时序IRdelay()函数里的延时即可。 |
|
|
|
只有小组成员才能发言,加入小组>>
imx6ull 和 lan8742 工作起来不正常, ping 老是丢包
2481 浏览 0 评论
3341 浏览 9 评论
3022 浏览 16 评论
3514 浏览 1 评论
9119 浏览 16 评论
1243浏览 3评论
636浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
627浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2375浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1938浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-1-25 02:39 , Processed in 1.361414 second(s), Total 77, Slave 58 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号