2680|5

13

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

求大神看一下这个51程序有什么问题 [复制链接]

这是一个50秒计时器,想要利用外部中断形成倒计时


#include < reg51.h >
#define  GPIO_DIG  P0
sbit  LSA=P2^2;
sbit  LSB=P2^3;
sbit  LSC=P2^4;          
code unsigned char sag[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};//0123456789
sbit  key_again=P3^3; //重新开始
sbit  key_back=P3^2;//        倒计时
sbit  key_start=P3^1;  //开始
sbit  key_pause=P3^0; //暂停            
unsigned int  count,count1;  
bit         k_b=1;
void delay(unsigned int n);          
unsigned int  count,count1;  
void displayb(unsigned char a);
void display(unsigned char d);
void main(void)
{
    bit k_s,k_a,k_p;
     TMOD=0x01;//设置T0、T1为方式1(16位定时器)
     TH0=(65536-50000)/256 ;   //50ms延时常数(t=(65536-TH)/fosc/12)
     TL0=(65536-50000)%256 ;
     IT0=0; EX0=1; //外部中断0电平触发
     IE=0x82; //开T0中断(总中断和外部中断)
         TR0=0;         //T0定时禁止
        // EX0=0;
     count=0;
         count1=20;
   while(1)
   {   display(count);
                  k_s=key_start;
              k_a=key_again;
              k_p=key_pause;
        if(k_s==0||k_p==0||k_a==0||k_b==0)
        {if(k_s==0)
          {TR0=1;}
           do
                  {          display(count);
                  }   
                  while(key_start==0);//判断按键是否释放
          if(k_p==0)
          {TR0=0;}
           do
                  { display(count);
                  }   
                  while(key_pause==0);//判断按键是否释放
                   if(k_a==0)
          {        TR0=1;
                    count=0;}
           do
                  {  display(count);
                  }   
                  while(key_again==0);//判断按键是否释放        */
                  if(k_b==0)
         // {IT0=0; EX0=1; }
           do
                  {displayb(count);}   
                  while(key_back==0);//断按键是否释放        */是否释放
        if(count1==0)
                {count1=20;count+=1;}
           if(count>50)
                count=0; }}}
void timer0() interrupt 1 using 2// 定时器0中断服务程序.
{   TH0=(65536-50000)/256;   
    TL0=(65536-50000)%256;
    count1-=1;}
void display(unsigned char d )         
{   unsigned int outdata[2];
    unsigned char b;
    b=d;   
    outdata[0]=b/10; //取出高位(整形会将b/10的小数位丢掉)
    outdata[1]=b%10; //取出低位
            LSA=0;
        LSB=0;
        LSC=0;       
            switch(outdata[1])   
        {case 0:GPIO_DIG=sag[0];break;
         case 1:GPIO_DIG=sag[1];break;
         case 2:GPIO_DIG=sag[2];break;
         case 3:GPIO_DIG=sag[3];break;
         case 4:GPIO_DIG=sag[4];break;
         case 5:GPIO_DIG=sag[5];break;
         case 6:GPIO_DIG=sag[6];break;
         case 7:GPIO_DIG=sag[7];break;
         case 8:GPIO_DIG=sag[8];break;
         case 9:GPIO_DIG=sag[9];break;
       }
                delay(50);
                GPIO_DIG=0x00;
                LSA=1;
        LSB=0;
        LSC=0;
        switch(outdata[0])   
        {case 0:GPIO_DIG=sag[0];break;
         case 1:GPIO_DIG=sag[1];break;
         case 2:GPIO_DIG=sag[2];break;
         case 3:GPIO_DIG=sag[3];break;
         case 4:GPIO_DIG=sag[4];break;
         case 5:GPIO_DIG=sag[5];break;
         case 6:GPIO_DIG=sag[6];break;
         case 7:GPIO_DIG=sag[7];break;
         case 8:GPIO_DIG=sag[8];break;
         case 9:GPIO_DIG=sag[9];break;
        }
                 delay(50);
                 GPIO_DIG=0x00;
}
void displayb(unsigned char a)
{          unsigned int outdatab[2];
      unsigned char m;
          while(a>0)
           {m=a--;
           outdatab[0]=m/10; //取出高位(整形会将b/10的小数位丢掉)
       outdatab[1]=m%10; //取出低位
                   LSA=0;
        LSB=1;
        LSC=1;       
          switch(outdatab[1])   
        {case 0:GPIO_DIG=sag[0];break;
         case 1:GPIO_DIG=sag[1];break;
         case 2:GPIO_DIG=sag[2];break;
         case 3:GPIO_DIG=sag[3];break;
         case 4:GPIO_DIG=sag[4];break;
         case 5:GPIO_DIG=sag[5];break;
         case 6:GPIO_DIG=sag[6];break;
         case 7:GPIO_DIG=sag[7];break;
         case 8:GPIO_DIG=sag[8];break;
         case 9:GPIO_DIG=sag[9];break;
       }
                delay(50);
                GPIO_DIG=0x00;
                LSA=1;
        LSB=1;
        LSC=1;
        switch(outdatab[0])   
        {case 0:GPIO_DIG=sag[0];break;
         case 1:GPIO_DIG=sag[1];break;
         case 2:GPIO_DIG=sag[2];break;
         case 3:GPIO_DIG=sag[3];break;
         case 4:GPIO_DIG=sag[4];break;
         case 5:GPIO_DIG=sag[5];break;
         case 6:GPIO_DIG=sag[6];break;
         case 7:GPIO_DIG=sag[7];break;
         case 8:GPIO_DIG=sag[8];break;
         case 9:GPIO_DIG=sag[9];break;
        }
                 delay(50);
                 GPIO_DIG=0x00;
                  delay(250);
           }
                 
                 EX0=0;
  }

void delay(unsigned int n)         // 延时子程序
{  while(n--) ;  
}
void Int0()interrupt 0
{ delay(50);
   if(key_back==0)
      k_b=0;
}

此帖出自51单片机论坛

最新回复

高手啊!学习了。  详情 回复 发表于 2014-12-12 20:35
点赞 关注
 

回复
举报

1万

帖子

25

TA的资源

版主

沙发
 
建议不要在中断中delay,这样会严重影响程序的效率。

可以在proteus中仿真运行一下的。

像这个代码:
     switch(outdata[1])   
        {case 0:GPIO_DIG=sag[0];break;
         case 1:GPIO_DIG=sag[1];break;
         case 2:GPIO_DIG=sag[2];break;
         case 3:GPIO_DIG=sag[3];break;
         case 4:GPIO_DIG=sag[4];break;
         case 5:GPIO_DIG=sag[5];break;
         case 6:GPIO_DIG=sag[6];break;
         case 7:GPIO_DIG=sag[7];break;
         case 8:GPIO_DIG=sag[8];break;
         case 9:GPIO_DIG=sag[9];break;
       }
完全可以用GPIO_DIG=sag[outdata[1]],这样更加简洁高效。你比较两种写法编译后程序的大小就知道了。
此帖出自51单片机论坛
 
 
 

回复

32

帖子

0

TA的资源

一粒金砂(中级)

板凳
 

111

本帖最后由 1185054154 于 2014-11-20 11:07 编辑

得得得
此帖出自51单片机论坛
 
个人签名天行健,君子以自强不息;地势坤,君子以厚德载物
 
 

回复

87

帖子

1

TA的资源

一粒金砂(中级)

4
 
正在学习中....................
此帖出自51单片机论坛
 
 
 

回复

32

帖子

0

TA的资源

一粒金砂(中级)

5
 
同意一樓的看法  不要在中斷裏面加延時  還有LZ可以試一下Debug  往上搜一下  Proteus是可以實現聯調的
此帖出自51单片机论坛
 
 
 

回复

12

帖子

0

TA的资源

一粒金砂(中级)

6
 
高手啊!学习了。
此帖出自51单片机论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表