找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 10697|回复: 12
打印 上一主题 下一主题
收起左侧

基于51单片机驱动PT2262+DA1527收发解码C语言程序

  [复制链接]
跳转到指定楼层
楼主
ID:50658 发表于 2013-6-7 22:47 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 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
  1. //RF_IN_OUT.H头文件


  2. #define MAIN_Fosc5529000//定义主时钟, 模拟串口和红外接收会自动适应。5~36MHZ

  3. #define T0_YS           50   //t0定時時間50MS

  4. sbit led=P3^4;

  5. sbit P_TXD1 = P3^1;//定义模拟串口发送脚,打印信息用

  6. sbit p_rxd=P3^4;      //定义模拟串口接收脚

  7. sbit RFIN = P3^5;           //RF接收脚

  8. sbit out22=P3^3;            //RF发射脚

  9. sbit k1=P3^0;

  10. //----------------------------------------------------------------------

  11. voidPrintString(unsigned char code *puts);

  12. voidsend_char(uchar dat);//9600,N,8,1发送一个字节

  13. voidBitTime(void);

  14. uchar uart_rx_da[10];uchar rx_da_num=0;// 串口接收数据缓存

  15. 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;

  16. //***********************************************************

  17. void TIME0_INT() interrupt 1 using 0  //time0中断程序,模拟外中断,用于串口接收

  18. {

  19. uchar ii,u,tem;

  20. BitTime();                   //开始信号

  21. for(ii=0;ii<8;ii++)

  22. {

  23. if(p_rxd==0)

  24. {

  25.   tem&=(~(1<<ii));                    

  26. }

  27. else if(p_rxd==1)

  28. {

  29.   tem|=(1<<ii);                  

  30. }

  31.   BitTime();         

  32. }

  33. BitTime();  //停止脉冲

  34. for (u=10;u>1;u--)uart_rx_da[u-1]=uart_rx_da[u-2];  //已收到的数据后移

  35. uart_rx_da[0]=tem;                                 //新数据始终放在最前面   

  36. rx_da_num++;            

  37.    TH0=0XFF;TL0=0XFF;

  38. }

  39. //***********************************************************

  40. /********************** 模拟串口相关函数************************/

  41. voidBitTime(void)//位时间函数

  42. {

  43. uint i;

  44. i = ((MAIN_Fosc / 100) * 104) / 140000 - 1;//根据主时钟来计算位时间

  45. while(--i);

  46. }

  47. //模拟串口发送

  48. void send_char(uchar dat)//9600,N,8,1发送一个字节

  49. {

  50. uchari;

  51. EA = 0;

  52. P_TXD1 = 0;

  53. BitTime();

  54. for(i=0; i<8; i++)

  55. {

  56. if(dat & 1)P_TXD1 = 1;

  57. elseP_TXD1 = 0;

  58. dat >>= 1;

  59. BitTime();

  60. }

  61. P_TXD1 = 1;

  62. EA = 1;

  63. BitTime();

  64. BitTime();

  65. }

  66. void send_str(unsigned char code *puts)//发送一串字符串

  67. {

  68. for (; *puts != 0;puts++)  send_char(*puts); //遇到停止符0结束

  69. }

  70. //************************************************************************

  71. //IO.H头文件


  72. uchar rf_en=0;

  73. bit jmnx=0;  //为0是2262,1是1527

  74. uchar da1527[2][3],key_d;

  75. uchar short_k=0;     //短脉冲脉部宽度,在发射前可用此数据初始成与接收相同脉冲宽度

  76. void RF_IN()

  77. {

  78. uchar ii=0,j=0,k=0,rep=0;

  79. uint head_k=0;           //短脉冲及头脉冲宽度   

  80. if(rf_en==0)

  81. {

  82. //-------------------------------数据接收-----------------------------------------

  83. short_k=0;while(RFIN && j<250) {delay(1);short_k++;} //检测信号前一个高脉冲的宽度

  84. while(!RFIN) {delay(1);head_k++;} //检测头信号的宽度

  85. if(((short_k*24)<head_k) && (head_k<(short_k*38)))   //头信号的宽度是短脉冲的32倍

  86. {

  87. for(rep=0;rep<2;rep++)

  88.   {  

  89.     for(ii=0;ii<3;ii++)//3字节

  90.             {

  91.           for(k=0;k<8;k++)//每个字节8位

  92.              {         

  93.    j=0;while(RFIN && j<245) {delay(1);j++;}//  16us(6mhz:2~5)

  94.              if(j>(short_k-short_k/2-short_k/3)&&j<(short_k*1.96)) da1527[rep][ii]&=~(1<<((7-k)));

  95.                else if(j>(short_k*1.96)&&j<(short_k*5))da1527[rep][ii]|=(1<<(7-k)); //%25 长脉冲的宽度是短脉冲的3倍        

  96.                        else {rf_en=0;return;}          //乱码退出

  97.              j=0;while(!RFIN && j<150){delay(2);j++;}      //跳过低电平           

  98. }

  99.         }//for(ii=0;ii<12;ii++)  

  100.   j=0;while(RFIN && (j<200)){delay(1);j++;}            //跳个最后一个高脉冲

  101.       head_k=0;while(!RFIN) {delay(1);head_k++;} //检测下一个前导信号的宽度  

  102.       if((head_k<(short_k*26)) || (head_k>(short_k*38)))  {rf_en=0;return;} //头信号的宽度是短脉冲的32倍  //乱码退出

  103.   }

  104. //+++++++++++++++++++++++++2262与1527数据分离处理++++++++++++++++++++++++++++++++++++++++   

  105. if((da1527[0][0]==da1527[1][0]) && (da1527[0][1]==da1527[1][1]) && (da1527[0][2]==da1527[1][2]))//两次接收到的数据相同,就执行

  106.              {

  107. uchar u,i;   

  108. for(i=0;i<3;i++)  //判定2262与1527

  109. {

  110.   for(u=0;u<4;u++) {if(((da1527[0][i]>>(u*2)) & 3)==2) {i=80;break;}}  //有10则为1527

  111.   if(i==80) break;

  112. }

  113. if(i==80)  //1527

  114. {

  115. key_d=da1527[1][2] & 0x0f;         //分出1527的按键值

  116. da1527[0][2]=da1527[1][2]>>4; //分出1527的后4位地址

  117. jmnx=1;         //为0是2262,1是1527

  118. }

  119. else      //2262

  120. {

  121. key_d=0;

  122. for(i=0;i<4;i++){if(((da1527[0][2]>>(i*2))&3)==3) key_d|=1<<i;}   //计算出2262的按键数据                                 

  123. da1527[0][2]=00; //2262无后4位地址,全为0

  124. jmnx=0;         //为0是2262,1是1527

  125. }   

  126. rf_en=4;               

  127. }

  128. }      

  129. }//if(rf_en==0)

  130. }

  131. //^^^^^^^^^^^^rf接收END^^^^^^^

  132. //*******************rf发射********

  133. ////uchar wid发射脉冲宽度,//

  134. //发送8次数据的时间为120ms.=(0.96+0.34)*12*8

  135. //dat1,dat2,dat3为2262与1527地址,dat4为按键值,wid为发射脉冲的宽度一般为60

  136. //****************************************************************8

  137. out0();//发射0

  138. out1();//发射1  

  139. uchar short_width=60;     //初始发射的短脉冲宽度

  140. send_bat(uchar dat);

  141. send_rf(uchar dat1,uchar dat2,uchar dat3,uchar dat4,uchar wid)//1527编码发射

  142. {

  143. unsigned char dd,b;

  144. EA=0;short_width=wid;

  145. // ---------------------2262与1527自动按键值处理-------------------------------------

  146. for(b=0;b<4;b++){if(((dat1>>(b*2)) & 3)==2) {b=80;break;}}  //有10则为1527

  147. if(b!=80)for(b=0;b<4;b++){if(((dat2>>(b*2)) & 3)==2) {b=80;break;}}  //有10则为1527

  148. if(b!=80)for(b=0;b<2;b++){if((((dat3)>>(b*2)) & 3)==2) {b=80;break;}}  //有10则为1527

  149. if(b==80) dat3=dat3*16+dat4;  //1527

  150. else  //2262

  151. {

  152. dd=0;

  153. for (b=0;b<4;b++) if((dat4>>b)&1==1)dd|=3<<(b*2);  //还原按键值的2262编码

  154. dat3=dd;

  155. }      

  156. //------------------------------------------------------------------------------------     

  157. for(dd=0;dd<8;dd++)         //发送相同的8组码

  158.    {

  159. send_bat(dat1);send_bat(dat2);send_bat(dat3);

  160. out22=1;delay(short_width); out22=0;delay(short_width*32);//这几句是发射结束码及头信号           

  161.    }

  162. EA=1;

  163. }

  164. send_bat(uchar dat)

  165. {

  166.   uchar a;

  167.   for (a=0;a<8;a++)//发送一个字节数据

  168.     {

  169.   if((dat>>(7-a))&1==1)out1();

  170.   else out0();

  171. }

  172. }

  173. out0()//发射0  

  174.   {

  175. out22=1;delay(short_width);    //延时320us.

  176. out22=0;delay(short_width*3);   //长脉衝信號是短脉衝寬度的3倍.

  177.   }

  178. out1()//发射1

  179.   {

  180. out22=1;delay(short_width*3);   //延时960us.

  181. out22=0;delay(short_width);    //延时320us.

  182.   }


复制代码
  1. //>>>>>>>>>>>>>>>>>>>>>>>>  rf发射end  >>>>>>>>>>>>>>>>>>>>>>>>>

  2. //主程序

  3. #include <intrins.h>

  4. #include <STC_11xx.H>

  5. #include <IO.H>

  6. #include <RF_IN_OUT.H>

  7. uchar key_d=0;

  8. #define time_long 160   //8s

  9. #define time_short 60  //3s

  10. uchar tim_ys=0;       //未学习时闪灯计时

  11. uchar ys_t1=0;//学习中未收到信号定时计时,自动退出学习

  12. uint key_time=0;      //按键时间长短计时

  13. uchar start_en=0;//学习标志,

  14. uchar start_num=0;// 学习个数

  15. show_jm();

  16. //**************************

  17. main()

  18.   {

  19. uchar i;   

  20. out22=0;RFIN=1;p_rxd=1;                //輸出腳初始  

  21.   //**********定时器0,初始化,模拟中断,用于串口接收**************            

  22.     TMOD|=0X05;                 //定时器0计数模式,模拟外部中断

  23. TH0=0XFF;TL0=0XFF;

  24. ET0=1; TR0=1;                //打开中断,//啟動定時器0,  

  25. EA=1;

  26. //--------------定时器1--50ms定时用----------------

  27. TMOD|=0X10;      //定時器0設為16位定時器模式,方式1.方式0為13位定時器           

  28. clrbit(AUXR,6);//AUXR&=~(1<<7);     //t1 12Tmode

  29. TH1=(65536-MAIN_Fosc/12/1000*T0_YS)>>8;TL1=65536-MAIN_Fosc/12/1000*T0_YS;     //50MS定時器計數設定

  30. ET1=1; TR1=1;                //打开中断,//啟動定時器0,  

  31. EA=1;                        

  32. //******************************************************

  33. //************初始学习个数*************

  34.   start_num=bat_read(0x3fe);

  35. if(start_num<1 || start_num>12)  //没学习过

  36. {

  37. bat_prog(0x00);bat_prog(0x200);start_num=0;         

  38. }     

  39.   //************************************

  40. led_ss(2);      

  41. while(1)

  42.     {

  43. //-----------------------------------------------------------

  44. if(key_time>3 && key_time<10) //短按发射

  45. {

  46. delays(20);

  47. if(key_time<10)

  48.   {

  49. led^=1;     //取反

  50.   }        

  51. }

  52.   else if(key_time>time_short && key_time<(time_long-10)) {bat_prog(0x000);led=0;start_en=1;ys_t1=0;}    //3S正常学习            

  53.   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下

  54.   //---------------------------------------------------------------------------------------------------------------------------------------------------------

  55. RF_IN();     //2262接收

  56. if(rf_en==4)  //表示已接收到数据

  57.           {  

  58.             uchar u;

  59. for(i=0;i<3;i++){send_char(da1527[0][i]);}send_char(key_d);//串口发送接收到的数据

  60. show_jm();  //串口中文显示收到的数据

  61.   //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=

  62. if(start_en==1)   //学习状态

  63. {               

  64. if(start_num<11)  //个数未到最大学习个数

  65. {

  66.   for(u=0;u<3;u++)bat_white(start_num*4+u,da1527[0][u]);  //存地址

  67.   bat_white(start_num*4+3,key_d);                         //存键值

  68.   start_num++;bat_prog(0x200);bat_white(0x3fe,start_num); //存学习个数

  69.   led_ss(2);led=0;                                         //led闪后常亮,继续学习

  70. }

  71. }

  72. else                  //控制状态

  73. {

  74.   for(u=0;u<start_num;u++)  //一个一个的地址读出比较

  75. {

  76. if(da1527[0][0]==bat_read(u*4) && da1527[0][1]==bat_read(u*4+1) && da1527[0][2]==bat_read(u*4+2)) //地址比较  

  77. {

  78. if(key_d==1)  //按键值相同则执行

  79. {

  80. led^=1;     //取反

  81. u=20;     //退出FOR循环

  82. }

  83. }

  84. }

  85. }

  86.   rf_en=0;//

  87. }               

  88. }

  89.   }

  90. //***************************************************

  91. void TIME1_INT() interrupt 3 using 0  //time0中断程序(50ms)  

  92. {

  93.   //********************************

  94. 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;}}   //按键时间计数,学习中按键退出学习

  95. else key_time=0;      

  96.   //********************学习中计数****************************

  97. if(start_en==1) {ys_t1++;}         

  98. if(ys_t1>200){ys_t1=0;led_ss(5);start_en=0;}  //退出学习。

  99.   //********************         

  100.   TH1=(65536-MAIN_Fosc/12/1000*T0_YS)>>8;TL1=65536-MAIN_Fosc/12/1000*T0_YS;     //50MS定時器

  101. }

  102. //***********************************************************

  103. show_jm()

  104. {

  105. uchar i;uint da2262h;da2262h=da1527[0][0]*256+da1527[0][1];        

  106.   if(!jmnx)  //2262

  107. {        

  108.   //***********************************//发射收到并经转换后的数据2262*******************************************************************

  109.     send_str("\r\n");

  110. send_str("      本次解码结果如下:\r\n\r\n");

  111. send_str("  解码类型:2262  \r\n\r\n");

  112.     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);

  113. send_str("  地址管脚配制:");

  114.     for(i=0;i<8;i++)                                  //以字符的方式发送接收到的数据

  115.     {

  116.   if(((da2262h>>((7-i)*2))& 3)==3)send_char(1+0x30);

  117.   else if(((da2262h>>((7-i)*2))& 3)==1)send_char('F');

  118.   else send_char(0+0x30);

  119. }

  120. send_str("\r\n\r\n");

  121.     send_str("按键值:OX");if(key_d>9)send_char(key_d+0x37);else send_char(key_d+0x30);

  122.     send_str("   按键管脚状态:");

  123.     for(i=0;i<4;i++){send_char(((key_d>>(3-i))&1)+0x30);}

  124.     send_str("\r\n\r\n");

  125.     send_str("震荡电阻参考值:OX");

  126.     if((short_k>>4)>9)send_char((short_k>>4)+0x37);else send_char((short_k>>4)+0x30);

  127. if((short_k&0x0f)>9)send_char((short_k&0x0f)+0x37);else send_char((short_k&0x0f)+0x30);

  128.     send_str("\r\n\r\n");

  129. }

  130. //************************************************************************************************************************

  131. else

  132. {

  133. send_str("\r\n");

  134. send_str("      本次解码结果如下:\r\n\r\n");

  135. send_str("  解码类型:1527  \r\n\r\n");  

  136. 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);

  137. if(da1527[0][2]>9)send_char(da1527[0][2]+0x37);else send_char(da1527[0][2]+0x30);

  138. send_str("\r\n\r\n");

  139.     send_str("按键值:OX");if(key_d>9)send_char(key_d+0x37);else send_char(key_d+0x30);

  140. send_str("震荡电阻参考值:OX");

  141. if((short_k>>4)>9)send_char((short_k>>4)+0x37);else send_char((short_k>>4)+0x30);

  142. if((short_k&0x0f)>9)send_char((short_k&0x0f)+0x37);else send_char((short_k&0x0f)+0x30);

  143.     send_str("\r\n\r\n");            

  144. }

  145. }
复制代码
编码发射芯片振荡的电阻
同步位宽度
窄脉冲宽度
宽脉冲宽度
配套的解码接收芯片振荡电阻
PT2262
SC2260-R4



PT2272/SC2272
1.2M




200K
1.5M
5.1M
4.8毫秒
150微秒
450微秒
270K
2.2M




390K
3.3M
12M
10毫秒
320微秒
960微秒
680K
4.7M
20M
14毫秒
450微秒
1350微秒
820K



作者:mcuc 来源:智凡单片机



分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏8 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:137334 发表于 2016-8-22 21:13 | 只看该作者
我是菜鸟,学习学习再学习,谢谢!
回复

使用道具 举报

板凳
ID:73340 发表于 2017-9-28 23:17 | 只看该作者
看不到东西
回复

使用道具 举报

地板
ID:249545 发表于 2017-11-27 10:58 | 只看该作者
PT2272这芯片加接收电路就很好玩,做无线遥控就很需要.
回复

使用道具 举报

5#
ID:686858 发表于 2021-9-19 17:03 | 只看该作者
IO.H(2): error C129: missing ';' before 'rf_en'
请问一下rf_en就是什么,没有定义的
回复

使用道具 举报

6#
ID:686858 发表于 2021-9-19 17:39 | 只看该作者
Build target 'Target 1'
compiling RF.C...
IO.H(27): warning C206: 'delay': missing function-prototype
IO.H(27): error C267: 'delay': requires ANSI-style prototype
Target not created
缺少delay函数,不能编译
回复

使用道具 举报

7#
ID:970121 发表于 2021-12-8 21:02 | 只看该作者
winsinzhao 发表于 2021-9-19 17:39
Build target 'Target 1'
compiling RF.C...
IO.H(27): warning C206: 'delay': missing function-protot ...

自已加一个函数
回复

使用道具 举报

8#
ID:970121 发表于 2021-12-26 10:06 | 只看该作者
楼主厉害!参考楼主的代码,终于学会了RF信号接收是怎么处理的!
回复

使用道具 举报

9#
ID:31119 发表于 2021-12-27 00:45 | 只看该作者
幸苦很不错
回复

使用道具 举报

10#
ID:31119 发表于 2021-12-27 00:45 | 只看该作者
辛苦了很不错的东西
回复

使用道具 举报

11#
ID:686858 发表于 2022-3-26 23:38 | 只看该作者
感谢楼主的无私奉献!你这代码写得很好,我是个初学者,有这代码我可以理解1527的解码过程,有些不懂的地方想请教一下,请问振荡电阻参考值是怎么样对应到实际的电阻的,如0X44,还有我发现这个代码不能解SC2640这个IC。
回复

使用道具 举报

12#
ID:1058675 发表于 2023-11-3 17:27 | 只看该作者
这个电路有成功的兄弟吗
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表