stc89c52和LCD1602實現(xiàn)的秒表

功能描述

  1. 使用1602顯示時間 分鐘-秒-10毫秒 (256分鐘以內(nèi),0.01秒精度楞抡,達到最大時間蜂鳴器警告)
  2. 記錄20組數(shù)據(jù)
  3. 使用三個按鍵 K1開始/暫停 K2重置/計次 K3前一條記錄 K4后一條記錄(說明:運行時 K2添加一條記錄)

效果如下圖

Paste_Image.png

1602操作程序

#include <reg51.h>
sbit RS = P1^0;
sbit RW = P1^1;
sbit EN = P2^5;
sbit BUSY = P0^7;
#define DATA P0

//讀忙信號
void wait(void)
{
    P0 = 0xFF;
    do
    {
        RS = 0;
        RW = 1;
        EN = 0;
        EN = 1;
    }
    while (BUSY == 1);
    EN = 0;
}
//寫命令到1602
void writeCMD(unsigned char cmd)
{
    wait();
    DATA = cmd;
    EN = 1;
    RS = 0;
    RW = 0;
    EN = 0;
}
//寫數(shù)據(jù)到1602
void writeData(unsigned char dat)
{
    wait();
    DATA = dat;
    EN = 1;
    RS = 1;
    RW = 0;
    EN = 0;
}
//1602初始化
void init1602()
{
    writeCMD(0x38);
    writeCMD(0x08);
    writeCMD(0x01);
    writeCMD(0x06);
    writeCMD(0x0C);
    writeCMD(0x80);
}

秒表實現(xiàn)主程序

#include <reg51.h>
#include "1602.h"
#include <stdio.h>

#define noBtn               0
#define startOrPuaseBtn     1
#define resetOrCounterBtn   2
#define previousBtn         3
#define nextBtn             4
#define RE_NUM              20
#define FM_OFF              1
#define FM_ON               0
typedef struct{
    unsigned char minute;
    unsigned char second; 
    unsigned char msec;     
}time;

sbit K1 = P3^4;//開始、暫停按鍵
sbit K2 = P3^5;//重置析藕、計次按鍵
sbit K3 = P3^6;//查看上一條記錄按鍵
sbit K4 = P3^7;//查看下一條記錄按鍵
sbit FM = P2^3;//蜂鳴器 0 開 1 關
unsigned char  msec = 0;
//bit runState = 0;
void Delay10ms()        //@11.0592MHz
{
    unsigned char i, j;

    i = 18;
    j = 235;
    do
    {
        while (--j);
    } while (--i);
}

//按鍵檢測
unsigned char scanKey()
{
    P3 = 0xF0;
    if(P3!=0xF0)//有按鍵 延時10ms消抖
    {
        Delay10ms();
    }
    else
    {
        return noBtn;
    }
    if(K1==0) return startOrPuaseBtn;
    if(K2==0) return resetOrCounterBtn;
    if(K3==0) return previousBtn;
    if(K4==0) return nextBtn;
    return noBtn;
}
void Timer0Init(void)       //50毫秒@11.0592MHz
{
    //AUXR &= 0x7F;     //定時器時鐘12T模式
    TMOD &= 0xF0;       //設置定時器模式
    TMOD |= 0x01;       //設置定時器模式
    TL0 = 0x00;     //設置定時初值
    TH0 = 0xDC;     //設置定時初值
    TF0 = 0;        //清除TF0標志
    TR0 = 0;        //定時器0開始計時  //開始時暫停的
    ET0 = 1;        //定時器0中斷開啟
    EA = 1;         //打開全局中斷
}
//在1602的row行column列顯示dat
//row 0 - 1
//column 0 - 15
void dis1602(unsigned char row, unsigned char column, char dat)//
{
    writeCMD(0x80+row*0x40+column);
    writeData(dat);
}
//在1602的row行column列顯示字符串str
void disStr1602(unsigned char row, unsigned char column, char *str)//
{
    writeCMD(0x80+row*0x40+column);
    while(*str)
    {
        writeData(*str++);
    }
}
void main()
{
    unsigned char msecTemp = 0, keyValue = noBtn, keyTemp = noBtn;
    unsigned char recordTotal = 0, currentRecord = 0;
    unsigned char minute = 0, second = 0;
    char str[16] = "";
    time idata record[RE_NUM] = {0}; //記錄存放
    init1602();
    Timer0Init();
    disStr1602(0,0, "stop   000:00:00");//初始化顯示
    disStr1602(1,0, "00/00  000:00:00");
    //dis1602(0,10,':');
    //dis1602(0,13,':');
    while(1)
    {
        keyTemp = scanKey(); //當前key值
        if(keyValue!=keyTemp) //key狀態(tài)發(fā)生變化則處理按鍵功能
        {
            keyValue = keyTemp;
            switch(keyValue)
            {
                case startOrPuaseBtn: //啟動或暫停
                    TR0 = !TR0;
                    if(TR0)
                    {
                        disStr1602(0, 0, "start");
                    }
                    else
                    {
                        disStr1602(0, 0, "stop ");
                    }
                    break;
                case resetOrCounterBtn:
                    if(TR0)//運行狀態(tài) 增加記錄
                    {
                        if(recordTotal < RE_NUM)
                        {
                            record[recordTotal].minute = minute;
                            record[recordTotal].second = second;
                            record[recordTotal].msec = msec;
                            recordTotal++;
                            currentRecord = recordTotal;
                        }
                        sprintf(str,"%02d/%02d  %03d:%02d:%02d",
                                (int)currentRecord,(int)recordTotal,
                                (int)record[recordTotal-1].minute,
                                (int)record[recordTotal-1].second,
                                (int)record[recordTotal-1].msec);
                        disStr1602(1, 0, str);//顯示 記錄
                    }
                    else //暫停狀態(tài) 重置
                    {
                        FM = FM_OFF;
                        minute = 0;
                        second = 0;
                        msec = 0;
                        recordTotal = 0;
                        currentRecord = 0;
                        disStr1602(0,0, "stop   000:00:00");//重置顯示
                        disStr1602(1,0, "00/00  000:00:00");//重置顯示
                    }
                    break;
                case previousBtn: //前一條記錄
                    if(currentRecord > 1)
                    {
                        currentRecord--;
                        sprintf(str,"%02d/%02d  %03d:%02d:%02d",
                                (int)currentRecord,(int)recordTotal,
                                (int)record[currentRecord-1].minute,
                                (int)record[currentRecord-1].second,
                                (int)record[currentRecord-1].msec);
                        disStr1602(1, 0, str);//顯示 記錄
                    }
                    break;
                case nextBtn: //查看后一條記錄
                    if(currentRecord < recordTotal)
                    {
                        currentRecord++;
                        sprintf(str,"%02d/%02d  %03d:%02d:%02d",
                                (int)currentRecord,(int)recordTotal,
                                (int)record[currentRecord-1].minute,
                                (int)record[currentRecord-1].second,
                                (int)record[currentRecord-1].msec);
                        disStr1602(1, 0, str);//顯示 記錄
                    }
                    break;  
            }
        }
        if(msecTemp!=msec)//每變一次10ms刷新
        {
            msecTemp = msec;
            if(msec>99)
            {
                if(++second>59)
                {
                    minute++;
                    second = 0;
                    dis1602(0, 7,'0'+minute/100);
                    dis1602(0, 8,'0'+minute/10%10);
                    dis1602(0, 9,'0'+minute%10);
                    if(minute==0xFF)//達到了秒表最大值 不能再繼續(xù) 打開蜂鳴器提醒 并暫停秒表 等待重置
                    {
                        TR0 = 0;
                        FM = FM_ON;
                    }
                }
                else
                {
                    dis1602(0,11,'0'+second/10);
                    dis1602(0,12,'0'+second%10);
                }
                msec = 0;
            }
            dis1602(0,14,'0'+msec/10);
            dis1602(0,15,'0'+msec%10);
        }
    }
    
}

void T0_50ms() interrupt 1
{
    TL0 = 0x00;     //設置定時初值
    TH0 = 0xDC;     //設置定時初值
    //if(runState)
    {
        msec++;
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末召廷,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子账胧,更是在濱河造成了極大的恐慌竞慢,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,729評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件治泥,死亡現(xiàn)場離奇詭異筹煮,居然都是意外死亡,警方通過查閱死者的電腦和手機居夹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,226評論 3 399
  • 文/潘曉璐 我一進店門败潦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人准脂,你說我怎么就攤上這事劫扒。” “怎么了狸膏?”我有些...
    開封第一講書人閱讀 169,461評論 0 362
  • 文/不壞的土叔 我叫張陵沟饥,是天一觀的道長。 經(jīng)常有香客問我环戈,道長闷板,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,135評論 1 300
  • 正文 為了忘掉前任院塞,我火速辦了婚禮遮晚,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘拦止。我一直安慰自己县遣,他們只是感情好,可當我...
    茶點故事閱讀 69,130評論 6 398
  • 文/花漫 我一把揭開白布汹族。 她就那樣靜靜地躺著萧求,像睡著了一般。 火紅的嫁衣襯著肌膚如雪顶瞒。 梳的紋絲不亂的頭發(fā)上夸政,一...
    開封第一講書人閱讀 52,736評論 1 312
  • 那天,我揣著相機與錄音榴徐,去河邊找鬼守问。 笑死匀归,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的耗帕。 我是一名探鬼主播穆端,決...
    沈念sama閱讀 41,179評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼仿便!你這毒婦竟也來了体啰?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,124評論 0 277
  • 序言:老撾萬榮一對情侶失蹤嗽仪,失蹤者是張志新(化名)和其女友劉穎荒勇,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體闻坚,經(jīng)...
    沈念sama閱讀 46,657評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡枕屉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,723評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了鲤氢。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,872評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡西潘,死狀恐怖卷玉,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情喷市,我是刑警寧澤相种,帶...
    沈念sama閱讀 36,533評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站品姓,受9級特大地震影響寝并,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜腹备,卻給世界環(huán)境...
    茶點故事閱讀 42,213評論 3 336
  • 文/蒙蒙 一衬潦、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧植酥,春花似錦镀岛、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,700評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至卸留,卻和暖如春走越,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背耻瑟。 一陣腳步聲響...
    開封第一講書人閱讀 33,819評論 1 274
  • 我被黑心中介騙來泰國打工旨指, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留赏酥,地道東北人。 一個月前我還...
    沈念sama閱讀 49,304評論 3 379
  • 正文 我出身青樓淤毛,卻偏偏與公主長得像今缚,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子低淡,可洞房花燭夜當晚...
    茶點故事閱讀 45,876評論 2 361

推薦閱讀更多精彩內(nèi)容