请问,哪位单片机高手,PT2262无线遥控单片机软件解码,怎么判断按键是否放开?
我这里有从别处找来的程序,弄了很久都无从着手,请看源程序,可以直接编译通过的,已经可以控制LED的开关!
PT2262单片机解码程序:
#include<reg51.h>
#include <intrins.h> //包含_nop_()函数的头文件
#define uchar unsigned char
#define uint unsigned int
//----------------------------------------------------------------------------------
sbit zhishi = P3^4; //密码正确指示灯
sbit RF=P3^2; //RF信号检测口
sfr P4=0xc0;
sbit deng_open=P3^5; //继电器闭合控制 ,灯开关控制
bit xue_xi=0; //每次上电后按住自学键后学习一次有效标志位
bit jiesuo_yx=0;
bit you_xiao=1; //解码有效标志,1有效,0无效
bit ajok_flag=1; //按键放开标志
bit lianji_flag; //连击键放开标志1:连击 0:点击
bit xuexi_key=1; //自学习标志1有效0无效
bit ycx=0; //每次上电后按住自学键后学习一次有效标志位
bit miao_key; //每次上电后按住自学键后学习1秒内一次有效标志位
bit get_out=0;//按键是否松开判断标志
bit an_jian;
//bit open_deng;
//------------------- 变量列表------------------------------------------------------
uchar ReadCode[3],GetCode; //定义密码和数据变量3个数组全局变量
uchar ReadCode2[3],ReadCode3[3],jm_chishu;
uchar kai_guan_one; //1灯总开关
uchar kai_guan_two; //2灯总开关
uchar kai_guan_three;//3灯总开关
uchar kai_guan_four;////4灯总开关
uchar key; ////取键值单元
uchar open_key;//按键放开标志
uchar bao_data;//数据状态保持标志
uint data TimerReadKey=0;//计时按键
uchar data cont;//50毫秒计数器
uchar data miao;//1秒计数器
uchar ji_shu;// 按键50毫秒内次数监测
uchar lianji_shu=0; //记录50MS键盘按下的次数
//uchar add_temp;
static uchar mima_h4,mima_l4,mima_h4_2,mima_l4_2,mima_h4_3,mima_l4_3,yaokong_geshu; //定义高4位和低4位密码保存区
uchar bj_temp=0;
uchar jiesuo_sheng_cishu=0;
uchar sheng_h,sheng_l;
uchar th1_temp,sheng_cishu;
//---------------------------------函数列表------------------------------------
void delay_200(void); //200us精确延时
void delay_250(void); //250us精确延时
void delay_131(void); //131ms精确延时
//void init(void); //初始化子程序
//void INT0_intrupt(); //中断处理子程序(解码程序)
void rf_jc(void);
void zixuexi_mima_du(void);
//-----------------------------主程序入口--------------------------------------
//******************************************************************************************
// 声明与IAP/ISP/EEPEOM有关的特殊功能寄存器的地址
// 该单片机与普通51单片机有区别,特殊功能控制寄存器需要用 sfr 关键字定义地址否则无法使用
//******************************************************************************************
sfr isp_data=0xc2; //ISP/IAP操作时的数据寄存器,读出的和要写入的数据都放这里
sfr isp_addrh=0xc3; //ISO/IAP操作时的地址寄存器高8位,需要读出的和写入的地址高8位
sfr isp_addrl=0xc4; //ISO/IAP操作时的地址寄存器低8位,需要读出的和写入的地址低8位
sfr isp_cmd=0xc5; //ISP/IAP操作时的命令寄存器,须命令触发寄存器触发方可生效
sfr isp_trig=0xc6; //操作时的命令触发寄存器
sfr isp_contr=0xc7; //ISP/IAP控制寄存器
sfr AUXR=0x8e; //特殊功能寄存器AUXR的地址声明
//==============定义FLASH操作等待时间及允许IAP/ISP/EEPROM操作的常数=============
#define enable_isp 0x82 //晶体<20MHZ时对ISP_CONTR设置此数
#define SYSclk 22529600L
#define T1MS (65536-SYSclk/1000)
#define T1MS (65536-SYSclk/12/1000)
static uchar xieshuju;
static uchar dushuju;
//****************************************************************************************
//关闭IAP功能函数,使CPU处于安全状态,一次连续的IAP操作之后建议关闭IAP功能,不需要每次都关.
//****************************************************************************************
void iap_disable(void)
{
isp_contr=0; //关闭IAP功能
isp_cmd=0; //清命令寄存器,使其无命令,此句也可不用
isp_trig=0; //清命令触发寄存器,使其无效,此句也可不用
isp_addrh=0xff; //指向非EEPROM区防止误操作
isp_addrl=0xff; //指向非EEPROM区防止误操作
}
//*************************************************************************************************
// 定时器1初始化
//*************************************************************************************************
void time1_csh(void) //50毫秒@5.5296MHz
{
AUXR = 0x00; //定时器时钟12T模式
TMOD = 0x00; //设置定时器模式
TL1 = T1MS; //设置定时初值
TH1 = T1MS>>8; //设置定时初值
TF1 = 0; //清除TF1标志
ET1 =1;
TR1 = 1; //定时器1开始计时
EA=1;
cont=0;
miao=0;
}
void delay_200(void)
{
uchar i,j;
for(i=5;i>0;i--) //5(STC12C2052外4MHz);5(AT89C2051外12MHz)
for(j=72;j>0;j--);//72(STC12C2052外4MHz);18(AT89C2051外12MHz)
}
/*-------------------------------250us精确延时---------------------------------*/
void delay_250(void)
{
uchar i,j;
for(i=5;i>0;i--) //5(STC12C2052外4MHz);5(AT89C2051外12MHz)
for(j=92;j>0;j--); ////92(STC12C2052外4MHz);23(AT89C2051外12MHz)
}
/*-------------------------------131ms精确延时--------------------------------*/
void delay_131(void)
{
uchar i,j;
for(i=254;i>0;i--)
for(j=254;j>0;j--);
}
//----------------- 读出自学习遥控器密码 --------------------------------------------------------
void zixuexi_mima_du(void)
{
e2prom_du(0,0); yaokong_geshu=dushuju; //读出已经保存的遥控器个数
e2prom_du(1,0);mima_h4=dushuju;e2prom_du(1,1);mima_l4=dushuju; //读出保存的第1个遥控器密码
e2prom_du(2,0);mima_h4_2=dushuju;e2prom_du(2,1);mima_l4_2=dushuju; //读出保存的第2个遥控器密码
e2prom_du(3,0);mima_h4_3=dushuju;e2prom_du(3,1);mima_l4_3=dushuju; //读出保存的第3个遥控器密码
}
//----------------- 写入自学习遥控器密码----------------------------------------------------------------
void zixuexi_mima_xie(void)
{
mima_h4=ReadCode2[0];mima_l4=ReadCode2[1]; //当前要写入的密码
e2prom_du(0,0);yaokong_geshu=dushuju; //读出已经学习好的遥控数量
if(yaokong_geshu >3){yaokong_geshu=0;} //遥控最多3个
if(yaokong_geshu <3){yaokong_geshu++;}else{yaokong_geshu=1;} //超过3个则覆盖第1个遥控
switch(yaokong_geshu)
{
case 1:
{
sector_erase(0,0); //檫除0扇区
e2prom_xie(0,0,yaokong_geshu); //写入目前学习好的遥控个数
sector_erase(1,0); //檫除1扇区
e2prom_xie(1,0,mima_h4);e2prom_xie(1,1,mima_l4); //保存第1个遥控器密码
break;
}
case 2:
{
sector_erase(0,0); //檫除0扇区
e2prom_xie(0,0,yaokong_geshu); //写入目前学习好的遥控个数
sector_erase(2,0); //檫除2扇区
e2prom_xie(2,0,mima_h4);e2prom_xie(2,1,mima_l4); //保存第2个遥控器密码
break;
}
case 3:
{
sector_erase(0,0); //檫除0扇区
e2prom_xie(0,0,yaokong_geshu); //写入目前学习好的遥控个数
sector_erase(3,0); //檫除3扇区
e2prom_xie(3,0,mima_h4);e2prom_xie(3,1,mima_l4); //保存第3个遥控器密码
break;
}
}
}
/*-------------------------定时器1子程序入口---------------------------*/
void time(void)interrupt 3 using 1
{
cont++; //计数单元到1秒
//if(cont>10&&cont<20&&miao_key==1)xuexi_key=1;
if(cont==20)
{
cont=0;
miao++;
if(miao==10) //计数单元到10秒
{
miao=0;
// xuexi_key=0; //自学习标志1有效0无效
// miao_key=0;
zhishi=0;
//deng_open=0;
//TR1=0;
}
}
/* if(lianji_shu>1)
{
ji_shu++;
if(ji_shu==1&&lianji_shu>3)
{
lianji_shu=0;
get_out=1;
zhishi=1;
ji_shu=0;
}
else
{
get_out=0;
//
you_xiao=0;
}
} */
}
/*-------------------------外部中断0子程序(解码程序)---------------------------*/
//void INT0_intrupt(void) interrupt 0 using 1
void rf_jc(void)
{
uchar i,j;bit BitState_2;
// EX0=0;
if(RF==0)
{
//////////////////////////////找起始位//////////////////////////////////////////
for(i=0;i<100;i++); //低电平持续时间
if(RF==1) goto kk; //非法电平退出
while(RF==0);
for(i=0;i<50;i++); //高
if(RF==0) goto kk;
delay_200();
if(RF==1) goto kk;
for(i=15;i>0;i--) //重复20次,检测在3750微秒内出现高电平就退出解码程序
{
delay_200();
if(RF==1) goto kk;
}
while(RF==0);
///////////////////////////////接收数据///////////////////////////////////////////
for(j=0;j<3;j++) //按照顺序分别保存密码高4位和低4位及数据位
{
for(i=0;i<8;i++) //每个数组为8位
{
delay_250(); //按照射频检测口电平高低保存到各自数组里
BitState_2=RF; //读入射频检测口电平
switch(jm_chishu)
{
case 0:
{
ReadCode[j]=ReadCode[j]<<1;//每次左移一位共移8次即完成一次操作
ReadCode[j]=ReadCode[j]|BitState_2; //根据读入射频电平信号或操作并保存
break;
}
case 1:
{
ReadCode2[j]=ReadCode[j]<<1;//每次左移一位共移8次即完成一次操作
ReadCode2[j]=ReadCode[j]|BitState_2; //根据读入射频电平信号或操作并保存
break;
}
case 2:
{
ReadCode3[j]=ReadCode[j]<<1;//每次左移一位共移8次即完成一次操作
ReadCode3[j]=ReadCode[j]|BitState_2; //根据读入射频电平信号或操作并保存
break;
}
}
if(RF==1) while(RF==1);//等待变成低电平
while(RF==0); //低电平出现一次电平处理保存完成直到所以地址码和数据位
//处理保存完毕才退出FOR循环
}
}
////////////////////////////////校验及运算数据/////////////////////////////////////
if(jm_chishu==2 )
{
jm_chishu=0;
if(ReadCode2[0]==ReadCode3[0])
{
for(i=0;i<3;i++)
{
if((~(ReadCode2[i]|0x55))&((ReadCode2[i]&0x55)<<1)!=0x00)
goto kk;
}
//校验
// vt=0;for(i=0;i<5;i++){delay_131();}//接收到的8位密码都正确VT有效指示灯亮一下
if(xuexi_key==1&&miao<10) //自学习按键为低且一次上电只学一次
{
//miao_key=0;
zixuexi_mima_xie(); //自学习后写入保存密码函数
}//----------------------------------------------------------------------------------------
else //不是自学习状态 ,按正常密码比较执行
{
if(((ReadCode2[0]==mima_h4)&(ReadCode2[1]==mima_l4)) //3个遥控器中任意一个密码正确就正式解码
|((ReadCode2[0]==mima_h4_2)&(ReadCode2[1]==mima_l4_2))
|((ReadCode2[0]==mima_h4_3)&(ReadCode2[1]==mima_l4_3)))
{
goto ok;
}
else{goto kk;}
}
ok:
GetCode=0x00; //遥控的数据位清0
for(i=0;i<8;i++) //接收到的4位数据位运算处理
{
GetCode |=((ReadCode[2]>>i)&(ReadCode[2]>>(i+1))&0x01<<i); //2262运算出数据位
// GetCode=ReadCode[2]; //1527运算出数据位
}
//////////////////////////////////////////////////////////////////////////////////
you_xiao=1;//for(i=0;i<5;i++){delay_131();}//接收到的8位密码都正确VT有效指示灯亮一下
goto mm;
}
else{goto kk;}
}
else{jm_chishu++;if(jm_chishu>2){jm_chishu=0;}}
kk: ajok_flag=1; you_xiao=0;// EX0=1; //退出中断
mm:;
}
}
//***********************************************************************************************
// 延时函数
//***********************************************************************************************
void delayy(int t)
{
uint i,j;
for(i=t;i>0;i--)
for(j=255;j>0;j--);;
}
//***********************************************************************************************
// 主循环函数
//***********************************************************************************************
//--------------------
main()
{
uchar add_temp;
deng_open=1;
//xuexi_key=1; //自学习标志1有效 0无效
zhishi=1;
//init();
//初始化子程序
time1_csh();
//定时器0初始化
zixuexi_mima_du(); //读出保存的遥控密码
while(1)
{
rf_jc(); //软件RF检测解码函数
if(you_xiao==1)
{
//解码有效
add_temp=~GetCode|0xf0; //输出4位数据位-用于控制对象-本程序里只有密码正确才有输出
add_temp=GetCode&0x0f; //分离4位按键数据
switch(add_temp)
{
case 0x01: //按键1
deng_open=~deng_open;
break;
case 0x02: //按键2
deng_open=~deng_open;
//you_xiao=0;
//ajok_flag=0;
break;
/*case 0x04: //按键3
if(miao<9)TR1 = 1; //定时器1开始计时
deng_open=~deng_open;
break; */
//按键4
/*case 0x08:
if(miao<9)TR1 = 1; //定时器1开始计时
deng_open=~deng_open;
break; */
}
}
}
} |
|