用 LCD1602 顯示的秒表
給?STC89C51?安一個(gè)?LCD1602?液晶顯示器。寫一段程序,使得?STC89C51?有計(jì)時(shí)、顯示功能。
當(dāng)給?STC89C51?一個(gè)連續(xù)的高電平時(shí),單片機(jī)開始計(jì)時(shí),同時(shí)在顯示器上顯示計(jì)時(shí)的秒數(shù);
當(dāng)結(jié)束高電平時(shí),計(jì)時(shí)停止,但是顯示器上保留計(jì)時(shí)數(shù)值。
當(dāng)下一個(gè)高電平來到,顯示器接著上次的時(shí)間繼續(xù)計(jì)時(shí)。
簡單的講就是說顯示器顯示幾個(gè)間斷的高電平持續(xù)的時(shí)間之和。
再設(shè)一個(gè)腳實(shí)現(xiàn)清零。
這個(gè)題目,實(shí)際上就是設(shè)計(jì)一個(gè)采用液晶顯示的秒表。
懸賞分:100?|?解決時(shí)間:2011-3-28?09:42?
原題網(wǎng)址:http://zhidao.baidu.com/question/237573382.html
================================================
回答:
LCD1602?和?51單片機(jī)的之間,如果采用常規(guī)接法,共需要?11?條線;
如果不用讀出,RW?就可以直接接地,使?LCD?永遠(yuǎn)處于寫入狀態(tài),這樣的電路如下所示:
如果覺得?LCD1602?占用單片機(jī)的引腳太多,可以只用?6?條引線來實(shí)現(xiàn)對(duì)液晶屏的驅(qū)動(dòng)。
驅(qū)動(dòng)?LCD1602,很簡單,關(guān)鍵是要寫好“寫指令”和“寫數(shù)據(jù)”兩個(gè)函數(shù),其它的設(shè)置、顯示等等,就不難了。
晶振選用?11.0592?/?12MHz,均可。
實(shí)現(xiàn)脈沖長度計(jì)時(shí)、顯示的程序如下:
#include
#include?
#define?uchar?unsigned?char?
#define?uint?unsigned?int
#define?LCD_IO?P2
sbit?LCD_RS?=?P3^0;
sbit?LCD_RW?=?P3^7;
sbit?LCD_EN?=?P3^1;
sbit?sw1?=?P3^2;
sbit?sw2?=?P3^3;
uchar?count;
uint??sec;
uchar?code?LCD_line1[]?=?"Pulse?Continued:";
uchar?code?LCD_line2[]?=?"???????00000?s??";
//---------------------------------------------------
void?delay(uint?z)
{
????uint??x,??y;
????for(x?=?z;?x?>?0;?x--)??for(y?=?10;?y?>?0;?y--);
}
//---------------------------------------------------
void?W_LCD_Com(uchar?com)??????//寫指令
{
????LCD_RS?=?0;????LCD_EN?=?0;?//?LCD_RS和R/W同時(shí)為低電平時(shí),可以寫入指令?????
????LCD_IO?=?com;??delay(5);???//下面用EN輸入一個(gè)高脈沖?
????LCD_EN?=?1;????delay(5);????LCD_EN?=?0;
}
//---------------------------------------------------
void?W_LCD_Dat(uchar?dat)??????//寫數(shù)據(jù)
{
????LCD_RS?=?1;????LCD_EN?=?0;?//?LCD_RS為高,LCD_RW為低時(shí),可以寫入數(shù)據(jù)??
????LCD_IO?=?dat;??delay(5);???//下面用EN輸入一個(gè)高脈沖?
????LCD_EN?=?1;????delay(5);????LCD_EN?=?0;
}
//---------------------------------------------------
void?W_LCD_STR(uchar?*s)???????//寫字符串
{
????while(*s?>?0)??{W_LCD_Dat(*s);??s++;}
}
//---------------------------------------------------
void?init()
{
????W_LCD_Com(0x38);
????W_LCD_Com(0x0c);
????W_LCD_Com(0x06);
????W_LCD_Com(0x01);
????W_LCD_Com(0x80);?W_LCD_STR(LCD_line1);
????W_LCD_Com(0xC0);?W_LCD_STR(LCD_line2);
????TMOD?=?0x01;
????TH0?=?(65536?-?50000)?/?256;
????TL0?=?(65536?-?50000)?%?256;
????TR0?=?1;
????ET0?=?1;
????EX0?=?1;
????EX1?=?1;
????PX1?=?1;
????EA?=?1;
}
//---------------------------------------------------
void?W_LCD_X1_Dat(uint??sec)
{
????W_LCD_Com(0xc0?+?7);
????W_LCD_Dat(0x30?+?sec?/?10000);
????W_LCD_Dat(0x30?+?(sec?%?10000)?/?1000);
????W_LCD_Dat(0x30?+?(sec?%?1000)?/?100);
????W_LCD_Dat(0x30?+?(sec?%?100)?/?10);
????W_LCD_Dat(0x30?+?sec?%?10);
}
//---------------------------------------------------
void?main()
{
????init();
????while(1);
}
//-------------------------------------------
void?timer0()?interrupt?1
{
????TL0?=?(65536-50000)?%?256;
????TH0?=?(65536-50000)?/?256;
????count++;
????if(count?==?20)??{
??????count?=?0;
??????sec++;
??????W_LCD_X1_Dat(sec);???
????}?
}
//-------------------------------------------
void?X0_INT()?interrupt?0
{
????while(sw1?==?0);
}
//-------------------------------------------
void?X1_INT()?interrupt?2
{
????while(sw2?==?0);
????count?=?0;
????sec?=?0;
????W_LCD_X1_Dat(sec);???
}