久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4949|回復: 15
收起左側

單片機秒表程序顯示問題

[復制鏈接]
ID:797796 發表于 2020-7-13 21:19 | 顯示全部樓層 |閱讀模式
220黑幣
程序要求按 A 鍵再按 B 鍵后,顯示兩鍵按下之間的時間 t(t <60s),單位為 ms。時間 t 用五位十進制整數顯示,由一位數碼管從最高位開始逐位顯示一遍。可是我的程序在按鍵之后顯示的數字好像和時間不對應,請問大佬們這是哪里出錯了?另外還要求轉成BCD碼后譯碼顯示輸出,這個應該怎么改?
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
uint m=0;
sbit A1=P3^4;
sbit A2=P3^5;
uint count,t;
uchar d,e,f;
uchar code table[]={0x14,0xde,0x38,0x1a,0xd2,0x13,0x11,0x9e,0x10,0x12};
uchar code cnt[]={10000,1000,100,10,1};
void delay(void)   //誤差 0us
{
    unsigned char a,b,c;
    for(c=67;c>0;c--)
        for(b=124;b>0;b--)
            for(a=167;a>0;a--);
}

void start()
{
        TMOD=0x01; //T0 使用工作方式 1
        TH0=(65536-1000)/256; //1ms 定時
        TL0=(65536-1000)%256;
        EA=1;
        ET0=1;
        TR0=0;
}
void time0(void) interrupt 1 //T0 中斷服務子程序
{
        TH0=(65536-1000)/256;
        TL0=(65536-1000)%256;
        count++;
        if(count>=1)
        {count=0;
         t++;
         if(t>=60000)
         {t=0;}
        }
}


void display(uint t)  //顯示子程序,從第一位開始逐位顯示
{
         uint k=0,v;
         for(;k<5;k++)
         {
                 v=t/cnt[k]%10 ;
                 P0=table[v];
                delay();
            {for(f=23;f>0;f--)
                for(e=152;e>0;e--)
                    for(d=70;d>0;d--)
                                P0=0xFF;
                }
         }

}
void main(void)
{        start();
while(1)
{
        P0=0xb7;
        P3=0x30;
        if(P3!=0x30)
        {if(A1==0)                          //按鍵掃描
                {TR0=1;}
         if(A2==0)
                 {
                        TR0=0;
                        while(!A2);
                        while(P3==0x30)
                        {
                                display(t);
                        }
                }
        
        }               
}
}
捕獲.PNG
圖片.png

最佳答案

查看完整內容

完全下圖做時間電路和程序,共陽數碼管,可以實現樓主想要的功能。 A、B 鍵互鎖,不需要消抖,用閃爍表示換顯示位,否則相鄰數字相同無法分辨。小數點前為妙,小數點后為毫秒。
回復

使用道具 舉報

ID:213173 發表于 2020-7-13 21:19 | 顯示全部樓層
完全下圖做時間電路和程序,共陽數碼管,可以實現樓主想要的功能。 A、B 鍵互鎖,不需要消抖,用閃爍表示換顯示位,否則相鄰數字相同無法分辨。小數點前為妙,小數點后為毫秒。
無標題.jpg

  1. #include<reg51.h>
  2. #define uchar unsigned char
  3. #define uint unsigned int
  4. sbit A1=P3^4;
  5. sbit A2=P3^5;
  6. uint m=0;
  7. uint count,t;
  8. uchar code table[]={//共陽數碼管"0~f .-"
  9.         0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
  10.         0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf,0x7f};
  11. uchar cnt[6]={0xc0,0xc0,0xc0,0xc0,0xc0,0xc0};//小數緩存
  12. bit flag=0;
  13. bit sign=0;
  14. bit init=0;

  15. void start()
  16. {
  17.         TMOD=0x01; //T0 使用工作方式 1
  18.         TH0=(65536-1000)/256; //1ms 定時
  19.         TL0=(65536-1000)%256;
  20.         EA=1;
  21.         ET0=1;
  22.         TR0=1;
  23. }

  24. void display()  //顯示子程序,從第一位開始逐位顯示't 00秒 000毫秒'
  25. {
  26.         static uint j=0;
  27.         if(sign)
  28.                 P0=0xbf;//等待計數時顯示'-'
  29.         else
  30.         {       
  31.                 if(j<=900)
  32.                         P0=cnt[m];
  33.                 else if(init==1)
  34.                         P0=0xff;//閃爍表示換位顯示
  35.                 j++;
  36.                 if(j>=1000)
  37.                 {
  38.                         j=0;
  39.                         m++;
  40.                         m%=6;
  41.                 }
  42.         }
  43. }
  44. void main(void)
  45. {
  46.         start();
  47.         P0=0xc0;//初始顯示0
  48.         while(1)
  49.         {
  50.                 if(A1==0 && flag==0) //按鍵掃描
  51.                 {
  52.                         flag=1;
  53.                         count=0;                               
  54.                         t=0;
  55.                         sign=1;
  56.                         init=1;
  57.                 }
  58.                 if(A2==0 && flag==1)
  59.                 {
  60.                         sign=0;
  61.                         flag=0;
  62.                         cnt[0]=0x87;
  63.                         cnt[1]=table[t/10];
  64.                         cnt[2]=table[t%10]&0x7f;//加秒點
  65.                         cnt[3]=table[count/100];
  66.                         cnt[4]=table[count/10%10];
  67.                         cnt[5]=table[count%10];
  68.                         m=0;
  69.                 }
  70.         }
  71. }

  72. void time0(void) interrupt 1 //T0 中斷服務子程序
  73. {
  74.         TH0=(65536-1000)/256;
  75.         TL0=(65536-1000)%256;
  76.         if(sign)
  77.         {
  78.                 count++;
  79.                 if(count>=1000)
  80.                 {
  81.                         count=0;
  82.                         t++;
  83.                         if(t>=60)
  84.                         {
  85.                                 t=0;
  86.                         }
  87.                 }
  88.         }
  89.         display();
  90. }
復制代碼



回復

使用道具 舉報

ID:789121 發表于 2020-7-13 23:12 | 顯示全部樓層
要不要把源文件發上來測試一下
回復

使用道具 舉報

ID:451718 發表于 2020-7-14 16:33 | 顯示全部樓層
1,為什么要在沒有時間定標的主循環中去控制定時器?  時鐘就一直讓它走,只去采集和記錄就好了嗎。 你亂控制主定時的TR0,  時間不亂才怪。
2,   count++;
        if(count>=1)
        {count=0;
         t++;
這段是干啥?     實在無法理解。
3,   8段數碼管輸出的不是BCD碼。是你那個table[]數組對應的控制值,而且這個值分陰碼和陽碼,根據你P0口的線序不同,這個控制值也會不同。(為什么要線序不同? 等你自己布線經驗多一點就明白了)  你這個顯示子程序,有點花。  不太容易懂的,也不利于你弄明白LED的顯示原理。想弄明白,還是找教程看吧,論壇上就有的。
回復

使用道具 舉報

ID:797796 發表于 2020-7-14 16:41 | 顯示全部樓層
wulin 發表于 2020-7-14 12:31
完全下圖做時間電路和程序,共陽數碼管,可以實現樓主想要的功能。 A、B 鍵互鎖,不需要消抖,用閃爍表示換 ...

感謝大佬!!另外框圖要求轉成BCD碼后譯碼顯示輸出,你這個顯示子程序是不是也算是符合呢?
回復

使用道具 舉報

ID:797796 發表于 2020-7-14 16:45 | 顯示全部樓層
本帖最后由 Irvingzong 于 2020-7-14 16:48 編輯
robinsonlin 發表于 2020-7-14 16:33
1,為什么要在沒有時間定標的主循環中去控制定時器?  時鐘就一直讓它走,只去采集和記錄就好了嗎。 你亂控 ...

噢噢好的,師傅要求轉成BCD碼后譯碼用十進制顯示輸出,這個是怎么理解呢?我感覺沒有用到BCD碼呀
回復

使用道具 舉報

ID:213173 發表于 2020-7-14 20:42 | 顯示全部樓層
Irvingzong 發表于 2020-7-14 16:41
感謝大佬!!另外框圖要求轉成BCD碼后譯碼顯示輸出,你這個顯示子程序是不是也算是符合呢?

不同的顯示設備需要不同的驅動碼,LED數碼管用的是16進制筆段碼。如果非得轉成BCD碼后再轉成筆段碼就是自找麻煩了。不過樓主用一個數碼管顯示5位數也屬特殊用法,未見有在實際運用中出現過。
回復

使用道具 舉報

ID:213173 發表于 2020-7-14 21:17 | 顯示全部樓層
Irvingzong 發表于 2020-7-14 16:41
感謝大佬!!另外框圖要求轉成BCD碼后譯碼顯示輸出,你這個顯示子程序是不是也算是符合呢?

改成5或6位數碼管顯示較為合理
無標題.jpg

  1. #include<reg51.h>
  2. #define uchar unsigned char
  3. #define uint unsigned int
  4. sbit A1=P3^4;
  5. sbit A2=P3^5;
  6. uint m=0;
  7. uint count,t;
  8. uchar code table[]={//共陽數碼管"0~f .-"
  9.         0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
  10.         0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf,0x7f};
  11. uchar cnt[6]={0x87,0xc0,0xc0,0xc0,0xc0,0xc0};//顯示緩存
  12. bit flag=0;//鍵態標志
  13. bit sign=0;//計時啟動標志

  14. void start()
  15. {
  16.         TMOD=0x01; //T0 使用工作方式 1
  17.         TH0=(65536-1000)/256; //1ms 定時
  18.         TL0=(65536-1000)%256;
  19.         EA=1;
  20.         ET0=1;
  21.         TR0=1;
  22. }

  23. void display()  //顯示子程序,從第一位開始逐位顯示't 00秒 000毫秒'
  24. {
  25.         P2&=0xc0;//位碼清0消隱
  26.         P0=cnt[m];//送段碼
  27.         P2|=0x01<<m;//送位碼
  28.         m++;
  29.         m%=6;
  30. }
  31. void main(void)
  32. {
  33.         start();
  34.         while(1)
  35.         {
  36.                 if(A1==0 && flag==0) //按鍵掃描
  37.                 {
  38.                         flag=1;
  39.                         count=0;                               
  40.                         t=0;
  41.                         sign=1;
  42.                 }
  43.                 if(A2==0 && flag==1)
  44.                 {
  45.                         flag=0;
  46.                         sign=0;
  47.                 }
  48.         }
  49. }

  50. void time0(void) interrupt 1 //T0 中斷服務子程序
  51. {
  52.         TH0=(65536-1000)/256;
  53.         TL0=(65536-1000)%256;
  54.         if(sign)
  55.         {
  56.                 count++;
  57.                 if(count>=1000)
  58.                 {
  59.                         count=0;
  60.                         t++;
  61.                         if(t>=60)
  62.                         {
  63.                                 t=0;
  64.                         }
  65.                 }
  66.         }
  67.         cnt[1]=table[t/10];
  68.         cnt[2]=table[t%10]&0x7f;//加秒點
  69.         cnt[3]=table[count/100];
  70.         cnt[4]=table[count/10%10];
  71.         cnt[5]=table[count%10];
  72.         display();
  73. }
復制代碼



回復

使用道具 舉報

ID:235954 發表于 2020-7-14 22:40 | 顯示全部樓層
閃爍點可以用GP來制作,也可以用LED來閃爍,這就是基本的定時器應用
回復

使用道具 舉報

ID:451718 發表于 2020-7-15 16:16 | 顯示全部樓層
Irvingzong 發表于 2020-7-14 16:45
噢噢好的,師傅要求轉成BCD碼后譯碼用十進制顯示輸出,這個是怎么理解呢?我感覺沒有用到BCD碼呀

轉BCD碼是軟件層面的要求,可能是用來直接匹配到哪個模塊,就可以直接驅動LED8段數碼管了。  我跟你講的是硬件層面的做法,直接用單片機的端口加三極管來驅動LED8段數碼管的方法。
回復

使用道具 舉報

ID:451718 發表于 2020-7-15 16:21 | 顯示全部樓層
Irvingzong 發表于 2020-7-14 16:41
感謝大佬!!另外框圖要求轉成BCD碼后譯碼顯示輸出,你這個顯示子程序是不是也算是符合呢?

手把手教你學51單片機-C語言版 PDF電子書下載
http://www.zg4o1577.cn/bbs/dpj-48477-1.html
(出處: 單片機論壇)
有C語言基礎, 花3天時間看看就能弄明白了
回復

使用道具 舉報

ID:797796 發表于 2020-7-15 18:01 | 顯示全部樓層
wulin 發表于 2020-7-14 21:17
改成5或6位數碼管顯示較為合理

謝謝,不過設計要求用一位數碼管,可是你第一個程序的display()函數我不是很能理解,能再解釋一下嗎
回復

使用道具 舉報

ID:797796 發表于 2020-7-16 10:23 | 顯示全部樓層
robinsonlin 發表于 2020-7-15 16:21
手把手教你學51單片機-C語言版 PDF電子書下載
http://www.zg4o1577.cn/bbs/dpj-48477-1.html
(出處: 單片 ...

大佬們幫我看下,設計框圖規定了顯示子程序,所以我把上面大佬的程序display()函數改了一下,可是運行時數據又亂了,請問是按照樓頂的框圖應該怎么改?
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit A1=P3^4;
sbit A2=P3^5;
uint m=0;
uint count,t,d,e,f;
uchar code table[]={0x14,0xde,0x38,0x1a,0xd2,0x13,0x11,0x9e,0x10,0x12};
uchar cnt[6]={0};//小數緩存
bit flag=0;
bit init=0;

void delay(void)   //誤差 0us
{
    unsigned char a,b,c;
    for(c=67;c>0;c--)
        for(b=124;b>0;b--)
            for(a=167;a>0;a--);
}

void start()
{
        TMOD=0x01; //T0 使用工作方式 1
        TH0=(65536-1000)/256; //1ms 定時
        TL0=(65536-1000)%256;
        EA=1;
        ET0=1;
            TR0=1;
}

void display()  //顯示子程序,從第一位開始逐位顯示't 00秒 000毫秒'
{
        uint j;
        if(flag)
                P0=0xbf;//等待計數時顯示'-'
        else
        {        
                                if(init==1)
                                for(j=5;j>=0;j--)
                                {P0=cnt[j];
                                delay();
                                }
        }
}
void main(void)
{
        start();
        P0=0xb7;//上電提示符
        while(1)
        {
                if(A1==0 && flag==0) //按鍵掃描
                {
                        flag=1;
                        count=0;                                
                        t=0;
                        init=1;                                               
                }
                if(A2==0 && flag==1)
                {
                                                while(!A2);
                        flag=0;
                        cnt[5]=0xbf;
                        cnt[4]=table[t/10];
                        cnt[3]=table[t%10];//加秒點
                        cnt[2]=table[count/100];
                        cnt[1]=table[count/10%10];
                        cnt[0]=table[count%10];
                        m=0;
                }
        }
}

void time0(void) interrupt 1 //T0 中斷服務子程序
{
        TH0=(65536-1000)/256;
        TL0=(65536-1000)%256;
        if(flag)
        {
                count++;
                if(count>=1000)
                {
                        count=0;
                        t++;
                        if(t>=60)
                        {
                                t=0;
                        }
                }
        }
        display();
}
回復

使用道具 舉報

ID:451718 發表于 2020-7-20 15:49 | 顯示全部樓層
Irvingzong 發表于 2020-7-16 10:23
大佬們幫我看下,設計框圖規定了顯示子程序,所以我把上面大佬的程序display()函數改了一下,可是運行時 ...

樓上給你的display()函數是驅動8段數碼管的程序, 而你的要求好像只是驅動某個BCD值模塊的。 都不是一樣的目標對象,你如何能改好。 我們做產品的,很少再用模塊去輔助驅動8段數碼管的,關于BCD值的模塊,沒有研究過,也沒有現成的環境做試驗,這里不好給你提供幫助。 但是,最終是驅動8段數碼管,所以,以下程序備注很經典,你仔細讀懂就會了。
void display()  //顯示子程序,從第一位開始逐位顯示't 00秒 000毫秒'
{
        P2&=0xc0;//位碼清0消隱
        P0=cnt[m];//送段碼
        P2|=0x01<<m;//送位碼
        m++;
        m%=6;
}
步驟大概就是1,消隱; 2,送段碼; 3,送位碼; 4,改變循環值; 5,檢查限定最大循環值。
回復

使用道具 舉報

ID:451718 發表于 2020-7-20 16:03 | 顯示全部樓層
剛剛又看了一下你自己改的程序。 看來你還是沒有深刻理解單片機工作方法,特別定時器這塊。 你的display()函數里面有 delay(),這個delay()是多長時間?  定時器周期又是多久? 請仔細思考這個問題!!!
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 欧美日韩亚洲二区 | 亚洲va欧美va人人爽午夜 | 成人午夜在线观看 | 日韩中文字幕一区二区 | 久久97精品 | 久久久91精品国产一区二区三区 | 日韩精品视频一区二区三区 | 色欧美综合 | 久久久久久久久久久高潮一区二区 | 国产精品久久av | 亚洲精品成人 | 欧美久久视频 | 久久精品16 | 日韩精品在线播放 | 青青久草 | 手机在线观看av | 精品一区二区久久 | 国产亚洲精品久久久久动 | 国产一伦一伦一伦 | 午夜影院视频在线观看 | 免费一区二区三区 | 国产一区高清 | 在线观看免费高清av | 欧美一区二区三区四区视频 | 一区二区免费看 | 一二三四av | 精品国产精品三级精品av网址 | 国产高清av免费观看 | 色性av| 久久久久精 | 97精品国产手机 | 一级二级三级在线观看 | 成年人免费网站 | 日韩午夜| 在线观看亚洲精品 | 男人天堂网址 | 精品国产一二三区 | 欧美日韩精品国产 | 亚洲一区中文 | 在线国产一区二区三区 | 日韩中文在线 |