晒一下用 STC15F104E 做的 2路红外线遥控双开关插座,+ 定时 + LED指示剩余时间 + (支
①支持单NEC遥控 和 NEC、RC5双遥控,通过长按(>6秒)K1键切换,EEOPROM保存设置。②K1、K2按键:长按(>1秒):打开/关闭 开关,
短按: 每按一次,定时 加30分钟(开关打开后,定时加才有效)
③定时的时候,对应LED规律点亮指示剩余时间:
剩余时间 >10分钟时,慢闪,闪一次表示10分钟,闪完后停顿几秒后重新指示,
在剩余2~10分钟时变长亮,
最后2分钟快速闪烁。
遥控器:
http://cache.amobbs.com/bbs_upload782111/files_45/ourdev_672302LKNHOH.jpg
(原文件名:20110819103.jpg)
http://cache.amobbs.com/bbs_upload782111/files_45/ourdev_672303W3V3QD.jpg
(原文件名:20110819099.jpg)
2路红外线遥控双开关插座:
http://cache.amobbs.com/bbs_upload782111/files_45/ourdev_672304QI78FJ.jpg
(原文件名:20110829104.jpg)
http://cache.amobbs.com/bbs_upload782111/files_45/ourdev_672305MMRO0V.jpg
(原文件名:20110829105.jpg)
http://cache.amobbs.com/bbs_upload782111/files_45/ourdev_672306QVS69U.jpg
(原文件名:20110829106.jpg)
//***************************************************************
// 作品:红外遥控双开关插座(支持NEC、RC5双遥控)
//单片机:STC15F104E
// 晶振:12M
//编译环境:Keil uVision4 V9.00
//***************************************************************
// 说明:STC15F104E(A版)外部中断有问题,用定时器1计数溢出中断代替
//
// 描述:①支持单NEC遥控 和 NEC、RC5双遥控,通过长按(>6秒)K1键切换,EEOPROM保存设置。
//
// ②K1、K2按键:长按(>1秒):打开/关闭 开关,
// 短按:每按一次定时 加30分钟(开关打开后,定时加才有效)
//
// ③定时的时候,对应LED规律点亮指示剩余时间:
// 剩余时间 >10分钟时,慢闪,闪一次表示10分钟,闪完后停顿几秒后重新指示,
// 在剩余2~10分钟时变长亮,
// 最后2分钟快速闪烁。
//
// ④使用可控硅循环打开 可调范围:开0.5秒~10秒,关0.5秒~10秒
//
#define uchar unsigned char
#define uintunsigned int
#define ulong unsigned long
#include <STC15F104E.H>
#include <EROM_STC10_11_15.H>
#include <IR_NEC_1T.H>
#include <IR_RC5_1T.H>
sbit LED3= P3^0; //白LED指示灯,可控硅间断/遥控/极限指示灯
sbit JZ = P3^1; //继电器
sbit K1 = P3^2; //按钮1(继电器开关),红LED指示灯
sbit K2 = P3^3; //按钮2(可控硅开关),黄LED指示灯
sbit GZ = P3^4; //可控硅
uchar t; //按键计数
uchar cnt0,cnt1; //时间段划分
uint Wcnt; //计数
ulong WN;
uchar JB0; //继电器延时标志
uchar jzT; //继电器延时时间
uchar J0,J1;
bit LED1; //按钮1 红指示灯
uchar GB0; //可控硅延时标志
uchar gzT; //可控硅延时时间
uchar G0,G1,G3,G4,G5;
bit LED2; //按钮2 黄指示灯
bit GB3; //可控硅间断标志
uchar gnk,gng; //间断开关时间计数
uchar kai,guan; //间断开关时间存放
voidshanshuo(uchar x); //闪烁程序
voidKEY(void);
voidW_W(void);
voidJZ_KG(void);
voidJZ_YS(void);
voidGZ_KG(void);
voidGZ_YS(void);
voidJ_SS();
voidNEC_KZ(uchar n);
voidRC5_KZ(uchar n);
/***************************************************************
函数:按键消抖 延时程序
入口:1mS×z (12MHz)
***************************************************************/
void YS(uchar z)
{
uchar i,j,k;
for(i=z;i!=0;i--)
for(j=18;j!=0;j--)
for(k=165;k!=0;k--);
}
/*************指示灯闪烁程序1***************/
void shanshuo(uchar x)
{
uchar i;
for(i=0;i<x;i++)
{
LED3=!LED3;
YS(50);
}
}
/***************** 主函数 ********************/
void main(void)
{
P33=1;
JB0=GB0=GB3=0;
G3=G4=G5=0;
WN = EROM_R(1,6);
TMOD= 0x40; //T0、T1:(0模式)16位重载定时器,C/T TMOD.6=1,T1用作计数器(从T1/P3.5脚输入)
TH0 = (65536-50000)>>8;
TL0 = (65536-50000); //50mS
TH1 = 0xff;
TL1 = 0xff; //一按下马上计数溢出中断
PT1 = 1; //T1高优先级
ET1 = 1; //打开T1中断
ET0 = 1; //打开T0中断
EA= 1; //打开中断总闸
TR0 = 1;
TR1 = 1;
WDT_CONR=0x3f; // 清0,启动看门狗,预分频数=256,约8S(@12MHz)
while(1)
{
KEY();
YS(6); //稍微延时
WDT_CONR |= 0x10; //清看门狗
if(++Wcnt > 100000) //约10min读取一次
{
Wcnt = 0;
EA = 0;
WN = EROM_R(1,6);
EA = 1;
}
}
}
///////////////////////////////////
void KEY(void)
{
K1= 1;
_nop_();
if(!K1)
{
YS(10); //10mS
if(!K1)
{
t=0;
while(!K1)
{
if(t++ > 120)break; //6S
YS(50); //50mS
}
if (t>20) JZ_KG(); //1S
else if(JZ==0) JZ_YS();
}
}
if(LED1)K1=0;
else K1=1;
////////////////可控硅/////////////////
K2= 1;
_nop_();
if(!K2)
{
YS(10);
if(!K2)
{
t=0;
while(!K2)
{
if(t++ > 120)break;
YS(50); //50mS
}
if (t>120) W_W();
else if(t>20)GZ_KG();
else if(GZ==0) GZ_YS();
}
}
if(LED2)K2=0;
else K2=1;
}
///////////////////////////////////
void W_W(void)
{
EA = 0;
if(WN == 6) EROM_C(1);
else { EROM_C(1);
EROM_W(1,6,6); }
WN = EROM_R(1,6);
EA = 1;
if(WN == 6)shanshuo(100); //NEC、RC5双遥控模式 设置成功闪烁指示
else shanshuo(22); //单NEC遥控 设置成功闪烁指示
}
///////////////////////////////////
void JZ_KG(void)
{
if(JB0) //如果已经打开延时则关闭延时
{
JB0=0; //继电器延时标志位 关闭
LED1 =0; //指示灯 关闭
jzT=0;
JZ =0; //转成一直开
}
else JZ = !JZ;
}
///////////////////////////////////
void JZ_YS(void)
{
JB0= 1; //继电器延时标志位 打开
J1 = 0;
jzT += 30; //每次加30min
if(jzT > 220) //大于220min时不再加30min,直接=240min
{
jzT = 240; //继电器延时时间=240min
shanshuo(100); //上限闪烁指示
}
}
///////////////////////////////////
void GZ_KG(void)
{
if(GB0 || GB3) //如果已经打开延时/间断则关闭
{
GB0=0; //可控硅延时标志位 关闭
GB3=0; //可控硅间断标志位 关闭
LED2 =0; //延时指示灯 关闭
LED3 =1; //间断指示灯 关闭
gzT=0; //可控硅延时时间清0
GZ = 0; //转成一直开
}
else GZ = !GZ;
}
///////////////////////////////////
void GZ_YS(void)
{
GB0= 1; //可控硅延时标志位 打开
G1 = 0; //闪烁计数
gzT += 30; //每次加30min
if(gzT > 220) //大于220min时不再加30min,直接=240min
{
gzT = 240; //可控硅延时时间=240min
shanshuo(100); //上限闪烁指示
}
}
/*************** 间断指示灯闪烁 ********************/
void J_SS()
{
if(G3==0)
{
if(G4++ < kai*2)LED3 = !LED3;
else
{
G5++;
if(G5 > 6)LED3 = 0;
if(G5 > 12){G3=1; G4=G5=0;}
}
}
else
{
if(G4++ < guan*2)LED3 = !LED3;
else
{
G5++;
if(G5 > 6)LED3 = 1;
if(G5 > 12){G3=0; G4=G5=0;}
}
}
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数:T0中断函数
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void Timer0_Rountine(void) interrupt 1
{
if(JB0==3)LED1 = !LED1;
if(GB0==3)LED2 = !LED2;
if(cnt0++ < 10)return;//////////////50mS ×10 =0.5S
cnt0 = 0;
/*┈┈┈┈ 可控硅间断 ┈┈┈┈*/
if(GB3)
{
if (gnk < kai) {GZ=0;gnk++;} //开
else if(gng++ < guan) GZ=1; //关
if(gng >= guan)gnk=gng=0;
J_SS(); //间断指示灯闪烁
}
/*┈┈┈┈ LED1闪烁 ┈┈┈*/
if((JB0==1)||(JB0==2))
{
if(jzT>9) J0=jzT/10; //更新计算闪烁次数,闪一次代表10min
else if(jzT>2){JB0=2;LED1=1;} //最后2~9分钟,指示灯一直亮提示
else JB0=3;
if(JB0==1)
{
if(LED1) LED1=0;
else {if(J1++ < J0)LED1=1;
else if(J1 > J0+4)J1=0;
}
}
}
/*┈┈┈┈ LED2闪烁 ┈┈┈*/
if((GB0==1)||(GB0==2))
{
if(gzT>9)G0=gzT/10; //更新计算闪烁次数,闪一次代表10min
else if(gzT>2){GB0=2;LED2=1;} //最后2~9分钟,指示灯一直亮提示
else GB0=3;
if(GB0==1)
{
if(LED2) LED2=0;
else {if(G1++ < G0)LED2=1; //闪烁
else if(G1 > G0+4)G1=0; //闪烁完后稍停6S
}
}
}
if(cnt1++ < 120)return;//////////////////0.5S×120=1min
cnt1 = 0;
/*┈┈┈┈ 继电器延时检测 ┈┈┈┈*/
if(JB0)
{
jzT--;
if(jzT == 0)
{
JB0= 0; //继电器延时标志位 关闭
LED1 = 0; //指示灯 关闭
JZ=1; //继电器 关闭
}
}
/*┈┈┈┈ 可控硅延时检测 ┈┈┈┈*/
if(GB0)
{
gzT--;
if(gzT == 0) //是否到达设置时间
{
GB0= 0; //可控硅延时标志位 关闭
GB3= 0; //可控硅间断标志位 关闭
LED2 = 0; //指示灯 关闭
LED3 = 1; //间断指示灯 关闭
GZ = 1; //可控硅 关闭
}
}
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数:T1计数溢出中断函数
说明:红外线解码
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void Timer1(void) interrupt 3
{
EA = 0;
TR1 = 0;
TF1 = 0;
if(IR_NEC()==1)NEC_KZ(NEC); //调用NEC解码函数
else if(WN==6) //RC5、NEC双遥控是否打开
{
if(IR_RC5()==1)RC5_KZ(RC5); //调用RC5解码函数
}
EA = 1; //打开中断总闸
TR1 = 1;
}
/////////////////////////////
void G_ZZ(void)
{
G3=G4=G5=0;
LED3=1;
gnk=gng=0;
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数:NEC控制
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void NEC_KZ(uchar n)
{
uchar s=1;
switch(n)
{
case 0x12: JZ_KG(); // "POWER" 继电器 开/关
break;
case 0x1e: GZ_KG(); // ">‖" 可控硅 开/关
break;
case 0x01: JZ = 0; // "VOL+" 继电器打开
JZ_YS(); // 延时0.5/1/1.5/2/2.5/3/3.5/4小时
break;
case 0x03: GZ = 0; // "VOL-" 可控硅打开
GZ_YS(); // 延时0.5/1/1.5/2/2.5/3/3.5/4小时
break;
case 0x07: GB3=1; // "<" 可控硅间断标志位 打开
G_ZZ();
kai =1; // 开0.5S
guan=1; // 关0.5S
break;
case 0x08: GB3=1; // "M"
G_ZZ();
kai =1; // 开0.5S
guan=2; // 关1S
break;
case 0x09: GB3=1; // ">"
G_ZZ();
kai =2; // 开1S
guan=2; // 关1S
break;
case 0x05: kai++; // "▲" 开+0.5S
if(kai >= 20) // 上限10S
{
kai = 20;
shanshuo(100); //上限闪烁指示
}
G_ZZ();
break;
case 0x1b: guan++; // "▼" 关+0.5S
if(guan >= 20) // 上限10S
{
guan = 20;
shanshuo(100); //上限闪烁指示
}
else
G_ZZ();
break;
/////////////////////////////////////////////////////////////////////////
case 0x22: JZ = 0; //继电器打开
JZ_YS(); //0.5h
break;
case 0xE6: JZ = 0; //继电器打开
jzT = 30;
JZ_YS(); //0.5h+0.5h = 1h
break;
case 0x33: JZ = 0; //继电器打开
jzT = 90;
JZ_YS(); //1.5h+0.5h = 2h
break;
//////////////////////
case 0x55: GZ = 0; //可控硅打开
gzT = 90;
GZ_YS(); //1.5h+0.5h = 2h
break;
case 0x6b: GZ = 0; //可控硅打开
gzT = 210;
GZ_YS(); //3.5h+0.5h = 4h
break;
case 0x68: kai += 2; //开+1S
if(kai >= 20) //上限10S
{
kai = 20;
shanshuo(100); //上限闪烁指示
}
G_ZZ();
break;
case 0xE2: guan += 2; //关+1S
if(guan >= 20) //上限10S
{
guan = 20;
shanshuo(100); //上限闪烁指示
}
G_ZZ();
break;
default: s = 0;
break;
}
if(s)shanshuo(12);
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数:RC5控制
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void RC5_KZ(uchar n)
{
uchar s=1;
switch(n)
{
case 0x0C: if(GB0 || GB3) // "待机"
{
GB0=0; //可控硅延时标志位 关闭
GB3=0; //可控硅间断标志位 关闭
LED2 =0; //延时指示灯 关闭
LED3 =1; //间断指示灯 关闭
gzT=0; //可控硅延时时间清0
GZ =1; //转成关
}
else GZ = !GZ; //可控硅 开/关
break;
case 0x20: GZ= 0; // "1" 可控硅打开
gzT = 30;
GZ_YS(); //0.5h+0.5h = 1h
break;
case 0x10: GZ= 0; // "2" 可控硅打开
gzT = 90;
GZ_YS(); //1.5h+0.5h = 2h
break;
case 0x30: GZ= 0; // "3" 可控硅打开
gzT = 150;
GZ_YS(); //2.5h+0.5h = 3h
break;
case 0x08: GZ= 0; // "4" 可控硅打开
gzT = 210;
GZ_YS(); //3.5h+0.5h = 4h
break;
default: s = 0;
break;
}
if(s)shanshuo(12);
}
※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
红外解码头文件:
//***************************************************************
//
// 使用说明:NEC红外解码头文件,适用于STC 1T系列 @12MHz
//
//***************************************************************/
#ifndef __IR_NEC_1T_H__
#define __IR_NEC_1T_H__
#defineucharunsigned char
#defineuint unsigned int
#define SBM0x80 //用户码
sbit IR = P3^5; //红外接口
uchar NEC; //存放16位用户码、操作码正反码
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数:NEC解码
返回:“0”无效,“1”有效
补充:操作码存放在NEC
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
uchar IR_NEC()
{
uchar i;
uint cnt=0;
while(!IR)cnt++;
if(cnt < 6000)return 0; //检测9ms引导码
cnt = 0;
while(IR) if(cnt++ > 2200)return 0; //大于4.5ms则返回
if(cnt < 1900)return 0; //小于4.5ms则返回
for(i=0;i<32;i++) //读取32位编码
{
cnt = 0;
while(!IR);
while(IR) if(cnt++ > 1000)return 0; //防卡死,超时保护
NEC >>= 1;
if(cnt>600) NEC |= 0x80; //0与1
}
if((NEC==SBM)&&(~NEC==SBM)&&(NEC==~NEC))//校验用户码,操作码
{
return 1;
}
return 0;
}
#endif 等楼主发原理图 我也做了个,不过显示用的是5110的屏 不明白一下的,
如何避免同_房间的:空调、彩电、DVD等遥控器的干扰,很可能是同一编码么? 好东西. 回复【3楼】wkman 鱼片
-----------------------------------------------------------------------
空调、彩电、DVD等遥控器的干扰?
家用电器的各红外遥控器碰巧某编码相近 就可能出现互相遥控。
像我家空调(NEC 100多位编码)、彩电(RC5)、DVD(NEC)、机顶盒(NEC)的遥控器没有互扰现象,
虽然DVD、机顶盒的遥控器都采用NEC编码,但用户码不同,所以不会出现互扰。
至于自己做的红外遥控开关,比如用NEC编码,你使用自己的用户码,不和家中NEC编码式遥控器的用户码相同,
还有解码程序上一定要校验 16位用户码 和 操作码正反码 就没问题了,
如果你不知家中NEC编码式遥控器的用户码,也懒得去解码,
你可以在 自己的红外遥控 使用24位用户码+操作码正反码,这样和家遥控器碰巧相似几率≈0 mark 遥控器还制作啊,不好看,直接使用学习行的万能遥控器就好了,一个遥控器可以控制家里的全部带遥控的电器。 回复【楼主位】BXAK
-----------------------------------------------------------------------
强悍啊 回复【楼主位】BXAK
-----------------------------------------------------------------------
强悍啊 回复【楼主位】BXAK
-----------------------------------------------------------------------
#include <EROM_STC10_11_15.H>
这个头文件 有吗,能不能发个共享啊 回复【楼主位】BXAK
-----------------------------------------------------------------------
你好,
WN = EROM_R(1,6);这条指令功能是什么啊,我刚学习C,嘻嘻 回复【11楼】qincai_
-----------------------------------------------------------------------
他的EROM_R(1,6)是个函数,函数将运算后的值赋给WN 回复【楼主位】BXAK
-----------------------------------------------------------------------
我也晒一下我做的成品的红外/无线遥控开关
http://cache.amobbs.com/bbs_upload782111/files_46/ourdev_678957KA9CKX.jpg
(原文件名:双路继电器.jpg)
可用普通无线遥控器或红外遥控器来遥控 回复【10楼】qincai_
-----------------------------------------------------------------------
原来的已经没了,那个头文件已经修改了:
点击此处下载 ourdev_703886YPSRAQ.zip(文件大小:3K) (原文件名:A.zip)
数码之家那有一个帖子:“STC15F104查询方式-学习型1路红外遥控灯座”,电路图简单易懂,感兴趣可以去看看
http://bbs.mydigit.cn/read.php?tid=340185
http://cache.amobbs.com/bbs_upload782111/files_49/ourdev_703887LGG64M.jpg
(原文件名:108_623247_9665b5b73fa8b53.jpg)
回复【13楼】shizhijian 石志坚
-----------------------------------------------------------------------
还是用无线好啊
自己的遥控插座用了段时间,觉得红外太局限了,
不像315M无线距离远又可以穿墙,遥控器也小巧,可挂在钥匙上,等哪天淘宝了也买一对315M收发模块 是的,像我们这种懒人,用红外也有点麻烦,要对齐呀,改用315M无线吧,穿墙效果佳 记个号! 恩要看看的。 好想仿制一个,但下面的原理图对不上,郁闷了 够实用!刚好买到几个STC15F104E的51单片。试试去{:biggrin:} 拼音做函数,变量名直观易看,楼主是个高手,不同我这种就喜欢玩玩的菜鸟! 以前做的,已经淘汰资料早删了,
用3.3V的315M接收模块(工作电流300uA左右)和ATTiny13来做更省电更方便 把源程序打包发附件就爽了,这样编译不过。 只想说打孔太难看了,就算没有专业工具也不至于这样。 我也做过这个,15F104E做的,自学习型,TO92封装97A6可控硅方案,体积非常小,PCB上留了三路,软件里面上电后自动识别通道,一个指示灯,一个按键,一个红外,三个控制,6个IO口全部用上了。
只可惜这个芯片的外部中断有问题,还说什么B版本的是正常的,鬼晓得B版本又有什么别的问题。后来红外解码改查询方式了。
现在自己房里装了一个在用。 学习了,,谢谢楼主分享 不错学习学习 mark,标记 楼主的电源稳定、耐用不 好长的程序,读完累死了 学习,学习,再学习,实用才是硬道理!!! 保存下来了,有时间学习学习 有点意思, 做个贴纸更好看些,不过我也没找到那种纸打印后效果好
页:
[1]