吴吴吴吴 发表于 2014-10-8 23:12:26

51单片机 外中断1无法触发

麻烦大家看看
先是红外遥控
然后是一个过零检测 检测一个下降沿 就是这个无法实现!
然后是PWM输出一些东西


求助攻{:sad:}

吴吴吴吴 发表于 2014-10-8 23:40:06

#include<at89x52.h>
#define uchar unsigned char
#define uint unsigned int

sbit IR = P3^2;
sbit P34 = P3^4;//为数码管位选
sbit PWM = P2^7;

uint LowTime;//低电平时间
uint HighTime;//高电平时间
uchar Code;//累积一个八位数据帧
uchar a;//接受4组八位数据帧
uchar light = 0x00;//亮度
uchar TH = 0xf4;
uchar code table[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80};//共阳数码管0-8编码

void intialise (void);

void main (void)
{
        EA = 1;
        PX1 = 1;

    IT0 = 1;
        IT1 = 1;
        EX0 = 1;    //用作外部信号感受//接受红外接受管引脚的信号电平
        EX1 = 1;    //因为初始化的时候的时候,亮度为0,不需要零点信号的时间

        TMOD = 0x11;//最高为9ms的计时,还是比较大,必须用定时方式1
        ET1 = 1;

        P34 = 0;//数码管位数
        P0 = table;
        PWM = 0;
        while (1);
}
void External0 (void) interrupt 0 using 0//外部中断0
{
//        EA = 0;//一旦有下降沿立即触发了中断,进来后就关闭中断功能,因为此时要对发来的数据进行分析,不能再接受二次红外的中断,只解码当前的信号。此时P3.2作为输入引脚。
        TH0 = 0;//定时器T0高八位置零
        TL0 = 0;//定时器T0低八位置零
        TR0 = 1;//开启定时器,此定时器不会用作中断
        while (IR == 0);//如果一直是9ms的低电平就一直等待,给引导码的低电平计时
        TR0 = 0;//引导码的低电平结束后就关闭定时器T0,计时结束
        LowTime = TH0*256 + TL0;//保存引导码的低电平时间

        TH0 = 0;//定时器T0高八位置零
        TL0 = 0;//定时器T0低八位置零
        TR0 = 1;//开启定时器,此定时器不会用作中断
        while (IR == 1);//如果一直是4.5ms的高电平就一直等待,给引导码的高电平计时
        TR0 = 0;//引导码的高电平结束后就关闭定时器T0,计时结束
        HighTime = TH0*256 + TL0;//保存引导码的高电平时间
       
        if ((LowTime>7000)&&(LowTime<9000)&&(HighTime>3000)&&(HighTime<5000))//理论值:LowTime = 9000/1.085 = 8294;区间定为:8300-500 = 7800,8300+500 = 8800。HighTime = 4500/1.085 = 4147;区间定为:4100-500 = 3600,4100+500 = 4600。
        //判断出他是引导码就开始解码,否则放弃,然后到最后开启中断,等待下次中断的触发
        {
                uchar i;
                uchar j;
                for (i=0; i<4; i++)//连续读取四个8位数据(用户码、用户码重复码、数据码、数据码反码)
                {
                        for (j=0; j<8; j++)//处理每个码的八位数字
                        {
                                Code = Code >> 1;//Code是用来装8位的二进制数,而且没有符号,右移后做高位补0,保证了确定这一位后, 后面的数据能写入这一位,(这也是为什么要将它放在循环的最开始而不是最后,如果最后的话最高位就必然是空);右移空出的一位放数据,所以每次来的数据是放在最高位的,而发送时是先发低位数据,最后结果就会把最低位放到最右边,取出整体的值就会是一个解好码的值
                              
                                TH0 = 0;
                                TL0 = 0;
                                TR0 = 1;
                                while (IR == 0);//低电平计时等待
                                TR0 = 0;
                                LowTime = TH0*256 + TL0;//保存编码的低电平时间

                                TH0 = 0;
                                TL0 = 0;
                                TR0 = 1;
                                while (IR == 1);//高电平计时等待
                                TR0 = 0;
                                HighTime = TH0*256 + TL0;//保存编码的高电平时间

                                if ((HighTime>4000)&&(HighTime<6000))//如果成立,表明是 "0",理论值:565/1.085 = 520;
                                        Code = Code & 0x7f;//Code的最高位和"0"与,Code的其他低位全部和"1"与,这些位是不会改变的,而最高位肯定是"0"
                                if ((HighTime>9000)&&(HighTime<11000))//如果成立,表明是"1",理论值:1685/1.085 = 1553;
                                        Code = Code | 0x80;//Code的最高位和"1"或,Code的其他低位全部和"0"或,这些位是不会改变的,而最高位肯定是"1"
                        }
                        a = Code;//每接受了一个数据帧,就要把这个数据保存起来
                }//置此32位数据接受完成
                if (a == 0x01&&a == 0x01&&a == ~a)//校验
                {
                        light = a;
                        P0 = table;
                }
        }
//        EA = 1;//数据处理结束了;需要开启中断功能,以便下一次中断的触发
}
void External1 (void) interrupt 2 using 1 //过零信号的中断处理
{
        PWM = 0;
        if (light == 8 || light == 0)
        {
                EX1 = 0;
                ET1 = 0;
                if (light == 8)
                        PWM = 1;
        }
        else
        {
                EX1 = 1;
                ET1 = 1;
                switch (light)
                {
                        case 0x01:TH1 = 0XC4;
                                          break;
                        case 0x02:TH1 = 0XCA;
                                          break;
                        case 0x03:TH1 = 0XD0;
                                          break;
                        case 0x04:TH1 = 0XDC;
                                          break;
                        case 0x05:TH1 = 0XE8;
                                          break;
                        case 0x06:TH1 = 0XEE;
                                          break;
                        case 0x07:TH1 = 0XF4;
                                          break;
                }
                TL1 = 0X00;
                TR1 = 1;
        }
}
void Timer1 (void) interrupt 3 using 2
{
        PWM = 1;
        TR1 = 0;//关闭定时器,下一个零点时才开始计时
}

吴吴吴吴 发表于 2014-10-9 00:10:25

{:dizzy:}求助!

hover_007 发表于 2014-10-9 00:30:37

{:biggrin:}{:biggrin:}{:biggrin:}

雨中的风铃 发表于 2014-10-9 08:04:59

{:biggrin:}{:biggrin:}{:biggrin:}{:biggrin:}{:biggrin:}

吴吴吴吴 发表于 2014-10-9 16:06:36

{:cry:}没人啊

吴吴吴吴 发表于 2014-10-11 10:47:09

问题已经解决 程序重写 是思路有问题

MetalSeed 发表于 2014-10-12 14:44:51

解决了就好~~
页: [1]
查看完整版本: 51单片机 外中断1无法触发