本帖最后由 hurong 于 2013-6-7 22:51 编辑
2262+1527解码,da1527[0][0],da1527[0][1],da1527[0][2]存地址,key_d存按键值;未学习,led慢闪;按3S按键进入学习,LED常亮,学习成功后闪两下,后LED再常亮,进入下一个摇控器的学习, 如此循环,过程中再短按一下按键,LED灭,退出学习;长按8S清除学习过的内容,3S时灯亮,8时灯灭再闪7下;短按IO口致反。 两种方式退出学习:1、学习过程中,短按按键;2、学习过程中,不进行任何操作,10S自动退出学习。STC_11xx.H根据自己单片机型号选择!STC15F104e- //RF_IN_OUT.H头文件
- #define MAIN_Fosc5529000//定义主时钟, 模拟串口和红外接收会自动适应。5~36MHZ
- #define T0_YS 50 //t0定時時間50MS
- sbit led=P3^4;
- sbit P_TXD1 = P3^1;//定义模拟串口发送脚,打印信息用
- sbit p_rxd=P3^4; //定义模拟串口接收脚
- sbit RFIN = P3^5; //RF接收脚
- sbit out22=P3^3; //RF发射脚
- sbit k1=P3^0;
- //----------------------------------------------------------------------
- voidPrintString(unsigned char code *puts);
- voidsend_char(uchar dat);//9600,N,8,1发送一个字节
- voidBitTime(void);
- uchar uart_rx_da[10];uchar rx_da_num=0;// 串口接收数据缓存
- led_ss(uchar h){uchar y;TR0=0;for(y=0;y<h;y++){led=0;delays(8);led=1;delays(8);}TR0=1;}//在这里只能用TR0=0,不能用EA=0,不然会多收到一个OXFF;
- //***********************************************************
- void TIME0_INT() interrupt 1 using 0 //time0中断程序,模拟外中断,用于串口接收
- {
- uchar ii,u,tem;
- BitTime(); //开始信号
- for(ii=0;ii<8;ii++)
- {
- if(p_rxd==0)
- {
- tem&=(~(1<<ii));
- }
- else if(p_rxd==1)
- {
- tem|=(1<<ii);
- }
- BitTime();
- }
- BitTime(); //停止脉冲
- for (u=10;u>1;u--)uart_rx_da[u-1]=uart_rx_da[u-2]; //已收到的数据后移
- uart_rx_da[0]=tem; //新数据始终放在最前面
- rx_da_num++;
- TH0=0XFF;TL0=0XFF;
- }
- //***********************************************************
- /********************** 模拟串口相关函数************************/
- voidBitTime(void)//位时间函数
- {
- uint i;
- i = ((MAIN_Fosc / 100) * 104) / 140000 - 1;//根据主时钟来计算位时间
- while(--i);
- }
- //模拟串口发送
- void send_char(uchar dat)//9600,N,8,1发送一个字节
- {
- uchari;
- EA = 0;
- P_TXD1 = 0;
- BitTime();
- for(i=0; i<8; i++)
- {
- if(dat & 1)P_TXD1 = 1;
- elseP_TXD1 = 0;
- dat >>= 1;
- BitTime();
- }
- P_TXD1 = 1;
- EA = 1;
- BitTime();
- BitTime();
- }
- void send_str(unsigned char code *puts)//发送一串字符串
- {
- for (; *puts != 0;puts++) send_char(*puts); //遇到停止符0结束
- }
- //************************************************************************
- //IO.H头文件
- uchar rf_en=0;
- bit jmnx=0; //为0是2262,1是1527
- uchar da1527[2][3],key_d;
- uchar short_k=0; //短脉冲脉部宽度,在发射前可用此数据初始成与接收相同脉冲宽度
- void RF_IN()
- {
- uchar ii=0,j=0,k=0,rep=0;
- uint head_k=0; //短脉冲及头脉冲宽度
- if(rf_en==0)
- {
- //-------------------------------数据接收-----------------------------------------
- short_k=0;while(RFIN && j<250) {delay(1);short_k++;} //检测信号前一个高脉冲的宽度
- while(!RFIN) {delay(1);head_k++;} //检测头信号的宽度
- if(((short_k*24)<head_k) && (head_k<(short_k*38))) //头信号的宽度是短脉冲的32倍
- {
- for(rep=0;rep<2;rep++)
- {
- for(ii=0;ii<3;ii++)//3字节
- {
- for(k=0;k<8;k++)//每个字节8位
- {
- j=0;while(RFIN && j<245) {delay(1);j++;}// 16us(6mhz:2~5)
- 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)); //%25 长脉冲的宽度是短脉冲的3倍
- else {rf_en=0;return;} //乱码退出
- j=0;while(!RFIN && j<150){delay(2);j++;} //跳过低电平
- }
- }//for(ii=0;ii<12;ii++)
- j=0;while(RFIN && (j<200)){delay(1);j++;} //跳个最后一个高脉冲
- head_k=0;while(!RFIN) {delay(1);head_k++;} //检测下一个前导信号的宽度
- if((head_k<(short_k*26)) || (head_k>(short_k*38))) {rf_en=0;return;} //头信号的宽度是短脉冲的32倍 //乱码退出
- }
- //+++++++++++++++++++++++++2262与1527数据分离处理++++++++++++++++++++++++++++++++++++++++
- if((da1527[0][0]==da1527[1][0]) && (da1527[0][1]==da1527[1][1]) && (da1527[0][2]==da1527[1][2]))//两次接收到的数据相同,就执行
- {
- uchar u,i;
- for(i=0;i<3;i++) //判定2262与1527
- {
- for(u=0;u<4;u++) {if(((da1527[0][i]>>(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]=00; //2262无后4位地址,全为0
- jmnx=0; //为0是2262,1是1527
- }
- rf_en=4;
- }
- }
- }//if(rf_en==0)
- }
- //^^^^^^^^^^^^rf接收END^^^^^^^
- //*******************rf发射********
- ////uchar wid发射脉冲宽度,//
- //发送8次数据的时间为120ms.=(0.96+0.34)*12*8
- //dat1,dat2,dat3为2262与1527地址,dat4为按键值,wid为发射脉冲的宽度一般为60
- //****************************************************************8
- out0();//发射0
- out1();//发射1
- uchar short_width=60; //初始发射的短脉冲宽度
- send_bat(uchar dat);
- send_rf(uchar dat1,uchar dat2,uchar dat3,uchar dat4,uchar wid)//1527编码发射
- {
- unsigned char dd,b;
- EA=0;short_width=wid;
- // ---------------------2262与1527自动按键值处理-------------------------------------
- for(b=0;b<4;b++){if(((dat1>>(b*2)) & 3)==2) {b=80;break;}} //有10则为1527
- if(b!=80)for(b=0;b<4;b++){if(((dat2>>(b*2)) & 3)==2) {b=80;break;}} //有10则为1527
- if(b!=80)for(b=0;b<2;b++){if((((dat3)>>(b*2)) & 3)==2) {b=80;break;}} //有10则为1527
- if(b==80) dat3=dat3*16+dat4; //1527
- else //2262
- {
- dd=0;
- for (b=0;b<4;b++) if((dat4>>b)&1==1)dd|=3<<(b*2); //还原按键值的2262编码
- dat3=dd;
- }
- //------------------------------------------------------------------------------------
- for(dd=0;dd<8;dd++) //发送相同的8组码
- {
- send_bat(dat1);send_bat(dat2);send_bat(dat3);
- out22=1;delay(short_width); out22=0;delay(short_width*32);//这几句是发射结束码及头信号
- }
- EA=1;
- }
- send_bat(uchar dat)
- {
- uchar a;
- for (a=0;a<8;a++)//发送一个字节数据
- {
- if((dat>>(7-a))&1==1)out1();
- else out0();
- }
- }
- out0()//发射0
- {
- out22=1;delay(short_width); //延时320us.
- out22=0;delay(short_width*3); //长脉衝信號是短脉衝寬度的3倍.
- }
- out1()//发射1
- {
- out22=1;delay(short_width*3); //延时960us.
- out22=0;delay(short_width); //延时320us.
- }
复制代码- //>>>>>>>>>>>>>>>>>>>>>>>> rf发射end >>>>>>>>>>>>>>>>>>>>>>>>>
- //主程序
- #include <intrins.h>
- #include <STC_11xx.H>
- #include <IO.H>
- #include <RF_IN_OUT.H>
- uchar key_d=0;
- #define time_long 160 //8s
- #define time_short 60 //3s
- uchar tim_ys=0; //未学习时闪灯计时
- uchar ys_t1=0;//学习中未收到信号定时计时,自动退出学习
- uint key_time=0; //按键时间长短计时
- uchar start_en=0;//学习标志,
- uchar start_num=0;// 学习个数
- show_jm();
- //**************************
- main()
- {
- uchar i;
- out22=0;RFIN=1;p_rxd=1; //輸出腳初始
- //**********定时器0,初始化,模拟中断,用于串口接收**************
- TMOD|=0X05; //定时器0计数模式,模拟外部中断
- TH0=0XFF;TL0=0XFF;
- ET0=1; TR0=1; //打开中断,//啟動定時器0,
- EA=1;
- //--------------定时器1--50ms定时用----------------
- TMOD|=0X10; //定時器0設為16位定時器模式,方式1.方式0為13位定時器
- clrbit(AUXR,6);//AUXR&=~(1<<7); //t1 12Tmode
- TH1=(65536-MAIN_Fosc/12/1000*T0_YS)>>8;TL1=65536-MAIN_Fosc/12/1000*T0_YS; //50MS定時器計數設定
- ET1=1; TR1=1; //打开中断,//啟動定時器0,
- EA=1;
- //******************************************************
- //************初始学习个数*************
- start_num=bat_read(0x3fe);
- if(start_num<1 || start_num>12) //没学习过
- {
- bat_prog(0x00);bat_prog(0x200);start_num=0;
- }
- //************************************
- led_ss(2);
- while(1)
- {
- //-----------------------------------------------------------
- if(key_time>3 && key_time<10) //短按发射
- {
- delays(20);
- if(key_time<10)
- {
- led^=1; //取反
- }
- }
- else if(key_time>time_short && key_time<(time_long-10)) {bat_prog(0x000);led=0;start_en=1;ys_t1=0;} //3S正常学习
- else if(key_time>time_long) {led=1;delays(80);bat_prog(0x00);bat_prog(0x200);start_num=0;start_en=0;led_ss(7);}//8S清除,3S时灯亮,8时灯灭再闪7下
- //---------------------------------------------------------------------------------------------------------------------------------------------------------
- RF_IN(); //2262接收
- if(rf_en==4) //表示已接收到数据
- {
- uchar u;
- for(i=0;i<3;i++){send_char(da1527[0][i]);}send_char(key_d);//串口发送接收到的数据
- show_jm(); //串口中文显示收到的数据
- //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
- if(start_en==1) //学习状态
- {
- if(start_num<11) //个数未到最大学习个数
- {
- for(u=0;u<3;u++)bat_white(start_num*4+u,da1527[0][u]); //存地址
- bat_white(start_num*4+3,key_d); //存键值
- start_num++;bat_prog(0x200);bat_white(0x3fe,start_num); //存学习个数
- led_ss(2);led=0; //led闪后常亮,继续学习
- }
- }
- else //控制状态
- {
- for(u=0;u<start_num;u++) //一个一个的地址读出比较
- {
- if(da1527[0][0]==bat_read(u*4) && da1527[0][1]==bat_read(u*4+1) && da1527[0][2]==bat_read(u*4+2)) //地址比较
- {
- if(key_d==1) //按键值相同则执行
- {
- led^=1; //取反
- u=20; //退出FOR循环
- }
- }
- }
- }
- rf_en=0;//
- }
- }
- }
- //***************************************************
- void TIME1_INT() interrupt 3 using 0 //time0中断程序(50ms)
- {
- //********************************
- if(!k1) {key_time++;if(key_time<time_short)led=1;if(start_en>0 && key_time<time_short){led_ss(5);start_en=0;}} //按键时间计数,学习中按键退出学习
- else key_time=0;
- //********************学习中计数****************************
- if(start_en==1) {ys_t1++;}
- if(ys_t1>200){ys_t1=0;led_ss(5);start_en=0;} //退出学习。
- //********************
- TH1=(65536-MAIN_Fosc/12/1000*T0_YS)>>8;TL1=65536-MAIN_Fosc/12/1000*T0_YS; //50MS定時器
- }
- //***********************************************************
- show_jm()
- {
- uchar i;uint da2262h;da2262h=da1527[0][0]*256+da1527[0][1];
- if(!jmnx) //2262
- {
- //***********************************//发射收到并经转换后的数据2262*******************************************************************
- send_str("\r\n");
- send_str(" 本次解码结果如下:\r\n\r\n");
- send_str(" 解码类型:2262 \r\n\r\n");
- send_str("地址:OX");for(i=0;i<4;i++)if(((da2262h>>(12-(i*4)))&0x0f)>9)send_char(((da2262h>>(12-(i*4)))&0x0f)+0x37);else send_char(((da2262h>>(12-(i*4)))&0x0f)+0x30);
- send_str(" 地址管脚配制:");
- for(i=0;i<8;i++) //以字符的方式发送接收到的数据
- {
- if(((da2262h>>((7-i)*2))& 3)==3)send_char(1+0x30);
- else if(((da2262h>>((7-i)*2))& 3)==1)send_char('F');
- else send_char(0+0x30);
- }
- send_str("\r\n\r\n");
- send_str("按键值:OX");if(key_d>9)send_char(key_d+0x37);else send_char(key_d+0x30);
- send_str(" 按键管脚状态:");
- for(i=0;i<4;i++){send_char(((key_d>>(3-i))&1)+0x30);}
- send_str("\r\n\r\n");
- send_str("震荡电阻参考值:OX");
- if((short_k>>4)>9)send_char((short_k>>4)+0x37);else send_char((short_k>>4)+0x30);
- if((short_k&0x0f)>9)send_char((short_k&0x0f)+0x37);else send_char((short_k&0x0f)+0x30);
- send_str("\r\n\r\n");
- }
- //************************************************************************************************************************
- else
- {
- send_str("\r\n");
- send_str(" 本次解码结果如下:\r\n\r\n");
- send_str(" 解码类型:1527 \r\n\r\n");
- send_str("地址:OX");for(i=0;i<4;i++)if(((da2262h>>(12-(i*4)))&0x0f)>9)send_char(((da2262h>>(12-(i*4)))&0x0f)+0x37);else send_char(((da2262h>>(12-(i*4)))&0x0f)+0x30);
- if(da1527[0][2]>9)send_char(da1527[0][2]+0x37);else send_char(da1527[0][2]+0x30);
- send_str("\r\n\r\n");
- send_str("按键值:OX");if(key_d>9)send_char(key_d+0x37);else send_char(key_d+0x30);
- send_str("震荡电阻参考值:OX");
- if((short_k>>4)>9)send_char((short_k>>4)+0x37);else send_char((short_k>>4)+0x30);
- if((short_k&0x0f)>9)send_char((short_k&0x0f)+0x37);else send_char((short_k&0x0f)+0x30);
- send_str("\r\n\r\n");
- }
- }
复制代码
作者:mcuc 来源:智凡单片机
|