給?STC89C51?安一個?LCD1602?液晶顯示器。寫一段程序,使得?STC89C51?有計時、顯示功能。
當給?STC89C51?一個連續(xù)的高電平時,單片機開始計時,同時在顯示器上顯示計時的秒數;
當結束高電平時,計時停止,但是顯示器上保留計時數值。
當下一個高電平來到,顯示器接著上次的時間繼續(xù)計時。
簡單的講就是說顯示器顯示幾個間斷的高電平持續(xù)的時間之和。
再設一個腳實現清零。
這個題目,實際上就是設計一個采用液晶顯示的秒表。
================================================
回答:
LCD1602?和?51單片機的之間,如果采用常規(guī)接法,共需要?11?條線;
如果不用讀出,RW?就可以直接接地,使?LCD?永遠處于寫入狀態(tài),這樣的電路如下所示:
如果覺得?LCD1602?占用單片機的引腳太多,可以只用?6?條引線來實現對液晶屏的驅動。
------------------------------------
驅動?LCD1602,很簡單,關鍵是要寫好“寫指令”和“寫數據”兩個函數,其它的設置、顯示等等,就不難了。
晶振選用?11.0592?/?12MHz,均可。
實現脈沖長度計時、顯示的程序如下:
#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同時為低電平時,可以寫入指令?????
????LCD_IO?=?com;??delay(5);???//下面用EN輸入一個高脈沖?
????LCD_EN?=?1;????delay(5);????LCD_EN?=?0;
}
//---------------------------------------------------
void?W_LCD_Dat(uchar?dat)??????//寫數據
{
????LCD_RS?=?1;????LCD_EN?=?0;?//?LCD_RS為高,LCD_RW為低時,可以寫入數據??
????LCD_IO?=?dat;??delay(5);???//下面用EN輸入一個高脈沖?
????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);???
}