標題: LCD1602電子時鐘 [打印本頁]
作者: csz9981 時間: 2017-2-26 13:07
標題: LCD1602電子時鐘
/*******************************************************************************
* 實驗名 : 定時器實驗
* 使用的IO :
* 實驗效果 :1602顯示時鐘,按K3進入時鐘設置,按K1選擇設置的時分秒,按K2選擇
*選擇設置加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; //用來計時間的值
unsigned char SetPlace; //設置修改位
/*******************************************************************************
* 函 數 名 : main
* 函數功能 : 主函數
* 輸 入 : 無
* 輸 出 : 無
*******************************************************************************/
void main(void)
{
unsigned char hour=13,minute=14,second=00;
unsigned char H2[]=" I LOVE YOU!!! "; //可以改成任意16個字符。
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); //消除抖動
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); //消除抖動
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); //消除抖動
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); //消除抖動
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) //一秒鐘來到改變數值
{
Time=0;
second++;
if(second==60)
{
second=0;
minute++;
if(minute==60)
{
minute=0;
hour++;
if(hour==24)
{
hour=0;
}
}
}
}
//--顯示時鐘--//
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);
}
}
}
/*******************************************************************************
* 函 數 名 : Delay1ms()
* 函數功能 : 延時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--);
}
}
}
/*******************************************************************************
* 函 數 名 : TimerConfiguration()
* 函數功能 : 配置定時器值
* 輸 入 : 無
* 輸 出 : 無
*******************************************************************************/
void TimerConfiguration()
{
TMOD = 0x01; //選擇工作方式1
TH0 = 0x3C; //設置初始值 50ms
TL0 = 0xB0;
EA = 1; //打開總中斷
ET0 = 1; //打開定時器0中斷
TR0 = 1; //啟動定時器0
}
/*******************************************************************************
* 函 數 名 : Timer0()
* 函數功能 : 定時器0中斷函數
* 輸 入 : 無
* 輸 出 : 無
*******************************************************************************/
void Timer0() interrupt 1
{
TH0 = 0x3C; //設置初始值 50ms
TL0 = 0xB0;
Time++;
}
/*******************************************************************************
* 函 數 名 : Int0Configuration()
* 函數功能 : 配置外部中斷0
* 輸 入 : 無
* 輸 出 : 無
*******************************************************************************/
void Int0Configuration()
{
//設置INT0
IT0=1;//跳變沿出發方式(下降沿)
EX0=1;//打開INT0的中斷允許。
EA=1;//打開總中斷
}
/*******************************************************************************
* 函 數 名 : Int0() interrupt 0
* 函數功能 : 外部中斷0的中斷函數
* 輸 入 : 無
* 輸 出 : 無
*******************************************************************************/
void Int0() interrupt 0
{
Delay1ms(10);
if(K3==0)
{
TR0=~TR0;
SetPlace=0;
}
}
書上原來的程序,可以實現1602顯示時鐘,按K3進入時鐘設置,按K1選擇設置的時分秒,按K2選擇加1。 但是進入設置后,正在設置的哪一位沒有光標提示,不夠人性化。我在原程序的基礎上,加以修改,進入設置功能后,正在設置哪一位,有了光標閃爍提示。
-
IMG_20170226_103248.jpg
(1.24 MB, 下載次數: 129)
下載附件
2017-2-26 13:06 上傳
-
IMG_20170226_103248_1.jpg
(1.24 MB, 下載次數: 98)
下載附件
2017-2-26 13:06 上傳
-
IMG_20170226_103248_6.jpg
(1.23 MB, 下載次數: 104)
下載附件
2017-2-26 13:06 上傳
-
IMG_20170226_103255.jpg
(1.28 MB, 下載次數: 110)
下載附件
2017-2-26 13:06 上傳
-
IMG_20170226_103255_2.jpg
(1.3 MB, 下載次數: 132)
下載附件
2017-2-26 13:06 上傳
-
IMG_20170226_103255_7.jpg
(1.28 MB, 下載次數: 96)
下載附件
2017-2-26 13:06 上傳
-
IMG_20170226_103307.jpg
(1.41 MB, 下載次數: 91)
下載附件
2017-2-26 13:06 上傳
-
IMG_20170226_103309.jpg
(1.4 MB, 下載次數: 111)
下載附件
2017-2-26 13:06 上傳
-
秒1.jpg
(1.24 MB, 下載次數: 131)
下載附件
2017-2-26 13:06 上傳
-
秒2.jpg
(1.25 MB, 下載次數: 89)
下載附件
2017-2-26 13:06 上傳
-
秒3.jpg
(1.29 MB, 下載次數: 109)
下載附件
2017-2-26 13:06 上傳
作者: csz9981 時間: 2017-2-26 21:22
我把這個 程序 在實驗板上運行了4個小時,感覺慢了好幾分鐘,請大家看看,誤差產生在哪里?
作者: admin 時間: 2017-2-27 00:27
慢了好幾分鐘,可能是由晶振的誤差導致的。你可以在軟件中進行補償。樓主 lcd.h 能帖出來一下嗎?
作者: csz9981 時間: 2017-3-1 18:15
#ifndef __LCD_H_
#define __LCD_H_
/**********************************
當使用的是4位數據傳輸的時候定義,
使用8位取消這個定義
**********************************/
#define LCD1602_4PINS
/**********************************
包含頭文件
**********************************/
#include<reg51.h>
//---重定義關鍵詞---//
#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;
/**********************************
函數聲明
**********************************/
/*在51單片機12MHZ時鐘下的延時函數*/
void Lcd1602_Delay1ms(uint c); //誤差 0us
/*LCD1602寫入8位命令子函數*/
void LcdWriteCom(uchar com);
/*LCD1602寫入8位數據子函數*/
void LcdWriteData(uchar dat) ;
/*LCD1602初始化子程序*/
void LcdInit();
#endif
作者: middfat 時間: 2017-3-1 20:42
應該是你用了國產的1302,再使用了12pF的晶振的關系。這個情況我碰到兩次,都是在晶振引腳對地加一個小電容解決的。一次加了30p的(那時候沒有再小得了),另一次加12p的。都能把精度提高到1分鐘/月的級別。
作者: middfat 時間: 2017-3-1 20:43
應該是你用了國產的1302,再使用了12pF的晶振的關系。這個情況我碰到兩次,都是在晶振引腳對地加一個小電容解決的。一次加了30p的(那時候沒有再小得了),另一次加12p的。都能把精度提高到1分鐘/月的級別。
作者: csz9981 時間: 2017-3-2 07:37
學習了,
作者: 越快樂越墮落 時間: 2017-3-3 13:27
在晶振的兩只腳加上30PF左右的電容,對地。快了則加大電容容量,慢了則減小
作者: csz9981 時間: 2017-5-18 21:26
我是用的 定時器0 中斷函數 實現計時的,50MS一計數,20計數為1秒,我實驗了一下,26分鐘,慢了87秒。平均慢3.34秒/分鐘。
可以通過減少定時器初值,縮短定時器,計數周期的方法,提高走時速度吧?大家遇到這種情況,都 是怎樣處理的?
請教了。
歡迎光臨 (http://www.zg4o1577.cn/bbs/) |
Powered by Discuz! X3.1 |
主站蜘蛛池模板:
久久久久国产一级毛片
|
久久激情视频
|
国产精品一二区
|
欧美日韩国产精品一区
|
久久精品二区
|
在线观看国产wwwa级羞羞视频
|
久草成人
|
国产高清一二三区
|
夜夜爽99久久国产综合精品女不卡
|
精品一区二区三区在线播放
|
国产精品不卡视频
|
久久成人精品一区二区三区
|
做a视频
|
天天草av
|
www.中文字幕av
|
久久久久一区
|
岛国在线免费观看
|
欧美一区二区
|
天天澡天天操
|
欧美xxxx在线
|
蜜桃视频在线观看免费视频网站www
|
久久专区|
久久最新精品视频
|
亚洲国产精品久久久久
|
国产东北一级毛片
|
欧美a在线看
|
成人亚洲性情网站www在线观看
|
人人草人人干
|
亚洲视频精品在线
|
精品亚洲一区二区
|
欧美综合国产精品久久丁香
|
91在线电影
|
青青久在线视频
|
一区在线视频
|
久久久久久久久久久久一区二区
|
欧美99|
亚洲天堂av在线
|
91在线观看网址
|
亚洲综合久久精品
|
国产中文字幕在线
|
福利av在线
|