>>(u*2)) & 3)==2) {i=80;break;}} //有10则为1527
if(i==80) break;
}
if(i==80) //1527
{
key_d=da1527[1][2] & 0x0f; //分出1527的按键值
da1527[0][2]=da1527[1][2]>>4; //分出1527的后4位地址
jmnx=1; //为0是2262,1是1527
}
else //2262
{
key_d=0;
for(i=0;i<4;i++){if(((da1527[0][2]>>(i*2))&3)==3) key_d|=1<<i;} //计算出2262的按键数据
da1527[0][2]=0x00; //2262无后4位地址,全为0
jmnx=0; //为0是2262,1是1527
jk++;//自锁用,作用:按下按键不松手继电器状态不变,松开再按下改变,一次只改变一次状态,因为按下按键后遥控会一直发码,所以让jk一直自加,但是只取jk=1的值的状态
}
if (!study) //非学习状态
{
rf_ok=0;
for(x=0;x<60;x++)
{
if((da1527[0][0]==key_number[x*3+1])&&(da1527[0][1]==key_number[x*3+2])
&&(da1527[0][2]==key_number[x*3+3]))//判断是否已学习过的编码
{
// D0=!(key_d&0x08); //取得按键码
// D1=!(key_d&0x04);
// D2=!(key_d&0x02);
// D3=!(key_d&0x01);
if(m==1) //互锁
{
if(key_d == 0x01){D0=0;D1=1;D2=1;D3=1;}//D4=1;D5=1;D6=1;D7=1;D8=1;D9=1;D10=1;D11=1;}//else{D0=1;}
if(key_d == 0x02){D0=1;D1=0;D2=1;D3=1;}//D4=1;D5=1;D6=1;D7=1;D8=1;D9=1;D10=1;D11=1;}
// if(key_d == 0x03){D0=1;D1=1;D2=0;D3=1;D4=1;D5=1;D6=1;D7=1;D8=1;D9=1;D10=1;D11=1;}
if(key_d == 0x04){D0=1;D1=1;D2=0;D3=1;}//D4=1;D5=1;D6=1;D7=1;D8=1;D9=1;D10=1;D11=1;}
// if(key_d == 0x05){D0=1;D1=1;D2=1;D3=1;D4=0;D5=1;D6=1;D7=1;D8=1;D9=1;D10=1;D11=1;}
// if(key_d == 0x06){D0=1;D1=1;D2=1;D3=1;D4=1;D5=0;D6=1;D7=1;D8=1;D9=1;D10=1;D11=1;}
// if(key_d == 0x07){D0=1;D1=1;D2=1;D3=1;D4=1;D5=1;D6=0;D7=1;D8=1;D9=1;D10=1;D11=1;}
if(key_d == 0x08){D0=1;D1=1;D2=1;D3=0;}//D4=1;D5=1;D6=1;D7=0;D8=1;D9=1;D10=1;D11=1;}
// if(key_d == 0x09){D0=1;D1=1;D2=1;D3=1;D4=1;D5=1;D6=1;D7=1;D8=0;D9=1;D10=1;D11=1;}
// if(key_d == 0x0a){D0=1;D1=1;D2=1;D3=1;D4=1;D5=1;D6=1;D7=1;D8=1;D9=0;D10=1;D11=1;}
// if(key_d == 0x0b){D0=1;D1=1;D2=1;D3=1;D4=1;D5=1;D6=1;D7=1;D8=1;D9=1;D10=0;D11=1;}
// if(key_d == 0x0c){D0=1;D1=1;D2=1;D3=1;D4=1;D5=1;D6=1;D7=1;D8=1;D9=1;D10=1;D11=0;}
}
else
{
if(ba==0) //B按键自锁
{
if(key_d == 0x04)
{
if(jk==1)
{
D2=~D2;
}
}
} //B自锁
if(da==0) //A按键自锁
{
if(key_d == 0x08)
{
if(jk==1)
{
D3=~D3;
}
}
} //A自锁
if(ca==0) //C按键自锁
{
if(key_d == 0x02)
{
if(jk==1)
{
D1=~D1;
}
}
} //C自锁
if(ea==0) //D按键自锁
{
if(key_d == 0x01)
{
if(jk==1)
{
D0=~D0;
}
}
} //D自锁
if(ba==1)//B按键点动,ba为自锁转点动标志位
{
if(key_d == 0x04){D2=0;}
}
if(da==1)//A按键点动,da为自锁转点动标志位
{
if(key_d == 0x08){D3=0;}
}
if(ca==1)//C按键点动,da为自锁转点动标志位
{
if(key_d == 0x02){D1=0;}
}
if(ea==1)//D按键点动,da为自锁转点动标志位
{
if(key_d == 0x01){D0=0;}
}
}
decode_ok=1;
ss=1;
sn=1;
sj=1;
so=1;
VT=0;
s=30;
break;
}
}
}
}
}
if(decode_ok) //解码有效信号,类似2272 PT脚
{
s--;
if(!s)
{
jk=0; //按一下按键只做一次动作信号没有后清零
decode_ok=0;
if(h==1){ss=2;} //点动标志位
if(hh==1){sn=2;}
if(hk==1){sj=2;}//点动标志位
if(hu==1){so=2;}
VT=1;
}
}
}
void key_buffer() //把遥控器码从 EEPROM 复制到DATA
{
uchar n;
for(n=0;n<181;n++)
{
key_number[n]=read_add(0x0000+n);
}
}
void KEY_study() //遥控器学习
{
uchar num_rf;
uint d_num;
if(study)
{
rf_ok=0;
d_num=0;
while(!rf_ok)
{
RF_decode();
d_num++;
if(d_num>50000) break;
}
d_num=0;
if(rf_ok==1)
{
num_rf=key_number[0]; //取已学习的遥控器数量
if(num_rf>60){num_rf=0;} //如果遥控器数量超过10个,覆盖最先学习的
key_number[num_rf*3+1]=da1527[0][0];
key_number[num_rf*3+2]=da1527[0][1];
key_number[num_rf*3+3]=da1527[0][2];
key_number[0]=num_rf+1;
Sector_Erase(0x0000);
for(num_rf=0;num_rf<181;num_rf++)
{
write_add(0x0000+num_rf,key_number[num_rf]);
}
rf_ok=0;
LED=1; //学习成功
}
else
{
rf_ok=0;
for(num_rf=0;num_rf<8;num_rf++) //操作超时
{
LED=!LED;
delay_1ms(100);
}
LED=1;
}
d_num=0;
study=0;
}
}
void system_res() //系统清零
{
Sector_Erase(0x0000);
write_add(0x0000,0x00);
key_buffer();
}
void set_scan() //判断学习键状态
{
uchar h=0;
while(!set)
{
if(h>5)
{
study=1;
h=0;
LED=0;
while(!set)
{
delay_1ms(100);
h++;
if(h>80)
{
study=0;
h=0;
system_res();
LED=1;
while(!set);
}
}
}
delay_1ms(100);
h++;
}
if(study)
{
KEY_study();
}
}
/*******************************************************************
* 按键读取
********************************************************************/
void KeyRead()//读取按键IO口函数
{
ReadData = aj1^0xff; // 读取按键状态取反后赋值给ReadData
trg = ReadData & (ReadData ^ cont); //trg短按,每按下按键trg=1;抬手后为trg=0,长按为trg=0
cont = ReadData; //cont长按,长按cont=1,抬手后cont=0
/*******************************************************************/
ReadData_1 = aj2^0xff; // 读取按键状态取反后赋值给ReadData
trg_1 = ReadData_1 & (ReadData_1 ^ cont_1); //trg短按,每按下按键trg=1;抬手后为trg=0,长按为trg=0
cont_1 = ReadData_1; //cont长按,长按cont=1,抬手后cont=0
/*******************************************************************/
ReadData_2 = aj3^0xff; // 读取按键状态取反后赋值给ReadData
trg_2 = ReadData_2 & (ReadData_2 ^ cont_2); //trg短按,每按下按键trg=1;抬手后为trg=0,长按为trg=0
cont_2 = ReadData_2; //cont长按,长按cont=1,抬手后cont=0
/*******************************************************************/
ReadData_3 = aj4^0xff; // 读取按键状态取反后赋值给ReadData
trg_3 = ReadData_3 & (ReadData_3 ^ cont_3); //trg短按,每按下按键trg=1;抬手后为trg=0,长按为trg=0
cont_3 = ReadData_3; //cont长按,长按cont=1,抬手后cont=0
}
/*******************************************************************
* A按键
********************************************************************/
void key_1()
{
if(trg & 0x01) //短按
{ rv=0; //长按延时标志位防止短按到200次后长按启动
biao=0; //这是长按屏蔽短按标志位
g=0; //这是长按只执行一次标志位
kt=1; //这是短按标志位,kt=1说明短按了
}
if((aj1!=0)&&(kt==1)&&(biao==0))//判断
{
D3=~D3;kt=0;
} // 短按
if((cont & 0x01)&&(g==0))//长按
{
rv++; //长按延时
if(rv>200)
{
biao=1; //屏蔽短按
hm=1;
yz+=1;//选位标志位
if(yz==1){h=1;da=1;za=0;hm=0;}
if(yz==2){h=2;m=1;yy=0;yk=0;yu=0;hh=0;hk=0;hu=0;ba=0;ca=0;ea=0;da=0;za=0;}
if(yz==3){
yz=0; //选位标志重个位开始重新选
h=0;
m=0;za=0;
}
g=1; //只让输出一次
rv=0; //延时时间归零
}
}//长按
}
/*******************************************************************
* B选位按键
********************************************************************/
void key_2()
{
if(trg_1 & 0x01) //短按
{ rv_1=0; //长按延时标志位防止短按到200次后长按启动
biao_1=0; //这是长按屏蔽短按标志位
g_1=0; //这是长按只执行一次标志位
kt_1=1; //这是短按标志位,kt=1说明短按了
}
if((aj2!=0)&&(kt_1==1)&&(biao_1==0))//判断
{
D2=~D2;kt_1=0;
} // 短按
if((cont_1 & 0x01)&&(g_1==0))//长按
{
rv_1++; //长按延时
if(rv_1>200)
{
biao_1=1; //屏蔽短按
hm_1=1;
yy+=1;//选位标志位
if(yy==1){hh=1;ba=1;aa=0;hm_1=0;}
if(yy==2){hh=2;m=1;hk=0;h=0;hu=0;yz=0;yk=0;yu=0;ba=0;ca=0;ea=0;da=0;aa=0;}
if(yy==3){
yy=0; //选位标志重个位开始重新选
hh=0;
m=0;aa=0;
}
g_1=1; //只让输出一次
rv_1=0; //延时时间归零
}
}//长按
}
/*******************************************************************
* C选位按键
********************************************************************/
void key_3()
{
if(trg_2 & 0x01) //短按
{ rv_2=0; //长按延时标志位防止短按到200次后长按启动
biao_2=0; //这是长按屏蔽短按标志位
g_2=0; //这是长按只执行一次标志位
kt_2=1; //这是短按标志位,kt=1说明短按了
}
if((aj3!=0)&&(kt_2==1)&&(biao_2==0))//判断
{
D1=~D1;kt_2=0;
} // 短按
if((cont_2 & 0x01)&&(g_2==0))//长按
{
rv_2++; //长按延时
if(rv_2>200)
{
biao_2=1; //屏蔽短按
hm_2=1;
yk+=1;//选位标志位
if(yk==1){hk=1;ca=1;ff=0;hm_2=0;}
if(yk==2){hk=2;m=1;h=0;hh=0;hu=0;yz=0;yy=0;yu=0;ba=0;ca=0;ea=0;da=0;ff=0;}
if(yk==3){
yk=0; //选位标志重个位开始重新选
hk=0;
m=0;ff=0;
}
g_2=1; //只让输出一次
rv_2=0; //延时时间归零
}
}//长按
}
/*******************************************************************
* D选位按键
********************************************************************/
void key_4()
{
if(trg_3 & 0x01) //短按
{ rv_3=0; //长按延时标志位防止短按到200次后长按启动
biao_3=0; //这是长按屏蔽短按标志位
g_3=0; //这是长按只执行一次标志位
kt_3=1; //这是短按标志位,kt=1说明短按了
}
if((aj4!=0)&&(kt_3==1)&&(biao_3==0))//判断
{
D0=~D0;kt_3=0;
} // 短按
if((cont_3 & 0x01)&&(g_3==0))//长按
{
rv_3++; //长按延时
if(rv_3>200)
{
biao_3=1; //屏蔽短按
hm_3=1;
yu+=1;//选位标志位
if(yu==1){hu=1;ea=1;hv=0;hm_3=0;}
if(yu==2){hu=2;m=1;h=0;hh=0;hk=0;yz=0;yy=0;yk=0;ba=0;ca=0;ea=0;da=0;hv=0;}
if(yu==3){
yu=0; //选位标志重个位开始重新选
hu=0;
m=0;hv=0;
}
g_3=1; //只让输出一次
rv_3=0; //延时时间归零
}
}//长按
}
/*******************************************************************
* 定时器配置
********************************************************************/
void ConfigTimer0(){
TMOD=0x01;//将定时器0,1都设置为模式1
TH0=0XFC;//1ms
TL0=0X66;
TR0=1;//开启定时器0
ET0=1;//开定时器0的中断
EA=1;//开总中断
}
/*******************************************************************
* t0定时器
********************************************************************/
void timer0() interrupt 1
{
TH0=0XFC;//1ms
TL0=0X66;
sk++;
if((t1==1)||(t2==1)||(t3==1)||(t4==1)) //闪烁一下
{
dq++;
if(dq==1000)
{
if(ra==1){deng1=0;}
if(rb==1){deng2=0;}
if(rc==1){deng3=0;}
if(rd==1){deng4=0;}
}
if(dq==2500)
{
if(ra==1){deng1=1;t1=0;ra=0;}
if(rb==1){deng2=1;t2=0;rb=0;}
if(rc==1){deng3=1;t3=0;rc=0;}
if(rd==1){deng4=1;t4=0;rd=0;}
dq=0;
}
}
if((t1==2)||(t2==2)||(t3==2)||(t4==2)) //闪烁两下
{
dt++;
if(dt==1000)
{
if(ra==1){deng1=0;}
if(rb==1){deng2=0;}
if(rc==1){deng3=0;}
if(rd==1){deng4=0;}
}
if(dt==2500)
{
if(ra==1){deng1=1;}
if(rb==1){deng2=1;}
if(rc==1){deng3=1;}
if(rd==1){deng4=1;}
}
if(dt==4000)
{
if(ra==1){deng1=0;}
if(rb==1){deng2=0;}
if(rc==1){deng3=0;}
if(rd==1){deng4=0;}
}
if(dt==5500)
{
if(ra==1){deng1=1;t1=0;ra=0;}
if(rb==1){deng2=1;t2=0;rb=0;}
if(rc==1){deng3=1;t3=0;rc=0;}
if(rd==1){deng4=1;t4=0;rd=0;}
dt=0;
}
}
if((t1==3)||(t2==3)||(t3==3)||(t4==3)) //闪烁三下
{
dr++;
if(dr==1000)
{
if(ra==1){deng1=0;}
if(rb==1){deng2=0;}
if(rc==1){deng3=0;}
if(rd==1){deng4=0;}
}
if(dr==2500)
{
if(ra==1){deng1=1;}
if(rb==1){deng2=1;}
if(rc==1){deng3=1;}
if(rd==1){deng4=1;}
}
if(dr==4000)
{
if(ra==1){deng1=0;}
if(rb==1){deng2=0;}
if(rc==1){deng3=0;}
if(rd==1){deng4=0;}
}
if(dr==5500)
{
if(ra==1){deng1=1;}
if(rb==1){deng2=1;}
if(rc==1){deng3=1;}
if(rd==1){deng4=1;}
}
if(dr==7000)
{
if(ra==1){deng1=0;}
if(rb==1){deng2=0;}
if(rc==1){deng3=0;}
if(rd==1){deng4=0;}
}
if(dr==8500)
{
if(ra==1){deng1=1;t1=0;ra=0;}
if(rb==1){deng2=1;t2=0;rb=0;}
if(rc==1){deng3=1;t3=0;rc=0;}
if(rd==1){deng4=1;t4=0;rd=0;}
dr=0;
}
}
}
void system_start() //上电初始化
{
AUXR=0xb5;
P0=0xfe;
P1=0xff;
P3=0xff;
key_buffer();
}
void main()
{
system_start(); //上电初始化
ConfigTimer0(); //t0中断配置
deng1=1;
deng2=1;
deng3=1;
deng4=1;
while(1)
{
KeyRead(); //按键读取函数
key_1();
key_2();
key_3();
key_4();
RF_decode(); //读取信号波形分析
set_scan(); //学习按键
if((h==1)&&(ss==2)){D3=1;} //A按键点动,h为k1按键按下后h=1,ss为接收指示灯熄灭后ss=2;控制对应输出断开,形成点动
if((hh==1)&&(sn==2)){D2=1;}//B按键点动,hh为k2按键按下后hh=1,sn为接收指示灯熄灭后sn=2;控制对应输出断开,形成点动
if((hk==1)&&(sj==2)){D1=1;} //C按键点动,hk为k3按键按下后hk=1,sj为接收指示灯熄灭后sj=2;控制对应输出断开,形成点动
if((hu==1)&&(so==2)){D0=1;} //D按键点动,hu为k4按键按下后hu=1,so为接收指示灯熄灭后so=2;控制对应输出断开,形成点动
if((yz==0)&&(za==0)&&(hm==1)){t1=1;za=1;ra=1;}//A按键:主要控制对应灯闪烁,za为只执行一次闪烁标志位,t1为闪烁标志位t1=1,闪一下,t1=2闪两下,t1=3闪三下
if((yz==1)&&(za==0)){t1=2;za=1;ra=1;} //ra为对应灯输出标志位,ra=1则输出,ra=0则停止
if((yz==2)&&(za==0)){t1=3;za=1;ra=1;}
if((yy==0)&&(aa==0)&&(hm_1==1)){t2=1;aa=1;rb=1;}//B按键:主要控制对应灯闪烁,aa为只执行一次闪烁标志位,t2为闪烁标志位t2=1,闪一下,t2=2闪两下,t2=3闪三下
if((yy==1)&&(aa==0)){t2=2;aa=1;rb=1;} //rb为对应灯输出标志位,rb=1则输出,rb=0则停止
if((yy==2)&&(aa==0)){t2=3;aa=1;rb=1;}
if((yk==0)&&(ff==0)&&(hm_2==1)){t3=1;ff=1;rc=1;}//C按键:主要控制对应灯闪烁,ff为只执行一次闪烁标志位,t3为闪烁标志位t3=1,闪一下,t3=2闪两下,t3=3闪三下
if((yk==1)&&(ff==0)){t3=2;ff=1;rc=1;} //rc为对应灯输出标志位,rc=1则输出,rc=0则停止
if((yk==2)&&(ff==0)){t3=3;ff=1;rc=1;}
if((yu==0)&&(hv==0)&&(hm_3==1)){t4=1;hv=1;rd=1;}//D按键:主要控制对应灯闪烁,hv为只执行一次闪烁标志位,t4为闪烁标志位t4=1,闪一下,t4=2闪两下,t4=3闪三下
if((yu==1)&&(hv==0)){t4=2;hv=1;rd=1;} //rd为对应灯输出标志位,rd=1则输出,rd=0则停止
if((yu==2)&&(hv==0)){t4=3;hv=1;rd=1;}
}
}我把上面程序中开关控制部省了,把保遥控60个改为10个,编译没有问题 ,但学习功能不能程序没反应,用表测试学习按键按下从高电平能变成低电平,就是没反应,找不问题在那,求高人指点
改的程序如下//-----------------STC8H1K08 SOP16 遥控解码程序----------------//
//测试单片机:STC8H1K08
//封装:SOP16
//晶振:内部11.0592MHz
//功能:2262/1527解码,遥控控制4路继电器,存储10个遥控器
#include <STC8H.H>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
// IO口分配(用户指定)
sbit RF = P3^2; //信号输入
sbit LED = P3^5; //学习指示灯
sbit set = P3^6; //学习键
sbit D0 = P1^0; //1号继电器
sbit D1 = P1^1; //2号继电器
sbit D2 = P1^6; //3号继电器
sbit D3 = P3^7; //4号继电器
// 功能标志位
bit decode_ok; //解码成功
bit rf_ok; //收到有效数据
bit study; //学习标志
bit jmnx; //编码类型:0=2262,1=1527
uchar da1527[2][3]; //解码临时数组
uchar key_d; //遥控器按键码
uchar short_k; //窄脉冲宽度
uchar ss=0, sn=0, s=0, x=0;
uint jk=0;
// 存储10个遥控器(每个3字节,共30字节+1字节数量)
uchar key_number[31]; // 0号单元存储数量,1-30存储遥控器数据
// 1ms延时函数
void delay_1ms(uint x)
{
uchar b,c;
for(x;x>0;x--)
{
for(b=3;b>0;b--)
{
for(c=150;c>0;c--);
}
}
}
// 简易延时
void delay(uint ms)
{
while(ms--);
}
//================ EEPROM操作函数 ================
void IAP_Disable()
{
IAP_CONTR = 0;
IAP_CMD = 0;
IAP_TRIG = 0;
IAP_ADDRH = 0;
IAP_ADDRL = 0;
}
uchar read_add(uint addr)
{
IAP_DATA =0x00;
IAP_CONTR =0x84;
IAP_CMD = 0x01;
IAP_ADDRH =addr>>8;
IAP_ADDRL =addr&0xff;
EA = 0;
IAP_TRIG =0x5a;
IAP_TRIG =0xa5;
_nop_();
EA = 1;
IAP_Disable();
returnIAP_DATA;
}
void write_add(uint addr, uchar ch)
{
IAP_CONTR =0x84;
IAP_CMD = 0x02;
IAP_ADDRH =addr>>8;
IAP_ADDRL =addr&0xff;
IAP_DATA = ch;
EA = 0;
IAP_TRIG =0x5a;
IAP_TRIG =0xa5;
_nop_();
EA = 1;
IAP_Disable();
}
void Sector_Erase(uint addr)
{
IAP_CONTR =0x84;
IAP_CMD = 0x03;
IAP_ADDRH =addr>>8;
IAP_ADDRL =addr&0xff;
EA = 0;
IAP_TRIG =0x5a;
IAP_TRIG =0xa5;
_nop_();
EA = 1;
}
//================ 接收解码函数 ================
void RF_decode()
{
ucharii=0,j=0,k=0,rep=0;
uint head_k=0;
uchar s;
short_k=0;
while(RF&& j<250)
{
delay(1);
short_k++;
}
while(!RF)
{
delay(1);
head_k++;
}
if(((short_k*24)<head_k) && (head_k<(short_k*38)))
{
for(rep=0;rep<2;rep++)
{
for(ii=0;ii<3;ii++)
{
for(k=0;k<8;k++)
{
j=0;
while(RF && j<245)
{
delay(1);
j++;
}
if(j>(short_k-short_k/2-short_k/3)&&j<(short_k*1.96))
{
da1527[rep][ii]&=~(1<<((7-k)));
}
else if(j>(short_k*1.96)&&j<(short_k*5))
da1527[rep][ii]|=(1<<(7-k));
else {return;}
j=0;
while(!RF && j<150){delay(2);j++;}
}
}
j=0;while(RF && (j<200)){delay(1);j++;}
head_k=0;while(!RF) {delay(1);head_k++;}
if((head_k<(short_k*26)) || (head_k>(short_k*38))) {return;}
}
if((da1527[0][0]==da1527[1][0]) && (da1527[0][1]==da1527[1][1])&& (da1527[0][2]==da1527[1][2]))
{
uchari,u;
rf_ok=1;
for(i=0;i<3;i++)
{
for(u=0;u<4;u++) {if(((da1527[0]>>(u*2)) & 3)==2){i=80;break;}}
if(i==80) break;
}
if(i==80) // 1527
{
key_d=da1527[1][2] & 0x0f;
da1527[0][2]=da1527[1][2]>>4;
jmnx=1;
}
else // 2262
{
key_d=0;
for(i=0;i<4;i++){if(((da1527[0][2]>>(i*2))&3)==3)key_d|=1<<i;}
da1527[0][2]=0x00;
jmnx=0;
jk++;//自锁用
}
}
}
}
//================ 遥控器学习函数 ================
void key_buffer() // 读取EEPROM到RAM
{
uchar n;
for(n=0;n<31;n++)
{
key_number[n]=read_add(0x0000+n);
}
}
void KEY_study() // 学习新遥控器
{
uint d_num;
if(study)
{
rf_ok=0;
d_num=0;
while(!rf_ok)
{
RF_decode();
d_num++;
if(d_num>50000) break;
}
d_num=0;
if(rf_ok==1)
{
ucharnum_rf = key_number[0];
if(num_rf>=10){num_rf=0;} // 最多存储10个
key_number[num_rf*3+1]=da1527[0][0];
key_number[num_rf*3+2]=da1527[0][1];
key_number[num_rf*3+3]=da1527[0][2];
key_number[0]=num_rf+1;
Sector_Erase(0x0000);
for(num_rf=0;num_rf<31;num_rf++)
{
write_add(0x0000+num_rf, key_number[num_rf]);
}
rf_ok=0;
LED=1; // 学习成功
}
else
{
for(num_rf=0;num_rf<8;num_rf++)
{
LED=!LED;
delay_1ms(100);
}
LED=1;
}
study=0;
}
}
void system_res() // 系统清零
{
Sector_Erase(0x0000);
write_add(0x0000, 0x00);
key_buffer();
}
void set_scan() // 学习键扫描
{
uchar h=0;
while(!set)
{
if(h>5)
{
study=1;
h=0;
LED=0;
while(!set)
{
delay_1ms(100);
h++;
if(h>80)
{
study=0;
h=0;
system_res();
LED=1;
while(!set);
}
}
}
delay_1ms(100);
h++;
}
if(study)
{
KEY_study();
}
}
//================ 定时器配置 ================
void ConfigTimer0(){
TMOD=0x01;
TH0=0XFC; // 1ms定时初值
TL0=0X66;
TR0=1;
ET0=1;
EA=1;
}
void timer0() interrupt 1
{
TH0=0XFC;
TL0=0X66;
if(decode_ok) // 解码有效信号
{
s--;
if(!s)
{
jk=0;
decode_ok=0;
}
}
}
//================ 继电器控制逻辑(一路遥控一路) ================
void relay_control()
{
if(!study) // 非学习状态
{
rf_ok=0;
for(x=0;x<10;x++) // 检查10个遥控器
{
if((da1527[0][0]==key_number[x*3+1])&&
(da1527[0][1]==key_number[x*3+2])&&
(da1527[0][2]==key_number[x*3+3]))
{
// 一路遥控控制一路继电器(取消互锁,简化逻辑)
if(key_d == 0x01) {D0=~D0;} // 按键1控制D0
if(key_d == 0x02) {D1=~D1;} // 按键2控制D1
if(key_d == 0x04) {D2=~D2;} // 按键4控制D2
if(key_d == 0x08) {D3=~D3;} // 按键8控制D3
decode_ok=1;
ss=1;
sn=1;
s=30;
break;
}
}
}
}
void system_start() // 上电初始化
{
AUXR=0xb5; // 配置辅助寄存器,根据STC8H特性可能需要调整
P1=0xff;
P3=0xff;
key_buffer();
}
void main()
{
system_start();
ConfigTimer0();
LED=1; // 初始化学习指示灯
while(1)
{
RF_decode(); // 读取信号波形分析
set_scan(); // 学习按键扫描
relay_control(); // 继电器控制
}
}