遥控解码程序,调试中遇到按一下松开后有时中断里面的程序执行了几遍,求助

2019-07-15 12:42发布

TP2262的解码程序 ,调试中遇到按一下松开后有时中断里面的程序执行了几遍 我想要的是按下直到松开只执行一遍 再按再执行一遍 望高手指点 程序如下//自适应频率的2262解码代码 晶振11.0592
#include "AT89x52.h"
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit WuXian_IN = P3^2;
sbit OK_LED = P1^7;
//=========================================================================
void Inittimer0(void)
{
    TMOD = 0x11;    //定时器1,定时器0用模式1 16位计时用,12T        
    EA = 1;  //
        ET0=1;     //      //使能全部中断
}
//========================================================================
void delay(uchar z)
{
        uchar x,y;
        for(x=z;z>0;z--)
                for(y=200;y>0;y--);                                                                                                                        
}

void main(void)
{
    InitTimer0();
        WuXian_IN=0;
//        IT0=0;                        //电平解发方式
    EX0 = 1;
//        EA=1;       //允许外部中断0中断
    while(1);
}
//========================================================================
void ex0(void) interrupt 0
{
//PT2262发码为窄高+宽低+窄高+宽低=0    /宽高+窄低+宽高+窄低=1 /窄高+宽低+宽高+窄低=F
//数值表示:    00 = 0 / 11 = 1 / 01 = F
//反码表示:    11 = 0 / 00 = 1 / 10 = F(本例所用)
    bit err = 0;
    uchar I = 0;                //用来记录位数,正常会收到24位
    uchar TL,TH;                //用来记录每位的低电平总时长
    uchar MA1,MA2,MA3;            //用来记录地址码(占16位)和键码(占8位)
    uchar TimeCount;
    uint L,M;
    EX0 = 0;                    //暂停外部中断
    TR1 = 1;                    //启动定时器计数器1
    if(TimeCount > 0)            //当按键按下释放后该值不在赋值就同通过递减直到该值等于0
    {
        TimeCount--;            //等于0后表示按键释放
    }
    while(WuXian_IN == 0);        //如果为0一直等待,等待高电平出现 P3.2
    while(I < 24)                //共接收24位
    {
        while(WuXian_IN == 0);    //等待高电平到来
        TL = TL1;
        TH = TH1;
        TH1 = TL1 = 0;             //记录低电平长度并初始化高电平头
        L = TH;
        L = ((L << 8) + TL);    //将计时器的高低8位合并
        if(I == 0)                 //处理同步位
        {
            if(L > 2360)          //确认是引导头(判断同步位低电平时长31a)   
            {        
                M = L / 31;        //M即4a亦即是窄电平的时长
            }
            else                 //不符合规则(出错)
            {
                I = TR1 = TH1 = TL1 = 0;
                err = 1;
                break;
            }
        }
        else
        {
            //短555 长1666
            //4.7M的振荡电阻时同步位的低电平时长为L=15378uS;即31a
            //4.7M的振荡电阻时窄电平时长为M=492uS;即4a
            //4.7M的振荡电阻时宽电平时长为1488uS即12a
            //以下语句即判断窄电平与宽电平的宽度是否合格
            if(((L < M - M / 4) && (L > M + M / 4)) || ((L < M * 3 - M / 2) && (L > M * 3 + M / 2)))
            {//如果窄电平小于4a与大小4a或宽电平小于12a与大小12a则表示出错
                I = TR1 = TH1 = TL1 = 0;
                err = 1;
                break;
            }        
        }
        while(WuXian_IN == 1);      //等待低电平到来
        TH = TH1;
        TL = TL1;
        TH1 = TL1 = 0;
        L = TH;
        L = ((L << 8) + TL);        //将计时器的高低8位合并
        //以下语句即判断是窄电平是否合格(4.7M的振荡电阻时窄电平时长为492uS即4a)
        if(((L > (M - M / 4)) && (L < (M + M / 4))))//如果此时为4a则本位为0  短492uS
        {
            I++;
            MA1 <<= 1;    //本位置0
        }
        //以下语句即判断宽电平是否合格(4.7M的振荡电阻时宽电平时长为1488uS即12a)
        else if(((L > (M * 3 - M / 2)) && (L < (M * 3 + M / 2))))////如果此时为12a则本位为1  长1488uS
        {
            I++;
            MA1 <<= 1;
            MA1++;    //本位置1
        }
        else        //已不是4a也不是12a则不符合规表示出错
        {
            I = 0;
            TR1 = TH1 = TL1 = 0;
            err = 1;
            break;
        }
        if(I == 8)
        {
            MA3 = MA1;    //每二位对应PT2262的一个引脚,bit7/bit6二位对应PT2262的1脚,类推
                        //对应PT2262的1~4脚 / 11 = 接+ / 00 = 接地 / 01 = 悬空
            //P1 = MA3;    //送P1口显示方便调试
        }
        if(I == 16)
        {
            MA2 = MA1;    //每二位对应PT2262的一个引脚,bit7/bit6二位对应PT2262的5脚,类推
                        //对应PT2262的5~8脚 / 11 = 接+ / 00 = 接地 / 01 = 悬空
            //P0 = MA2;    //送P1口显示方便调试
        }
        if(I == 24)                //24位已收完则解码结束
        {                    
            if(TimeCount == 0)    //为0表示是新的一次按下对其进行处理,如过该值大于0表示已经按下不在处理
            {   
                switch(MA1)
                {
                    case 0xC0:    //PT2262的10脚按键按下时
                        P1_0 = ~P1_0;
                        break;
                    case 0x30:    //PT2262的11脚按键按下时
                        P1_1 = ~P1_1;
                        break;   
                    case 0x0C:    //PT2262的12脚按键按下时
                        P1_2 = ~P1_2;
                        break;   
                    case 0x03:    //PT2262的13脚按键按下时
                        P1_3 = ~P1_3;
                        break;   
                }
            }
            OK_LED = !OK_LED;    //解码正确后取反一次
                     delay(200);
            TimeCount = 60;        //PT2262每按一次会发出4组相同的编码防止按键没放开直在取反,保证按1次只做1次处理
        }
    }
    TR1 = TH1 = TL1 = 0;
    EX0 = 1;
}

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。