zoukankan      html  css  js  c++  java
  • PT2264解码心得

    PT2264解码心得

      最近闲暇时间在琢磨无线RF解码程序,正好在数码之家论坛中翻出大佬的解码程序(http://bbs.mydigit.cn/read.php?tid=245739),于是乎,慢慢学习2264解码程序,正好用上之前买的逻辑分析仪,带看波形,带看程序,琢磨了两天,程序已可完美解码,在此来总结下心得。        

    一、管脚如下图所示:

     

    OSC1和OSC2为振荡电阻管脚,常用有4.7M、3.3M等,A0-A7位2264地址位管脚,可设置为悬空(F)、高(1)、低(0)三态;D0-D3为四位数据位;

    振荡频率 f=2x1000x16/Rosc(KΩ) ,Rosc为振荡电阻阻值,单位为KΩ;例:Rosc=4.7MΩ;则,f=6.8KHz,则振荡周期为Trosc=1/f=147us;

    二、PT2264编码格式如下

    1.位值格式(1、0、F)(长脉冲(3A)是短脉冲(A)的3倍)

         窄高+宽低+窄高+宽低=0        宽高+窄低+宽高+窄低=1             窄高+宽低+宽高+窄低=F

    2.时序图

                  同步码低电平(L)是窄脉冲(A)的31倍,即,A=L/31

                上图中OSC表示振荡电阻周期 Trosc,则上图时序T=2XTrosc

                        

    3.数据结构

     三、解码思路

    1、首先识别出帧与帧,依据同步码区分开来,同步码低电平时长为31T;

    2、再依据识别出的同步码,判断计算出窄电平时间T,则宽电平时间为3T;(判断窄电平思路,窄电平的误差范围为正(T+T/4)负(T-T/4)一个振荡周期A=T/4;宽电平的误差范围为正(T * 3 + T / 2)负(T * 3 - T / 2) 两个振荡周期2A=T/2)

    3.依据宽窄电平组合即可解出遥控器码值。

    四、程序如下所示,借鉴数码之家各位大佬程序再结合自己理解

      1 //自适应频率的2262解码代码 晶振11.0592
      2 #include <STC15F2K60S2.H>    //STC15F104W头文件
      3 #include <intrins.h>          //左移右移函数头文件
      4 #define uchar unsigned char
      5 #define uint unsigned int
      6 sbit WuXian_IN =P3^3;           //外部中断1,RF模块DATA信号输入管脚
      7 sbit OK_LED =P3^0;               //解码成功
      8 sbit D0=P3^1;                   //数据位1000
      9 sbit D1=P3^2;                   //数据位0100
     10 sbit D2=P3^4;                   //数据位0010
     11 sbit D3=P3^5;                   //数据位0001
     12 void Init()
     13 {
     14  TMOD = 0x01;                   //定时器T0,工作模式1,16位定时,不自动重装,TL0、TH0全用
     15  TR0=0;                        //(可位寻址)关闭定时器T0运行
     16 // ET0=0;                     //(可位寻址)T0的溢出中断允许控制位,ET0=1允许T0中断; ET0=0禁止T0中断;
     17 
     18  EX1 =1;                       //允许外部中断1中断
     19  IT1=0;                        //IT1=0 --上升沿和下降沿均可触发中断;  IT1=1  ----下降沿触发
     20  EA=1;                         //(可位寻址)开启总中断
     21 
     22 }
     23 
     24 void main()
     25 {
     26   Init();
     27   OK_LED=0;
     28   D0=0;
     29   D1=0;
     30   D2=0;
     31   D3=0;
     32  while(1);
     33 }
     34 
     35 void ex0(void) interrupt 2          //外部中断1入口函数
     36 {
     37 
     38 
     39 
     40    //PT2262发码为窄高+宽低+窄高+宽低=0    /宽高+窄低+宽高+窄低=1 /窄高+宽低+宽高+窄低=F
     41    //数值表示:    00 = 0 / 11 = 1 / 01 = F
     42    //反码表示:    11 = 0 / 00 = 1 / 10 = F(本例所用)
     43     bit err = 0;
     44     uchar I = 0;                  //用来记录位数,正常会收到24位
     45     uchar TL,TH;                  //用来记录每位的低电平总时长
     46     uchar MA1,MA2,MA3;            //用来记录地址码(占16位)和键码(占8位)(MA1、MA2、MA3各8个bit位)
     47     uchar TimeCount;
     48     uint L,M;
     49 
     50 
     51     EX1 = 0;                     //暂停外部中断
     52     TR0 = 1;                     //启动定时器计数器0
     53     if(TimeCount > 0)            //当按键按下释放后该值不在赋值就同通过递减直到该值等于0
     54     {
     55         TimeCount--;             //等于0后表示按键释放
     56     }                            
     57     while(WuXian_IN == 0);        //如果为0一直等待,等待高电平出现
     58     while(I < 24)                 //共接收24位
     59     {
     60         while(WuXian_IN == 0);     //等待高电平到来
     61         TL = TL0;
     62         TH = TH0;
     63         TH0 = TL0 = 0;             //记录低电平长度
     64         L = TH;
     65         L = ((L << 8) + TL);       //将计时器的高低8位合并
     66         if(I == 0)                 //处理同步位
     67         {
     68             if(L > 2360)          //确认是引导头(判断同步位低电平时长31a) 
     69             {        
     70                 M = L / 31;        //M即4a亦即是窄电平的时长
     71             }
     72             else                   //不符合规则(出错)
     73             {
     74                 I = TR0 = TH0 = TL0 = 0;
     75                 err = 1;
     76                 break;
     77             }
     78         }
     79         else
     80         {
     81             //短555 长1666
     82             //4.7M的振荡电阻时同步位的低电平时长为L=15378uS;即31a
     83             //4.7M的振荡电阻时窄电平时长为M=492uS;即4a
     84             //4.7M的振荡电阻时宽电平时长为1488uS即12a
     85             //以下语句即判断窄电平与宽电平的宽度是否合格
     86      /*
     87               窄电平时长为M即 M=4a;a为一个振荡频率, fosc=(2x1000x16/Rosc(KΩ))KHz,fosc单位为KHz, (Rosc为振荡电阻,单位为KΩ),则一个振荡周期T=1/fosc 
     88              
     89             例如常用振荡电阻为4.7M;则振荡频率a=fosc=1/(2x1000x16/4700)=6.8KHz ,则振荡周期T=1/6.8K=147uS,即窄电平M=a=4T=588us;则宽电平3xM=3a=1764us;
     90 
     91             程序中窄电平的误差范围为正(M+M/4)负(M-M/4)一个振荡周期a=M/4;
     92 
     93             程序中宽电平的误差范围为正(M * 3 + M / 2)负(M * 3 - M / 2) 两个振荡周期2a=M/2;
     94 
     95     */
     96             if(((L < M - M / 4) && (L > M + M / 4)) || ((L < M * 3 - M / 2) && (L > M * 3 + M / 2)))  //如果窄电平小于4a与大小4a或宽电平小于12a与大小12a则表示出错
     97             {                                                                                          //窄电平的误差范围为正(M+M/4)负(M-M/4)一个振荡周期a=M/4;
     98                 I = TR0 = TH0 = TL0 = 0;                                                              //宽电平的误差范围为正(M * 3 + M / 2)负(M * 3 - M / 2) 两个振荡周期2a=M/2;
     99                 err = 1;
    100                 break;
    101             }        
    102         }
    103         while(WuXian_IN == 1);      //等待低电平到来
    104         TH = TH0;
    105         TL = TL0;
    106         TH0 = TL0 = 0;
    107         L = TH;
    108         L = ((L << 8) + TL);        //将计时器的高低8位合并
    109         /*以下语句即判断是窄电平是否合格(4.7M的振荡电阻时窄电平时长为492uS即4a)    */
    110         if(((L > (M - M / 4)) && (L < (M + M / 4))))//如果此时为4a则本位为0  短492uS
    111         {                                             //窄电平的误差范围为正(M+M/4)负(M-M/4)一个振荡周期a=M/4;
    112             I++;
    113             MA1 <<= 1;    //本位置0
    114         }
    115         /*以下语句即判断宽电平是否合格(4.7M的振荡电阻时宽电平时长为1488uS即12a)    */
    116         else if(((L > (M * 3 - M / 2)) && (L < (M * 3 + M / 2))))////如果此时为12a则本位为1  长1488uS
    117         {                                                          //宽电平的误差范围为正(M * 3 + M / 2)负(M * 3 - M / 2) 两个振荡周期2a=M/2;
    118             I++;
    119             MA1 <<= 1;
    120             MA1++;                  //本位置1
    121         }
    122         else                       //已不是4a也不是12a则不符合规表示出错
    123         {
    124             I = 0;
    125             TR0 = TH0 = TL0 = 0;
    126             err = 1;
    127             break;
    128         }
    129         if(I == 8)
    130         {
    131             MA3 = MA1;             //每二位对应PT2262的一个引脚,bit7/bit6二位对应PT2262的1脚,类推对应PT2262的1~4脚 / 11 = 接+ / 00 = 接地 / 01 = 悬空
    132             //P1 = MA3;            //送P1口显示方便调试
    133         }
    134         if(I == 16)
    135         {
    136             MA2 = MA1;              //每二位对应PT2262的一个引脚,bit7/bit6二位对应PT2262的5脚,类推
    137                                    //对应PT2262的5~8脚 / 11 = 接+ / 00 = 接地 / 01 = 悬空
    138             //P0 = MA2;            //送P1口显示方便调试
    139         }
    140         if(I == 24)                //24位已收完则解码结束
    141         {                    
    142             if(TimeCount == 0)    //为0表示是新的一次按下对其进行处理,如过该值大于0表示已经按下不在处理
    143             {    
    144                 switch(MA1)
    145                 {
    146                     case 0xC0:    //PT2262的10脚按键按下时
    147                         D0 = ~D0;
    148                         break;
    149                     case 0x30:    //PT2262的11脚按键按下时
    150                         D1 = ~D1;
    151                         break;    
    152                     case 0x0C:    //PT2262的12脚按键按下时
    153                         D2 = ~D2;
    154                         break;    
    155                     case 0x03:    //PT2262的13脚按键按下时
    156                         D3 = ~D3;
    157                         break;    
    158                 }
    159             }
    160             OK_LED = !OK_LED;    //解码正确后取反一次
    161             TimeCount =20000;        //PT2262每按一次会发出4组相同的编码防止按键没放开直在取反,保证按1次只做1次处理
    162         }
    163     }
    164     TR0 = TH0 = TL0 = 0;  //关闭定时器T0,并重置TH0、TL0
    165     EX1 = 1;       //开启外部中断1
    166 }
    167 
    168 
    169 //void timer0(void) interrupt 1  //***********定时器T0中断子函数************** 
    170 //{
    171 //TH0=(65536-5000)/256;
    172 //TL0=(65536-5000)%256;
    173 //   i++;
    174 //}
  • 相关阅读:
    启动控制面板命令大全
    C#下载网页为mht文件
    基于C#语言的可编程表达式计算器设计
    FileSystemWatcher监视文件变动
    C#梁朝伟变刘德华之山寨实现
    Json之语法,格式
    Regex类
    C# 索引器
    优化正则表达式的诀窍
    正则表达式(二) 零宽断言与懒惰匹配以及平衡组
  • 原文地址:https://www.cnblogs.com/UPUPDay2152/p/9457430.html
Copyright © 2011-2022 走看看