找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 5069|回復(fù): 8
打印 上一主題 下一主題
收起左側(cè)

LCD1602電子時(shí)鐘

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
/*******************************************************************************
* 實(shí)驗(yàn)名                           : 定時(shí)器實(shí)驗(yàn)
* 使用的IO             :
* 實(shí)驗(yàn)效果       :1602顯示時(shí)鐘,按K3進(jìn)入時(shí)鐘設(shè)置,按K1選擇設(shè)置的時(shí)分秒,按K2選擇
*選擇設(shè)置加1。
*        注意                                        :
*******************************************************************************/
#include<reg51.h>       
#include"lcd.h"
sbit K1=P3^0;
sbit K2=P3^1;
sbit K3=P3^2;
void Delay1ms(unsigned int c);
void TimerConfiguration();
void Int0Configuration();
unsigned char Time;                        //用來計(jì)時(shí)間的值
unsigned char SetPlace;                //設(shè)置修改位
/*******************************************************************************
* 函 數(shù) 名         : main
* 函數(shù)功能                   : 主函數(shù)
* 輸    入         : 無
* 輸    出         : 無
*******************************************************************************/
void main(void)
{
        unsigned char hour=13,minute=14,second=00;
        unsigned char H2[]="  I LOVE YOU!!! ";                           //可以改成任意16個(gè)字符。
        unsigned int i;
        TimerConfiguration();
        Int0Configuration();
        LcdInit();
        LcdWriteCom(0x84);
        LcdWriteData('0'+hour/10);
        LcdWriteData('0'+hour%10);
        LcdWriteData(':');
        LcdWriteData('0'+minute/10);
        LcdWriteData('0'+minute%10);
        LcdWriteData(':');
        LcdWriteData('0'+second/10);
        LcdWriteData('0'+second%10);
        LcdWriteCom(0xc0);
        for(i=0;i<16;i++)                                  //第2行顯示的字符
        {   
                LcdWriteData(H2);                 
        }
        while(1)
        {
                if(TR0==0)
                {        if(K1==0)                        //檢測按鍵K1是否按下
                        {
                                Delay1ms(10);        //消除抖動(dòng)
                                if(K1==0)
                                {  
                                        SetPlace++;
                                        Delay1ms(100);
                                        if(SetPlace>=3)
                                                SetPlace=0;                                       
                                }
                                while((i<50)&&(K1==0))         //檢測按鍵K1是否松開
                                {
                                        Delay1ms(1);
                                        i++;
                                }
                                i=0;                        
                        }
                        switch(SetPlace)
                                {case 0 :
                                        {LcdWriteCom(0x8b);                   //定位置
                                         LcdWriteCom(0x0f);
                                         Delay1ms(100);
                                         if(K2==0)                //檢測按鍵K2是否按下
                                                {
                                                Delay1ms(10);        //消除抖動(dòng)
                                                if(K2==0)
                                                        {
                                                        second++;
                                                        Delay1ms(100);
                                                        if(second>=60)
                                                        second=0;
                               
                                                        }
                                                }
                                         LcdWriteCom(0x8a);                   //定位置
                                         LcdWriteData('0'+second/10);
                                         LcdWriteData('0'+second%10);
                                         LcdWriteCom(0x8b);
                                         }break;
                                case 1 :
                                        {LcdWriteCom(0x88);                   //定位置
                                         LcdWriteCom(0x0f);
                                         Delay1ms(100);
                                         if(K2==0)                //檢測按鍵K2是否按下
                                                {
                                                Delay1ms(10);        //消除抖動(dòng)
                                                if(K2==0)
                                                        {
                                                        minute++;
                                                        Delay1ms(100);
                                                        if(minute>=60)
                                                        minute=0;
                               
                                                        }
                                                }
                                         LcdWriteCom(0x87);                   //定位置
                                         LcdWriteData('0'+minute/10);
                                         LcdWriteData('0'+minute%10);
                                         LcdWriteCom(0x88);
                                         }break;
                                case 2 :
                                        {LcdWriteCom(0x85);                   //定位置
                                         LcdWriteCom(0x0f);
                                         Delay1ms(100);
                                         if(K2==0)                //檢測按鍵K2是否按下
                                                {
                                                Delay1ms(10);        //消除抖動(dòng)
                                                if(K2==0)
                                                        {
                                                        hour++;
                                                        Delay1ms(100);
                                                        if(hour>=24)
                                                        hour=0;
                               
                                                        }
                                                }
                                         LcdWriteCom(0x84);                   //定位置
                                         LcdWriteData('0'+hour/10);
                                         LcdWriteData('0'+hour%10);
                                         LcdWriteCom(0x85);
                                         }break;
                                }   
                }       
               
                else
                {
                LcdWriteCom(0x0c);         
                if(Time>=20)         //一秒鐘來到改變數(shù)值
                {
                        Time=0;
                        second++;
                        if(second==60)
                        {
                                second=0;
                                minute++;
                                if(minute==60)
                                {
                                        minute=0;
                                        hour++;
                                        if(hour==24)
                                        {
                                                hour=0;       
                                        }
                                }                               
                        }                                       
                }       
            //--顯示時(shí)鐘--//
                LcdWriteCom(0x84);
                LcdWriteData('0'+hour/10);
                LcdWriteData('0'+hour%10);
                LcdWriteData(':');
                LcdWriteData('0'+minute/10);
                LcdWriteData('0'+minute%10);
                LcdWriteData(':');
                LcdWriteData('0'+second/10);
                LcdWriteData('0'+second%10);
                }
        }                               
}
/*******************************************************************************
* 函 數(shù) 名       : Delay1ms()
* 函數(shù)功能                 : 延時(shí)1ms
* 輸    入       : c
* 輸    出       : 無
*******************************************************************************/                  
void Delay1ms(unsigned int c)   //誤差 0us
{
    unsigned char a,b;
        for (; c>0; c--)
        {
                for(b=199;b>0;b--)
                {
                        for(a=1;a>0;a--);
                }
        
        }
   
}
/*******************************************************************************
* 函 數(shù) 名         : TimerConfiguration()
* 函數(shù)功能                   : 配置定時(shí)器值
* 輸    入         : 無
* 輸    出         : 無
*******************************************************************************/                  
void TimerConfiguration()
{
    TMOD = 0x01;         //選擇工作方式1
    TH0 = 0x3C;                 //設(shè)置初始值         50ms
    TL0 = 0xB0;
    EA = 1;                         //打開總中斷
    ET0 = 1;                 //打開定時(shí)器0中斷
    TR0 = 1;                 //啟動(dòng)定時(shí)器0
}
/*******************************************************************************
* 函 數(shù) 名         : Timer0()
* 函數(shù)功能                   : 定時(shí)器0中斷函數(shù)
* 輸    入         : 無
* 輸    出         : 無
*******************************************************************************/                  
void Timer0() interrupt 1
{
        TH0 = 0x3C;         //設(shè)置初始值  50ms
    TL0 = 0xB0;
        Time++;
}
/*******************************************************************************
* 函 數(shù) 名         : Int0Configuration()
* 函數(shù)功能                   : 配置外部中斷0
* 輸    入         : 無
* 輸    出         : 無
*******************************************************************************/                  
void Int0Configuration()
{
        //設(shè)置INT0
        IT0=1;//跳變沿出發(fā)方式(下降沿)
        EX0=1;//打開INT0的中斷允許。
        EA=1;//打開總中斷       
}
/*******************************************************************************
* 函 數(shù) 名         : Int0() interrupt 0
* 函數(shù)功能                   : 外部中斷0的中斷函數(shù)
* 輸    入         : 無
* 輸    出         : 無
*******************************************************************************/                  
void Int0() interrupt 0                 
{
        Delay1ms(10);
        if(K3==0)
        {
                TR0=~TR0;
                SetPlace=0;
        }
}
書上原來的程序,可以實(shí)現(xiàn)1602顯示時(shí)鐘,按K3進(jìn)入時(shí)鐘設(shè)置,按K1選擇設(shè)置的時(shí)分秒,按K2選擇加1。 但是進(jìn)入設(shè)置后,正在設(shè)置的哪一位沒有光標(biāo)提示,不夠人性化。我在原程序的基礎(chǔ)上,加以修改,進(jìn)入設(shè)置功能后,正在設(shè)置哪一位,有了光標(biāo)閃爍提示。

IMG_20170226_103248.jpg (1.24 MB, 下載次數(shù): 129)

IMG_20170226_103248.jpg

IMG_20170226_103248_1.jpg (1.24 MB, 下載次數(shù): 98)

IMG_20170226_103248_1.jpg

IMG_20170226_103248_6.jpg (1.23 MB, 下載次數(shù): 104)

IMG_20170226_103248_6.jpg

IMG_20170226_103255.jpg (1.28 MB, 下載次數(shù): 110)

IMG_20170226_103255.jpg

IMG_20170226_103255_2.jpg (1.3 MB, 下載次數(shù): 132)

IMG_20170226_103255_2.jpg

IMG_20170226_103255_7.jpg (1.28 MB, 下載次數(shù): 96)

IMG_20170226_103255_7.jpg

IMG_20170226_103307.jpg (1.41 MB, 下載次數(shù): 91)

IMG_20170226_103307.jpg

IMG_20170226_103309.jpg (1.4 MB, 下載次數(shù): 111)

IMG_20170226_103309.jpg

秒1.jpg (1.24 MB, 下載次數(shù): 131)

秒1.jpg

秒2.jpg (1.25 MB, 下載次數(shù): 89)

秒2.jpg

秒3.jpg (1.29 MB, 下載次數(shù): 109)

秒3.jpg
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:161933 發(fā)表于 2017-2-26 21:22 | 只看該作者
我把這個(gè) 程序 在實(shí)驗(yàn)板上運(yùn)行了4個(gè)小時(shí),感覺慢了好幾分鐘,請(qǐng)大家看看,誤差產(chǎn)生在哪里?
回復(fù)

使用道具 舉報(bào)

板凳
ID:1 發(fā)表于 2017-2-27 00:27 | 只看該作者
慢了好幾分鐘,可能是由晶振的誤差導(dǎo)致的。你可以在軟件中進(jìn)行補(bǔ)償。樓主 lcd.h 能帖出來一下嗎?
回復(fù)

使用道具 舉報(bào)

地板
ID:161933 發(fā)表于 2017-3-1 18:15 | 只看該作者
admin 發(fā)表于 2017-2-27 00:27
慢了好幾分鐘,可能是由晶振的誤差導(dǎo)致的。你可以在軟件中進(jìn)行補(bǔ)償。樓主 lcd.h 能帖出來一下嗎?

#ifndef __LCD_H_
#define __LCD_H_
/**********************************
當(dāng)使用的是4位數(shù)據(jù)傳輸?shù)臅r(shí)候定義,
使用8位取消這個(gè)定義            
**********************************/
#define LCD1602_4PINS

/**********************************
包含頭文件
**********************************/
#include<reg51.h>

//---重定義關(guān)鍵詞---//
#ifndef uchar
#define uchar unsigned char
#endif

#ifndef uint
#define uint unsigned int
#endif

/**********************************
PIN口定義
**********************************/
#define LCD1602_DATAPINS P0
sbit LCD1602_E=P2^7;
sbit LCD1602_RW=P2^5;
sbit LCD1602_RS=P2^6;

/**********************************
函數(shù)聲明
**********************************/
/*在51單片機(jī)12MHZ時(shí)鐘下的延時(shí)函數(shù)*/
void Lcd1602_Delay1ms(uint c);   //誤差 0us
/*LCD1602寫入8位命令子函數(shù)*/
void LcdWriteCom(uchar com);
/*LCD1602寫入8位數(shù)據(jù)子函數(shù)*/       
void LcdWriteData(uchar dat)        ;
/*LCD1602初始化子程序*/               
void LcdInit();                                                  

#endif
回復(fù)

使用道具 舉報(bào)

5#
ID:3212 發(fā)表于 2017-3-1 20:42 | 只看該作者
admin 發(fā)表于 2017-2-27 00:27
慢了好幾分鐘,可能是由晶振的誤差導(dǎo)致的。你可以在軟件中進(jìn)行補(bǔ)償。樓主 lcd.h 能帖出來一下嗎?

應(yīng)該是你用了國產(chǎn)的1302,再使用了12pF的晶振的關(guān)系。這個(gè)情況我碰到兩次,都是在晶振引腳對(duì)地加一個(gè)小電容解決的。一次加了30p的(那時(shí)候沒有再小得了),另一次加12p的。都能把精度提高到1分鐘/月的級(jí)別。
回復(fù)

使用道具 舉報(bào)

6#
ID:3212 發(fā)表于 2017-3-1 20:43 | 只看該作者
csz9981 發(fā)表于 2017-2-26 21:22
我把這個(gè) 程序 在實(shí)驗(yàn)板上運(yùn)行了4個(gè)小時(shí),感覺慢了好幾分鐘,請(qǐng)大家看看,誤差產(chǎn)生在哪里?

應(yīng)該是你用了國產(chǎn)的1302,再使用了12pF的晶振的關(guān)系。這個(gè)情況我碰到兩次,都是在晶振引腳對(duì)地加一個(gè)小電容解決的。一次加了30p的(那時(shí)候沒有再小得了),另一次加12p的。都能把精度提高到1分鐘/月的級(jí)別。
回復(fù)

使用道具 舉報(bào)

7#
ID:161933 發(fā)表于 2017-3-2 07:37 來自觸屏版 | 只看該作者
學(xué)習(xí)了,
回復(fù)

使用道具 舉報(bào)

8#
ID:99130 發(fā)表于 2017-3-3 13:27 | 只看該作者
在晶振的兩只腳加上30PF左右的電容,對(duì)地。快了則加大電容容量,慢了則減小
回復(fù)

使用道具 舉報(bào)

9#
ID:161933 發(fā)表于 2017-5-18 21:26 | 只看該作者
middfat 發(fā)表于 2017-3-1 20:42
應(yīng)該是你用了國產(chǎn)的1302,再使用了12pF的晶振的關(guān)系。這個(gè)情況我碰到兩次,都是在晶振引腳對(duì)地加一個(gè)小電 ...

我是用的 定時(shí)器0 中斷函數(shù) 實(shí)現(xiàn)計(jì)時(shí)的,50MS一計(jì)數(shù),20計(jì)數(shù)為1秒,我實(shí)驗(yàn)了一下,26分鐘,慢了87秒。平均慢3.34秒/分鐘。

可以通過減少定時(shí)器初值,縮短定時(shí)器,計(jì)數(shù)周期的方法,提高走時(shí)速度吧?大家遇到這種情況,都 是怎樣處理的?

請(qǐng)教了。
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表