51单片机在下降沿来之前提前触发外部中断

2019-07-15 13:28发布

   #include <reg52.h>
   #include <absacc.h>
   #include <intrins.h>

   #define u3 XBYTE[0xfdf3]   //通过A0、A1,写控制字

   #define wru3_y XBYTE[0xfdf0]   //通过A0、A1,确认读写计数器0
   #define wru3_j XBYTE[0xfdf1]   //通过A0、A1,确认读写计数器1

   void send2(void);
   void atc89c51_init(void);
   void AT82c54a_init(void);

   unsigned int caprute_jin();
   unsigned int caprute_yuan();
   sbit H=P1^1;
   sbit G=P1^2;
   sbit CT=P1^3;
   sbit gate0=P1^4;
   sbit gate1=P1^5;



///////////////////////////////////////////////////



/////////// ======M8254(U3)初始化
   void AT82c54a_init(void)
{

        u3=0x74;          //写控制字01110100,选计数器1,2次读写操作,方式2,2进制数
        wru3_j=0x00;     //赋初值
    _nop_();
        wru3_j=0x00;

        u3=0x34;          //写控制字00110100,选计数器0,2次读写操作,方式2,2进制数
        wru3_y=0x00;     //赋初值
    _nop_();
        wru3_y=0x00;


        u3=0xb4;       //写控制字10110100,选计数器2,2次读写操作,方式2,2进制数
        wrvr=0x00;       //赋初值
        _nop_();
        wrvr=0x00;
       
}



///////// ======M8254(U6)初始化
   void AT82c54b_init(void)
{
        u6=0x34;           //写控制字00110100,选计数器0,2次读写操作,方式2,2进制数
            _nop_();
        wrjw=0x00;           //赋初值
            _nop_();
        wrjw=0x00;           //赋初值
            _nop_();
        u6=0x74;           //写控制字01110100,选计数器1,2次读写操作,方式2,2进制数
            _nop_();
        wrxv=0x00;
            _nop_();
        wrxv=0x00;
            _nop_();
}

//////////////===89c51初始化
   void atc89c51_init(void)
{
TCON=0x05;
TMOD=0x21;
SCON=0x50;
PCON=0x00;
TH1=0xFD;

TR1=1;
ET1=0;

TR0=1;
ET0=1;
TH0=0xb8;
TL0=0x00;

ES=1;

   gate0=1;
   gate1=1;

  EA=1;
}




//======================
  unsigned int caprute_yuan()
{
  unsigned int dl;
  unsigned int dh;
  unsigned int a;
  u3=0x34;          //写控制字00110100,选计数器0,2次读写操作,方式2,2进制数
    _nop_();
  dl=wru3_y;
    _nop_();
  dh=wru3_y;
    _nop_();
  a=((dh&0x00ff)<<8)+(dl&0x00ff);        //16进制数
  a=65536-a;                        //递减计数需要求得最终值
        u3=0x34;          //写控制字00110100,选计数器0,2次读写操作,方式2,2进制数
        wru3_y=0x00;     //赋初值
    _nop_();
        wru3_y=0x00;
  return a;                                //a为caprute()_y的值

}



//==========================
  unsigned int caprute_jin()
{
  unsigned int dl;
  unsigned int dh;
  unsigned int a;
          u3=0x74;          //写控制字01110100,选计数器1,2次读写操作,方式2,2进制数
        dl=wru3_j;     //赋值
    _nop_();
        dh=wru3_j;
  a=((dh&0x00ff)<<8)+(dl&0x00ff);        //16进制数
  a=65536-a;                        //递减计数需要求得最终值
        u3=0x74;          //写控制字01110100,选计数器1,2次读写操作,方式2,2进制数
        wru3_j=0x00;     //赋值
    _nop_();
        wru3_j=0x00;
  return a;                                //a为caprute()_j的值

}



///////============外部中断0========
void ISR0(void) interrupt 0
{

  gate0=0;   /////关远接收门信号
  EX0=0;

  H=1;   ///远近接收外部触发中断完成标志
  IE0=0;
}



///////===============外部中断1========
void ISR1(void)interrupt 2
{

gate1=0;  //////关近接收门信号
EX1=0;          //近接收外部中断禁止

EX0=1;    //远接收外部中断允许

  delay10us();
  wru_sf=0x20;
  sf=wru_sf;
IE1=0;
}





///////////////////////////////////////////////

   void zhongduan(void) interrupt 1
   {

          bingo++;

  if (bingo==2)
  {


        CT=1;
        gate0=1;
        gate1=1;  //开门信号

        _nop_();



        CT=0;         //CT触发信号拉低
       
        delay50us();
        EX0=0;   //远接收中断禁止
    EX1=1;          //近接收中断允许
  }

        if (bingo==5)
        {
        c=1;
        bingo=0;
        }


   TL0= 0x00;
   TH0= 0xb8;                 //T0_20ms赋值
   }

                 

///////////////////////////////////////////////////

////////////////////////////////////////////
void main(void)
{
   atc89c51_init();
   AT82c54a_init();
   AT82c54b_init();
   delay1s();

//   H=0;                        //声波执行判定标志



while(1)
{




if (H==1)
{
count_yuan=caprute_yuan();
yuanh4=(count_yuan>>8);
yuanl8=(count_yuan&0xff);

count_jin=caprute_jin();
jinh4=(count_jin>>8);
jinl8=(count_jin&0xff);

shicha=(count_yuan-count_jin);
sch4=shicha>>8;
scl8=shicha&0xff;
H=0;
}
if (c==1)
{
avg_vr();
count_xv=caprute_xv();
xv_h4=(count_xv>>8);
xv_l8=(count_xv&0xff);

count_jw=caprute_jw();
jw_h4=(count_jw>>8);
jw_l8=(count_jw&0xff);


         send2();
  c=0;
}

}

}
从示波器上可以看到,我的关门信号gate0、gate1在外部中断触发下降沿到来之前几十微妙就自己置零了,我用的C52芯片,11.059M的晶振

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
4条回答
panlei1106
2019-07-16 01:48
但是还有个问题想接着请教一下,为什么加上(读AD)
wru_sf=0x20;
  sf=wru_sf;
这么俩句后,我跟INT1中断有关的8254计数器被清零了?
我AD和8254的片选地址不一样啊,而且门信号gate1置零后,计数器计得的读数不是应该保存在里面吗?
AD那一块我是这么定义的#define wru_sf XBYTE[0xfeff]
AD和8254计数器的WR和RD我都挂在单片机上了,不明白为什么把这俩句丢在gate1=0前面我的计数器不清零(但是读数上肯定就有变化了)求解……

一周热门 更多>