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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2271|回復: 13
打印 上一主題 下一主題
收起左側

單片機秒表 可以實現開始、暫停、復位功能 求指導記錄和查看功能

[復制鏈接]
跳轉到指定樓層
樓主
多功能秒表系統設計
設計要求:
(1)兩位LED顯示,顯示時間為00~99秒。
(2)具有開始、暫停、復位功能。
(3)在秒表工作過程中能通過按鍵多次(不少于4次)記錄當前的時間。
(4)可以通過按鈕查看記錄的時間 。
本人現在可以實現開始、暫停、復位功能,后面的記錄和查看功能有沒有哪位大佬可以幫忙改一下。求求了。
#include<reg51.h>
#define uint unsigned int
#define uchar unsigned char
sbit w0=P2^0;
sbit w1=P2^1;

sbit s1=P3^4;      //啟動
sbit s2=P3^5;     //暫停
sbit s3=P3^6;     //清零
sbit s4=P3^7;     //記錄
sbit s5=P3^3;     //查詢

unsigned char recordTimes[4]; // 記錄的時間,長度為4
uchar count=0;        //對50ms定時時間進行計數   
uchar miao=0;       //秒計數器
uchar j,k;
unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
                        0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};//共陰極
void timedr0init()
{
  TMOD=0x01;
        TH0=(65536-50000)/256;
        TL0=(65536-50000)%256;
        TR0=0;
        ET0=1;
        EA=1;
}
void delay(unsigned char i)
{
  for(j=i;j>0;j--)
    for(k=125;k>0;k--);
}                           //延時
void display(uchar n)
{
   uchar c,d;
   c=n/10;
   d=n%10;
   P0=0x00;        //xiao
   P0=table[c];
   w0=0,w1=1;
   delay(5);

   P0=0x00;
   P0=table[d];
   w1=0,w0=1;
   delay(5);
                                              // P0=table[n/10];w0=0,w1=1;
                                        // P0=tabie[n%10];w0=1,w1=0;        
}
void scankeys()
{static bit recordFlag = 0;     //聲明了一個靜態的位變量 recordFlag,并將其初始化為 0
        static unsigned char recordIndex = 0;//靜態無字符變量

if(s1==0)//啟動
{
TR0=1;                  
}
if(s2==0)//暫停
{
TR0=0;                  
}
if(s3==0)//清零
{
TR0=0,miao=count=0;                  
}

        if (s4 == 0) {  // 記錄
        if (!recordFlag && recordIndex < 4) {
            recordFlag = 1;

                recordTimes[recordIndex++] = miao;
                                                                while (s4 == 0);
                                                                delay(100); // 等待按鍵釋放,防止重復記錄

        }
    }
                else {
        recordFlag = 0;
    }

    if (s5 == 0) {  // 查看記錄
        if (recordIndex > 0)
                                        {
            uchar i;
            for (i = 0; i < recordIndex; i++)
                                        {
                display(recordTimes[ i]);
                delay(100);
                                        }
                                }
                        }                        
                }
void main()
{
       timedr0init();

        while(1)
        {
        display(miao);
                                        scankeys();

    }
}

void time0() interrupt 1
{       TH0=(65536-50000)/256;
        TL0=(65536-50000)%256;
        count++;
        if(count==20)
        {
            count=0;
                                          miao++;
            if(miao==100)
            miao=0;        

        }

}

51hei.png (70.26 KB, 下載次數: 50)

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

使用道具 舉報

沙發
ID:213173 發表于 2023-11-12 20:12 | 只看該作者
按下記錄鍵,緩存recordTimes[3]=recordTimes[2];recordTimes[2]=recordTimes[1];recordTimes[1]=recordTimes[0];全部后移,再將當前秒數存在recordTimes[0]。始終保存最近4次的記錄
回復

使用道具 舉報

板凳
ID:1099267 發表于 2023-11-12 21:03 | 只看該作者
wulin 發表于 2023-11-12 20:12
按下記錄鍵,緩存recordTimes[3]=recordTimes[2];recordTimes[2]=recordTimes[1];recordTimes[1]=recordTim ...

大佬,程序添加在哪里,求指導,純新手,不是特別熟練
回復

使用道具 舉報

地板
ID:1099267 發表于 2023-11-12 21:27 | 只看該作者
wulin 發表于 2023-11-12 20:12
按下記錄鍵,緩存recordTimes[3]=recordTimes[2];recordTimes[2]=recordTimes[1];recordTimes[1]=recordTim ...

if (s4 == 0) {  // 記錄
        if (!recordFlag && recordIndex < 4) {
            recordFlag = 1;

            // 將記錄后移
            for ( i = 3; i > 0; i--) {
                recordTimes[ i] = recordTimes[i-1];
            }
            // 記錄當前時間
            recordTimes[0] = miao;

            while (s4 == 0);
            delay(100); // 等待按鍵釋放,防止重復記錄
        }
    } else {
        recordFlag = 0;
    }
回復

使用道具 舉報

5#
ID:1099267 發表于 2023-11-12 21:38 | 只看該作者
wulin 發表于 2023-11-12 20:12
按下記錄鍵,緩存recordTimes[3]=recordTimes[2];recordTimes[2]=recordTimes[1];recordTimes[1]=recordTim ...

求大佬指導,純萌新
回復

使用道具 舉報

6#
ID:195496 發表于 2023-11-12 22:08 | 只看該作者
建產數組存儲數據,再修改按鍵程序,上下翻看
回復

使用道具 舉報

7#
ID:123289 發表于 2023-11-14 09:50 | 只看該作者
本帖最后由 yzwzfyz 于 2023-11-15 09:36 編輯

1、建立一個二維數組【P,2】,P記錄你歷史上記錄的秒表數據是第幾個。2秒表讀數0-99。
2、建立三個指針P1\P2\P3:P1=當前的秒表P號,P2=【記錄】按鍵指向的P號,P3=【查詢】按鍵指向的P號。
3、顯示程序,只從【P1,2】取數字顯示,也即只顯示P1所指向的數據。
鍵操作:
1、按下【記錄】鍵:P2=P2+1(表示進行到第幾個記錄了),P1=P2(顯示指向新的P2記錄)。
2、按下【查詢】鍵:P3=P3+1(表示查詢到第幾個記錄了),P1=P3(對查詢到的記錄進行顯示)。
3、按下【開始、清0、暫定】鍵:加一條 P1 = P2 (顯示改為【記錄】所指定的記錄號,并在此記錄上進行操作,這樣保證【查詢】后,能回到之前的記錄號,不致混亂),其它操作與你的定義相同。
如此:
能讓你記錄到P組秒表數據(循環使用1-P),做到P組數據互不干擾,可查可詢,且查詢不影響當前的操作,甚至在讀秒時查詢也不影響當前的秒表計秒工作。
回復

使用道具 舉報

8#
ID:397054 發表于 2023-11-14 11:19 | 只看該作者
他已經建立數組了,只是沒必要二維吧,序號就可以作為記錄的數據是第幾個。問題是他這個程序實在是太勉強了,直接驅動數碼管不是這種方法,他的 display 函數這樣寫是不對的,只能在不按S4和S5的情況下正常,但也只是看似正常,這就是我說的“勉強”的意思,當按下S4或S5時,在按下的這段時間里有一個數碼管會滅,而亮的那個數碼管會保持,不會變化,尤其是S4,只要不抬起來一直保持這樣不變,這恐怕并不是你需要的功能吧,按下S5鍵情況就更復雜了,按下不動基本上是亂顯示,這取決于你的delay函數,delay(100)究竟會延遲多長時間,如果時間很短,那就是亂顯示,如果時間很長比如超過0.5秒,會看到兩個數碼管閃亮幾次,次數由記錄的次數決定,最多4次,閃亮的時間很短由display函數中的delay(5);決定,基本也看不清,如果按著S5不放就是這個過程反復循環。

由這個分析能夠猜出你的用意,想的是挺美,但這個程序做不到,僅僅是秒表勉強能用。要修改的話,量也不是很大,但框架就變了。。。
回復

使用道具 舉報

9#
ID:1099267 發表于 2023-11-14 21:19 | 只看該作者
鵜鶘 發表于 2023-11-14 11:19
他已經建立數組了,只是沒必要二維吧,序號就可以作為記錄的數據是第幾個。問題是他這個程序實在是太勉強了 ...

大佬,可以幫忙修改一下嗎,新手不是特別懂
回復

使用道具 舉報

10#
ID:1099267 發表于 2023-11-14 21:26 | 只看該作者
1556544 發表于 2023-11-14 21:19
大佬,可以幫忙修改一下嗎,新手不是特別懂

上面呢位大佬講的二維數組沒有聽說過,剛學得新手
回復

使用道具 舉報

11#
ID:397054 發表于 2023-11-15 21:30 | 只看該作者
原理更重要吧,清楚了原理怎樣做是很自由的,我先把原理說下,一個修改方案提供給你,你也不必照搬的,可隨意修改試驗。

這種LED數碼管的直接驅動都是以掃描方式實現的,且掃描的頻率要穩定不受其他程序部分的干擾,你的程序之所以僅在秒表時看起來正常,是因為它就是在快速重復掃描,但你這種掃描太易受到干擾而停頓,即在主函數的while中循環,當你不按按鍵或只按s1-s3時,scankeys可以快速返回,顯示會連續,但按下s4或者s5我上面那貼說過因為延遲和判斷是否抬起它就會延遲返回或者按著不放它就不返回,顯示就不正常。

所以這種數碼管的顯示一般都是分兩個部分,驅動和賦值是分開的,驅動部分只是將顯示緩沖區的內容依次輪換送數碼管顯示,而向顯示緩沖區賦值是另一部分,可以在程序的任何地方、任何時候執行(在這里顯示緩沖區就是c、d兩個無符號字符變量)。驅動部分又必須等頻率不斷重復執行,這樣數碼管才會看起來常亮且不受干擾而停頓,要做到這點驅動部分就只能放在計時器的中斷程序里,這樣,你的display函數就要修改,把它分成兩部分,計算和賦值部分(實際只有兩句)留下,其余都移到中斷程序中。

但這還不夠,引起這個中斷的是計時器,而你啟停秒表是靠啟停這個計時器實現的,這又不行,因為計時器一停中斷就消失,數碼管沒了驅動就立即不亮了,所以這個也要改,計時器只要一上電初始化后就必須立即工作直到斷電,這樣才能使顯示驅動不停地等間隔刷新數碼管,并且頻率要足夠高以使眼睛覺察不出閃爍。這又引來了一個問題,看你的程序參數,你用的是12兆的晶振,計時器0,模式1,中斷頻率是20Hz,作為秒表用,這個沒問題,但兼作顯示驅動頻率太低,數碼管肯定會閃,,,所以兼顧編程方便和人眼的視覺暫留特性,這個頻率應該提高到100Hz,為此 timedr0init 函數中的50000應改成10000,對應的,中斷函數中的 if(count==20)改成 if(count==100),即每100次中斷為一秒到。由于計時器一上電初始化后就要立即工作,所以這個函數中的另一處TR0=0;要改成TR0=1;。既然TR0不能再=0了,那么啟停秒表就用更常規的辦法:設置一個全局的標志位,比如Bit Stop_run,加在程序頭部的說明區中;而且作為顯示緩沖區的變量c、d也要全局化,因為主函數要向它賦值,中斷函數也要用到它,為此將他倆的定義從display函數中取出也放置在此處。啟停秒表就靠標志位Stop_run被置1/清零來實現,置1表示秒表啟動;清零表示暫停/停止,反過來當然也可以,,,相應的中斷程序中miao++;和下面的兩句改為:

if (Stop_run)
  {
     miao++;
     if(miao==100) miao=0;
  }

如果Stop_run的01定義與此相反的話前面加個非號就行了。Stop_run的置1/清零就用你的scankeys函數中的s1-s3處理語句來執行,將TR0=0或1改成相應的Stop_run=0或1。

另外,你也沒說你想達到什么目的,秒表就不用說了,主要是回顯那幾個記錄值用什么方式、要達到什么效果,根據你貼出的程序看,你大概想以這樣的方式回顯:按下s5健,就立即在數碼管上依次顯示所有記錄值,每個記錄值顯示的時間由delay(100);控制。你的display函數在scankeys函數中的這種用法根本達不到目的,且邏輯還很混亂,并且delay函數的性能究竟怎樣,delay(100)究竟能延時多長時間這都不知道,直覺看它遠不會達到1秒,如果你真想用這種方式回顯,那么每個記錄值顯示的時間怎么也應該超過1秒吧。

根據這些條件我給你提供一個修改方案供你參考:

在變量聲明區后面再附加兩句:

bit stp_run=0;
uchar c,d,timer;



函數timedr0init改為:

void timedr0init()
{
  TMOD=0x01;
        TH0=(65536-10000)/256;
        TL0=(65536-10000)%256;
        TR0=1;
        ET0=1;
        EA=1;
}



增加一個延時函數:

void wait(unsigned char t)//t單位為10ms,當t=200時,即延時2秒。
  {
    timer=0;
    while (timer<t);
   }



函數display改為:

void display(uchar n)
{
   c=n/10;
   d=n%10;
}



函數scankey改為:

void scankeys()
{static bit recordFlag = 0;     //聲明了一個靜態的位變量 recordFlag,并將其初始化為 0
        static unsigned char recordIndex = 0;//靜態無字符變量

if(s1==0)//啟動
{
stp_run=1;                  
}
if(s2==0)//暫停
{
stp_run=0;                  
}
if(s3==0)//清零
{
stp_run=miao=count=0;                  
}

        if (s4 == 0) {  // 記錄
        if (!recordFlag && recordIndex < 4) {
            recordFlag = 1;

                recordTimes[recordIndex++] = miao;
                                                                while (s4 == 0);
                                                                delay(100); // 等待按鍵釋放,防止重復記錄

        }
    }
                else {
        recordFlag = 0;
    }

    if (s5 == 0) {  // 查看記錄
        if (recordIndex > 0)
                                        {
            uchar i;
            for (i = 0; i < recordIndex; i++)
                                        {
                display(recordTimes[ i]);
                wait(150);        //延時1.5秒,即每個數字顯示1.5秒。
                                        }
                                }
                        }                        
                }



中斷程序改動比較大,但大部分代碼可以復制/粘貼過來:

void time0() interrupt 1
{
        static bit dp;
        TH0=(65536-10000)/256;
        TL0=(65536-10000)%256;
        P0=0x00;        //xiao
        timer++;
        count++;
        if(count==100)
        {
           count=0;
           if (stp_run)
             {
                miao++;
                if (miao==100) miao=0;
             }

        }
        if (dp=~dp)
          {
             P0=table[c];
             w0=0,w1=1;
          }
         else
         {
             P0=table[d];
             w1=0,w0=1;
         }
}


未提及的,就保留原文。

評分

參與人數 1黑幣 +100 收起 理由
admin + 100 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

12#
ID:1099267 發表于 2023-11-16 10:47 | 只看該作者
鵜鶘 發表于 2023-11-15 21:30
原理更重要吧,清楚了原理怎樣做是很自由的,我先把原理說下,一個修改方案提供給你,你也不必照搬的,可隨 ...

太牛了,大佬
回復

使用道具 舉報

13#
ID:397054 發表于 2023-11-17 15:27 | 只看該作者
呵呵你試沒試,結果怎樣?你是不是這個意思,達沒達到目的?
另外,我的那個中斷程序中前半部分不甚合理,應該把對stp_run的判斷放在最外層,還有就是count和miao的+1都沒不要單獨存在,都可以合并到條件判斷中,這樣程序就更簡潔清晰,也更符合C風范:

void time0() interrupt 1
{
  static bit dp;
  TH0=(65536-10000)/256;
  TL0=(65536-10000)%256;
  P0=0x00;        //xiao
  timer++;
  if (stp_run)
    {
       if(++count==100)
         {
            count=0;
            if (++miao==100)
              {
                 miao=0;
              }
         }
    }
  if (dp=~dp)
    {
       P0=table[c];
       w0=0,w1=1;
    }
   else
    {
       P0=table[d];
       w1=0,w0=1;
    }
}
回復

使用道具 舉報

14#
ID:1099267 發表于 2023-11-21 13:33 | 只看該作者
鵜鶘 發表于 2023-11-17 15:27
呵呵你試沒試,結果怎樣?你是不是這個意思,達沒達到目的?
另外,我的那個中斷程序中前半部分不甚合理, ...

試了,符合我想的功能
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 一二三四在线视频观看社区 | 欧美精品成人一区二区三区四区 | 久久在线免费 | 一区二区中文字幕 | 黄色a级一级片 | 妖精视频一区二区三区 | 在线观看免费av网 | www狠狠爱com | 国产伦一区二区三区四区 | 国产精品福利视频 | 九九久久精品视频 | 亚洲精品中文字幕 | 成人久久久| 激情小说综合网 | 婷婷二区| 久久久99国产精品免费 | 蜜桃精品视频在线 | 精品国产乱码久久久久久丨区2区 | 天天玩夜夜操 | 精品久久久久久久久久 | 国产精品一区二区三区在线 | 国产在线视频99 | 91亚洲欧美 | 成人免费视频观看 | 国产真实精品久久二三区 | 日日夜夜精品视频 | 精品美女视频在免费观看 | 国产成人精品a视频 | 国产精品久久精品 | 欧美成人免费在线 | 天天爱天天操 | 天堂影院av | 日韩毛片| 欧美国产日韩在线观看 | 国产精品久久久久久久7电影 | 欧美啊v在线观看 | 黑人精品欧美一区二区蜜桃 | 91大神在线资源观看无广告 | 亚洲国产成人精品久久久国产成人一区 | 国产精品视频久久久久久 | 一级毛片视频 |