[51单片机]

设置了两个中断函数,但是仿真中只能出现一个现象

[复制链接]
1107|3
手机看帖
扫描二维码
随时随地手机跟帖
蔬木果|  楼主 | 2018-6-14 21:31 | 显示全部楼层 |阅读模式
我的程序功能是在数码管显示计数的同时,在外部中断0的端口加了一个按键,当按键按下时,实行外部中断函数,数码管显示光敏电阻电压值。
遇到问题:当按键按下时,数码管不变化,没有显示电压值。
仿真图+程序见下图:
#include<reg51.h>
#include<absacc.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int

/*********************************端口定义**********************************/
sbit CS   = P3^5;
sbit Clk  = P3^4;
sbit DATI = P3^3;
sbit DATO = P3^3;
sbit KEY1 = P3^2;

/*******************************定义全局变量********************************/
unsigned char dat = 0x00;       //AD值 .
        //若dat=adc0832(CH)*500.0/255; 不可用unsigned char dat
        //500不可以。用500.0
        //如 下面unsigned int disdat; 不可unsigned char disdat   
unsigned char CH;                        //通道变量        
unsigned int dis[] = {0x00, 0x00, 0x00}; //显示数值

uchar code dispcode[ ]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00};   /*七段共阴管显示定义*/
char code tablewe[]={ 0xfe,0xfd,0xfb,0xf7,0xef,0xdf};                                            /*七段共阴管位选显示定义*/


uchar seconde=0;   /*定义并初始化变量*/
uchar minite=0;
uchar hour=0;
uchar a=0;
uint  mstcnt=0;

/*函数声明*/
void delay(uchar k );      //延时子程序
void time_pro( );          //时间处理子程序
void display( );           //显示子程序
void led_display( );       //led闪烁程序
void convdata( ) ;         //电压计算数据程序
void display_key1(void);   //数码管显示数据程序,中断进行


/*****************************************/
/*************AD转换子程序****************/
/*****************************************/
unsigned char adc0832(unsigned char CH)
{
    unsigned char i,test,adval;        
    adval = 0x00;
    test  = 0x00;

    Clk = 0;              //初始化
        CS=1;
    DATI = 1;     
    CS = 0;
    _nop_();
    Clk = 1;
    _nop_();

   if ( CH == 0x00 )      //通道选择
   {
       Clk = 0;           //写入10,选单极性0通道
       DATI = 1;          //通道0的第一位
       _nop_();           //clk上升沿写进去
       Clk = 1;        
       _nop_();

       Clk = 0;
       DATI = 0;      //通道0的第二位
       _nop_();
       Clk = 1;
       _nop_();
    }
    else
    {                   //写入11,选单极性1通道
       Clk = 0;
       DATI = 1;        //通道1的第一位
       _nop_();         //clk上升沿写进去
       Clk = 1;
       _nop_();

       Clk = 0;
       DATI = 1;        //通道1的第二位
       _nop_();
       Clk = 1;
       _nop_();
    }

      Clk = 0;          //写进空闲位 //clk上升沿写进去
      DATI = 1;
          _nop_();
      Clk = 1;
          _nop_();

    //读取前8位的值
    for( i = 0;i < 8;i++ )      //读取前8位的值
    {                           //clk下升沿读出来
       _nop_();                 //高位先行
       adval <<= 1;
       Clk = 1;
       _nop_();
       Clk = 0;
       if (DATO)
          adval |= 0x01;
           //else
           // adval |= 0x00;
     }  

     for (i = 0; i < 8; i++)      //读取后8位的值
      {                           //clk下升沿读出来
           test >>= 1;            //低位先行,时序图上
           if (DATO)
              test |= 0x80;
              //else
              //test |= 0x00;
          _nop_();
          Clk = 1;
          _nop_();
          Clk = 0;
      }

      if (adval == test)      //比较前8位与后8位的值,如果不相同舍去。
           dat = adval;       //若一直出现显示为零,请将该行去掉

       _nop_();
       CS = 1;        //释放ADC0832,关闭
       DATO = 1;
       Clk = 1;

      return dat;                        
}                                                   
/**************************************************/
/*****将0-255级换算成0.00-5.00的电压数值***********/
/**************************************************/                                                   
void convdata(unsigned char i)          //i=dat*5/255=51,是255份; 256份误差大                                       
{         
     unsigned int disdat;             //不可unsigned char disdat
     disdat=i*500.0/255;                 //500不可以。用500.0        
             /* 验证读数
              dis[0] = i/100;     //个位
              dis[1] = i/10%10;   //小数点后第一位
              dis[2] = i%10;     //小数点后第二位         */         
           
      dis[0] = disdat/100;     //个位
      dis[1] = disdat/10%10;   //小数点后第一位
      dis[2] = disdat%10;      //小数点后第二位
}
/*****************************************/
/*****数码管显示光敏电阻电压程序**********/
/*****************************************/
void display_key1(void)        
{      
    P1=0xfe;
    P0= dispcode[dis[0]] + 0x80;      //显示个位和小数点
        delay(5);   

    P1=0xfd;
    P0=dispcode[dis[1]];              //显示小数点后第一位
        delay(5);   

    P1=0xfb;
    P0=dispcode[dis[2]];              //显示小数点后第二位
        delay(5);   
}

/*****************************/
/*led灯闪烁程序*/
/****************************/
void led_display(void)
{
        delay(50);     //led灯闪烁三次后熄灭
        P2=0x07;       //赋初始值
        delay(50);
        P2=0x00;
        delay(50);
        P2=0x07;
        delay(50);
        P2=0x00;
        delay(50);
        P2=0x07;
        delay(50);
        P2=0x00;  
}

/*****************************/
/*延时子程序*/
/****************************/
void delay (uchar k)
{
        uchar j;
        while((k--)!=0)
        {
                for(j=0;j<125;j++)
                {;}
        }
}

/**************************/
/*时间处理子程序*/
/**************************/
void time_pro( void)
{
        if(seconde==60)                  //秒钟设为60进制
        {
                seconde=0;
                minite++;
                if(minite==60)              //分钟设为60进制
                {
                        minite=0;
                        hour++;
                        if(hour==24)              //时钟设为24进制        
                        {
                                hour=0;
                        }
                }
        }
}

/*****************************/
/* 显示子程序*/
/*****************************/
void display()
{
        static uchar i=0;
        P0=0x00; //消隐
        switch(i)
        {
                case 0: P1=0xfe;
                                P0=dispcode[hour/10];//显示小时的十位
                                i++;
                                break;

                case 1: P1=0xfd;
                                P0=(dispcode[(hour%10)])|0X80;//显示小时的个位
                                i++;
                                break;

                case 2: P1=0xfb;
                                P0=dispcode[minite/10];//显示分的十位
                                i++;
                                break;

                case 3: P1=0xf7;
                                P0=(dispcode[minite%10])|0X80;//显示分的个位
                                i++;
                                break;

                case 4: P1=0xef;
                                P0=dispcode[seconde/10];//显示秒的十位
                                i++;
                                break;

                case 5: P1=0xdf;
                                P0=dispcode[seconde%10];//显示秒的个位
                                i=0;
                                break;
        }
}

/**************************/
/*主函数*/
/**************************/
void main(void)
{   
        P1=0xff;                //初始化p1口,全设为1  
        TMOD=0x01;              //time0为定时器,方式1
        TH0=0xfc;               //预置计数初值1ms
        TL0=0x18;
        EA=1;
        ET0=1;
        TR0=1;
        while (1)
        {      
                        if(a==0)
                        {
                led_display( );      //led灯闪烁
                                time_pro( );         //时间处理
                                }
                                else
                display_key1();
}
}

/*****两个中断程序,一个计数器T0中断,一个外部INT0中断*****/

/**********************************************************/
/*    中断服务程序实现数码管的定时显示 计数器中断         */
/**********************************************************/
void timer0(void) interrupt 1 using 0     //定时器0方式1,16位计数器,50ms中断一次
{
        PT0=0;                                        //设置为低级中断
        TH0=0xfc;               //重置计数初值1ms
        TL0=0x18;
        mstcnt++;
        if(mstcnt>=1000)
        {
                seconde++;
                mstcnt=0;   
        }               
        display( );    //显示时间T1高级中断
                a=0;
}
/**********************************************************/
/*    外部中断————实现按键按下时电压显示         */
/**********************************************************/
void int0(void) interrupt 0
{   
    PX0=1;          //设置为高级中断  
    CH = 0x00;      //在这里选择通道 0x00(单极性0通道)或0x01(单极性1通道)
if (KEY1 == 0)
    {  
           a++;
           P1=0x00;       //端口初始化
       P0=0xff;
       dat = adc0832(CH);
           convdata(dat);     //数据转换
    // display_key1();    //显示数值INT0高级中断,符合设计要求
    }
}  
C:\Users\admin\Desktop

相关帖子

蔬木果|  楼主 | 2018-6-14 21:33 | 显示全部楼层
仿真图如下:
QQ截图20180614184037.jpg

使用特权

评论回复
蔬木果|  楼主 | 2018-6-15 20:47 | 显示全部楼层
已经解决了,我在外部中没有打开中断导致的问题。加了中断开启后,现象出来了。

使用特权

评论回复
一路向北lm| | 2018-6-15 20:55 | 显示全部楼层
蔬木果 发表于 2018-6-15 20:47
已经解决了,我在外部中没有打开中断导致的问题。加了中断开启后,现象出来了。 ...

外部中断都不打开,怎么可能进入呢,这是低级错误,以后多检查,鼓励多多发帖。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

10

主题

171

帖子

2

粉丝