找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

帖子
查看: 3475|回復: 8
打印 上一主題 下一主題
收起左側(cè)

寫的一個單片機秒表程序但bug實在找不出,求大佬幫我看看

[復制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:483399 發(fā)表于 2019-3-2 20:08 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
用51單片機(芯片為STC89C52)寫了實現(xiàn)一個范圍為0~99的秒表,并用按鍵控制秒表的啟動和暫停的程序,但程序燒錄后,數(shù)碼管一直停在00,不管按K1按鍵多少次都沒有反應,不知道程序錯在哪里,求指教
  1. #include<reg52.h>
  2. typedef unsigned int u8;
  3. typedef unsigned char u16;
  4. sbit LSA=P2^2;//使用138譯碼器
  5. sbit LSB=P2^3;
  6. sbit LSC=P2^4;
  7. sbit K1=P3^1;
  8. u8 code smgduan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5c,0x79,0x71};
  9. u16 s;
  10. u8 sec,mb[2];
  11. void delay(u16 i)
  12. {
  13.   while(i--);
  14. }
  15. void Time0Init()
  16. {
  17. TMOD|=0x01;//選擇定時器0模式,工作方式1,僅用TR0打開啟動
  18. TH0=0xFC;  //給定時器賦初值,定時1ms
  19. TL0=0x18;
  20. TR0=1;//定時器啟動
  21. }
  22. void Digdisplay()
  23. {
  24.   u8 i;
  25.   for(i=0;i<2;i++)
  26.   {
  27.   switch(i)//位選,選擇點亮的數(shù)碼管
  28.    {
  29.      case(0):LSA=0;LSB=0;LSC=0;break;//顯示第0位
  30.          case(1):LSA=1;LSB=0;LSC=0;break;//顯示第1位
  31.    }
  32.    P0=smgduan[mb[i]];//發(fā)送段碼
  33.    delay(1);//間隔一段時間掃描
  34.    P0=0x00;//消隱
  35.   }
  36. }
  37. void display()
  38. {
  39. if(TF0==1)
  40. {
  41.    TF0=0;
  42.    TH0=0xFC;
  43.    TL0=0x18;
  44.    s++;
  45.    }
  46.    if(s==1000) //到達1s時間
  47.    {
  48.      s=0;
  49.          sec++;
  50.          if(sec==99)sec=0;//計時到99s重新開始
  51.          }
  52.         mb[0]=sec%10;//秒表個位
  53.         mb[1]=sec/10;//秒表十位
  54.         Digdisplay();
  55. }
  56. void main()
  57. {
  58. Time0Init();
  59. while(1)
  60. {
  61.    display();
  62.    if(K1==0)//判斷按鍵K1是否按下
  63.    {
  64.     delay(1000);//消抖
  65.         if(K1==0)
  66.         {
  67.           TR0=0;//定時器中斷
  68.           while(!K1)
  69.           {
  70.            display();
  71.            }
  72.            TR0=1;//定時器重新打開,繼續(xù)計時
  73.          }
  74.         }
  75.   }
  76. }
復制代碼


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發(fā)
ID:404797 發(fā)表于 2019-3-3 00:00 | 只看該作者
askb1.zip (33.27 KB, 下載次數(shù): 4)     你的程序我看不懂,我按你的意思編了以下程序,可以實現(xiàn)按鈔從0到100計數(shù),到100后雙從0開始計數(shù),按K1實現(xiàn)暫�;蚶^續(xù);供你參考。由于程序循環(huán)的原因,K1鍵有時不能檢測到,可多按久一點,程序有等待按鍵松開的設(shè)計。
#include<reg52.h>
sbit k1=P3^1;
int msec,sec;
char smgduan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
void delay(int ii)
{int i,j;
for(i=0;i<ii;i++)
    for(j=0;j<110;j++);
}

void display()
{P2=0<<2;
P0=smgduan[sec/10];
delay(1);
P2=1<<2;
P0=smgduan[sec%10];
delay(1);
}

void TimerInit()
{EA=1;
ET0=1;
TMOD|=0x01;
TH0=0xFC;
TL0=0x18;
TR0=1;
}

void Timer0Pro() interrupt 1
{msec++;
if(msec==20)
{msec=0;
  sec++;
  if(sec==100)sec=0;
  }
}

main()
{TimerInit();
while(1)
{display();
  if(k1==0)
   {while(k1==0);
    TR0=~TR0;
    }
  };
}


下面是配套的Proteus原理圖。

附件有全套程序和Proteus設(shè)計

評分

參與人數(shù) 1黑幣 +80 收起 理由
admin + 80 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

板凳
ID:164602 發(fā)表于 2019-3-3 09:42 | 只看該作者
zxwdown 發(fā)表于 2019-3-3 00:00
你的程序我看不懂,我按你的意思編了以下程序,可以實現(xiàn)按鈔從0到100計數(shù),到100后雙從0開始計數(shù),按K1 ...

用外部中斷啊,就不怕掃描不到了。
回復

使用道具 舉報

地板
ID:111634 發(fā)表于 2019-3-3 10:37 | 只看該作者
本帖最后由 zl2168 于 2019-3-3 21:50 編輯

實例93  99.9秒秒表
Proteus仿真一下,確認有效。

實例95 99.9秒秒表.rar (38.86 KB, 下載次數(shù): 11)
以上摘自張志良編著《80C51單片機仿真設(shè)計實例教程——基于Keil CProteus》清華大學出版社ISBN 978-7-302-41682-1,內(nèi)有常用的單片機應用100案例,用于仿真實驗操作,書中電路和程序設(shè)計有詳細說明,電路與程序真實可靠可信可行,程序語句條條有注解。若需99.99秒,硬件電路增加一位595。軟件程序增加0.01s10ms計數(shù)器,并修改相應計數(shù)顯示程序。
回復

使用道具 舉報

5#
ID:164602 發(fā)表于 2019-3-3 10:37 | 只看該作者
你整人嘛�。。。。。。。。�!
調(diào)試了半天,才發(fā)現(xiàn)你的錯誤�。。。。。。。。�!
極低級的錯誤!�。。。。。。。�!
第二、三行:
typedef unsigned int u8;
typedef unsigned char u16;
寫反了吧,所以當s想達到1000時,最大才255,永遠達不到,所以不計時�。。。。。。。。。�
改了就好了:
typedef unsigned char u8;
typedef unsigned int u16;
回復

使用道具 舉報

6#
ID:213173 發(fā)表于 2019-3-3 10:42 | 只看該作者
你的程序主要問題是數(shù)據(jù)類型定義錯誤:typedef unsigned int u8; typedef unsigned char u16;
其次是按鍵程序有錯誤,數(shù)碼管動態(tài)顯示也有缺陷。都給你改了一下,供參考。

  1. #include<reg52.h>
  2. typedef unsigned int u16;
  3. typedef unsigned char u8;
  4. sbit LSA=P2^2;//使用138譯碼器
  5. sbit LSB=P2^3;
  6. sbit LSC=P2^4;
  7. sbit K1=P3^1;
  8. u8 code smgduan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5c,0x79,0x71};
  9. u16 s=0;
  10. u8 sec=0,KeySec=0;//鍵值
  11. bit flag=0;//起停標志

  12. void Time0Init()
  13. {
  14.         TMOD|=0x01;//選擇定時器0模式,工作方式1,僅用TR0打開啟動
  15.         TH0=0xFC;  //給定時器賦初值,定時1ms
  16.         TL0=0x18;
  17.         TF0=0;
  18.         TR0=1;//定時器啟動
  19. }

  20. void keyscan()        //按鍵掃描
  21. {
  22.         static u8 count=0;        //計數(shù)消抖變量                       
  23.         static bit key_sign=0;        //按鍵自鎖標志
  24.         if(K1==0)                                //檢測鍵按下
  25.         {
  26.                 if((++count>=100)&&(key_sign==0))//100次檢測按鍵如果為0
  27.                 {                       
  28.                         key_sign=1;
  29.                         KeySec++;
  30.                         if(KeySec>=3)
  31.                                 KeySec=0;

  32.                         if(KeySec==0)
  33.                         {       
  34.                                 s=0;
  35.                                 sec=0;
  36.                         }
  37.                         if(KeySec==1)
  38.                                 flag=1;
  39.                         if(KeySec==2)
  40.                                 flag=0;                       
  41.                 }
  42.         }
  43.         else                                         //鍵松手
  44.         {
  45.                 count=0;                        //計數(shù)變量清0
  46.                 key_sign=0;                        //自鎖標志清0
  47.         }
  48. }

  49. void Digdisplay()
  50. {
  51.         static u8 i;
  52.         P0=0x00;//消隱
  53.         switch(i)//位選,選擇點亮的數(shù)碼管
  54.         {
  55.                 case(0):LSA=0;LSB=0;LSC=0;P0=smgduan[sec%10];i=1;break;//顯示第0位
  56.                 case(1):LSA=1;LSB=0;LSC=0;P0=smgduan[sec/10];i=0;break;//顯示第1位
  57.         }
  58. }

  59. void main()
  60. {
  61.         Time0Init();
  62.         while(1)
  63.         {
  64.                 if(TF0==1)
  65.                 {
  66.                         TF0=0;
  67.                         TH0=0xFC;
  68.                         TL0=0x18;
  69.                         if(flag==1)
  70.                         {
  71.                                 s++;
  72.                                 if(s>=1000) //到達1s時間
  73.                                 {
  74.                                         s=0;
  75.                                         sec++;
  76.                                         if(sec>99)
  77.                                                 sec=0;//計時到99s重新開始
  78.                                 }
  79.                         }
  80.                         Digdisplay();//動態(tài)數(shù)碼管顯示,周期1ms
  81.                 }
  82.                 keyscan();//按鍵掃描
  83.         }
  84. }
復制代碼



回復

使用道具 舉報

7#
ID:404797 發(fā)表于 2019-3-3 10:55 | 只看該作者
HC6800-ES-V2.0 發(fā)表于 2019-3-3 09:42
用外部中斷啊,就不怕掃描不到了。

不是外部中斷,是計時器0中斷,按鍵是用于中斷繼續(xù)的
回復

使用道具 舉報

8#
ID:330301 發(fā)表于 2019-3-3 11:35 | 只看該作者
1.#include<reg52.h>
2.typedef unsigned int u8;
3.typedef unsigned char u16;
看開頭就感覺是神奇的代碼,雖然是例行公事,但還是需要細心,畢竟定義都錯了,引用就各種神級bug
回復

使用道具 舉報

9#
ID:483399 發(fā)表于 2019-3-3 12:35 | 只看該作者
謝謝各位的指教,才剛開始學單片機,錯誤低級請大家見諒
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復 返回頂部 返回列表