PT2262的软件解码
2012-08-04
红尘客
标签: PT2262 解码

编码芯片PT2262发出的编码由:地址码、数据码、同步码组成。地址码和数据码都用宽度不同的脉冲来表示,两个窄脉冲表示“0”;两个宽脉冲表示“1”;一个窄脉冲和一个宽脉冲表示“F”,也就是地址码的“悬空”;同步码为时间较长的低电平间隔,下图为PT2262编码图:

从图中可以看出,发送码的周期是相等的,只是脉冲宽度不同(宽脉冲与窄脉冲之比为3:1)。而同步码的低电平时间约为这个周期的8倍.

解码的关键是识别同步码,然后对后面的字码的脉冲宽度进行识别,就可以解出这个编码。

2262每次发射时至少发射4组字码,每组字码由25个脉冲组成,前24个脉冲为地址和数据,最后一个脉冲和一低电平间隔组成同步码。

下面我们来说说如何用51单片机对其进行解码。

由于程序结构不复杂,就不再画流程图,首先我们让Timer0工作在定时状态,初始化值使其能在同步码未结束时溢出,利用Timer0的溢出中断来初始化,准备接收后来数据,同时将Timer0设为门控定时,也就是TMOD的GATE0位为1,此模式下,只有TR0=1并且INT0=1才计数,此模式可以用来测量脉冲宽度.这样就识别出了同步码.

数据由INT0输入,INT0设为跳变触发,每中断一次就取TH0和TL0之和,这个和就是前一个的脉冲宽度.判断出是宽脉冲还是窄脉冲.由于上述的同步码周期与地址数据周期都远小于定时器0的定时时间,所在定时器0正常工作时,是不会溢出的.

以下为程序,程序的功能是分别解出地址码与按键码(也就是数据码),然后用串口输出.解码时宽脉冲为1,窄脉冲为0.低位放到接收码的最高位,也就是解码结果与原数据位颠倒了.至于想要什么结果,可以做相应的处理,当然包括变换成地址的三进制格式.

因为宽脉冲的脉宽与低脉冲的脉宽相差很大,所以解码很容易,下面为振荡电阻为1M时的程序,同样可用来解码振荡电阻为1.2M的编码.

//测试条件:单片机为AT89S51,晶振12M,振荡电阻1MΩ
#include<AT89X51.h>
#include<stdio.h>

unsigned int addr, key;
unsigned char cntint;//外部中断0计数

void eint0(void) interrupt 0//外部中断0
{
    static unsigned int tempaddr;//接收地址缓存
    static unsigned int tempkey;//接收数据缓存
    unsigned int timecnt;
    timecnt = TH0 * 256 + TL0;
    TH0 = 0;
    TL0 = 0;
    if (cntint < 16) { //接收地址码
        tempaddr = tempaddr << 1; //将接收的到最低位移到最高位
        if (timecnt > 210) { //210为宽脉冲与低脉冲界线,当振荡电阻为1M时,窄脉冲为110uS,宽脉冲为320uS
            tempaddr |= 1; //宽脉冲为1
        }
        cntint++;//中断次数加1
    }
    else if (cntint < 24) { //接收数据码
        tempkey = tempkey << 1;
        if (timecnt > 120) {
            tempkey |= 1;
        }
        cntint++;
    }
    else { //cntint大于24也就是中断了25次时,关闭外部中断0,等待同步码
        TMOD &= 0xf0; //设定时器0为定时方式
        TMOD |= 0x01;
        TH0 = 0xf9;
        TL0 = 0x66;
        cntint = 0;
        EX0 = 0; //关外部中断0
        addr = tempaddr;
        key = tempkey;
        tempaddr = 0;
        tempkey = 0;
    }

}

void timer0(void) interrupt 1//定时器0中断,只有初始化时,空闲时和同步码到来时才中断
{
    TMOD &= 0xf0; //将定时器0的工作方式设为门控定时,用以检测脉宽。
    TMOD |= 0x09;
    cntint = 0; //外部中断0中断次数设为0
    TH0 = 0; //设定时器0定时初值为0
    TL0 = 0;
    EX0 = 1; //允许外部中断0
    IE0 = 0; //清除外部中断0标志
}

void main(void)
{
    void sendd(unsigned int intnum);
    unsigned int i;
    TMOD = 0x21; //设定定时器0和定时器1,定时器1用来驱动串口
    TH0 = 0xf9; //设定定时器的初始值,这个值必小于同步码
    TL0 = 0x66;
    TH1 = 243; //12M晶振时,串口波特率为2400
    TL1 = 243;
    SCON = 0x50; //设定串口工作方式
    TI = 1; //要用printf就将其设为1
    EA = 1; //开所有中断
    ET0 = 1; //开定时器0中断
    EX0 = 0; //关外部中断0,在Timer0中断里面将其打开
    IT0 = 1; //外部中断0设为跳变触发
    TR0 = 1; //定时器0启动
    TR1 = 1; //定时器1启动
    while (1) {
        printf("%u\n", addr); //输出解码地址
        printf("%u\n\n", key); //输出解码数据
        for (i = 0; i < 3000; i++); //这个用来防止串口不同步
    }
}

当然上面的程序只是简单的解出了PT2262的编码,至于要做如何处理,以及可靠性等,要通过读者自己来设计与完善.

可能会用到的工具/仪表
本站简介 | 意见建议 | 免责声明 | 版权声明 | 联系我们
CopyRight@2024-2039 嵌入式资源网
蜀ICP备2021025729号