要求:
用stc89c51,數(shù)碼管土匀,鎖存器實(shí)現(xiàn)秒表功能
實(shí)驗(yàn)仿真圖:
加入兩個(gè)鎖存器使單片機(jī)能夠分時(shí)進(jìn)行位選和段選,這樣做的目的是為了節(jié)省單片機(jī)的端口數(shù)量米苹。P0口控制位選和段選公般,實(shí)現(xiàn)動(dòng)態(tài)數(shù)碼管的顯示,P2口連接了矩陣鍵盤择份,可以進(jìn)行功能的拓展扣孟。
注意,關(guān)于鎖存器和數(shù)碼管無(wú)法正常工作的問題荣赶,在圖1中P0口接了8個(gè)上拉電阻凤价,原因是P0口內(nèi)部沒有上拉電阻或電阻不夠,如果不外接一個(gè)上拉電阻拔创,P0口有可能只能輸出低電平和懸空狀態(tài)利诺,無(wú)法輸出高電平,而實(shí)驗(yàn)中所選用的數(shù)碼管是共陰極的數(shù)碼管剩燥,會(huì)導(dǎo)致數(shù)碼管不能工作慢逾,如果有類似問題出現(xiàn),可嘗試接上上拉電阻灭红。
接有鎖存器的動(dòng)態(tài)數(shù)碼管顯示:
動(dòng)態(tài)顯示電路如圖侣滩,共8個(gè)共陰極數(shù)碼管,采用兩片74LS573進(jìn)行驅(qū)動(dòng)变擒,74LS573與74LS373都是8D鎖存器君珠,只是573引腳排列更易于布線。其引腳功能為:D1-D8為數(shù)據(jù)輸入端娇斑;Q1-Q8為數(shù)據(jù)輸出端策添;LE為數(shù)據(jù)輸入鎖存端材部,LE=1數(shù)據(jù)輸入D鎖存器,LE=0數(shù)據(jù)不能輸入D鎖存器唯竹,即LE下降沿鎖存當(dāng)前輸入數(shù)據(jù)乐导;地址輸出允許端,-OE=0輸出鎖存數(shù)據(jù)摩窃,-OE=1輸出高阻兽叮。
電路中,U1輸出段碼a b c d e f g db猾愿,控制顯示的字形與小數(shù)點(diǎn)鹦聪,U2輸出位選碼,控制第幾個(gè)數(shù)碼管顯示蒂秘。單片機(jī)P1.4泽本、P1.5分別連接到U1、U2的LE姻僧,P1.3連接U1和U2的-OE规丽。根據(jù)硬件電路,動(dòng)態(tài)顯示編程時(shí)撇贺,應(yīng):① P1.3=1赌莺,U1、U2輸出高阻松嘶;② P1.4=1艘狭,P0口輸出段碼,P1.4=0翠订,U1鎖存輸入的段碼巢音;③ P1.5=1,P0口輸出位選碼尽超,P1.5=0官撼,U2鎖存輸入的位選碼;④ P1.3=0似谁,U1傲绣、U2同時(shí)輸出段碼和位選碼,進(jìn)行顯示巩踏,經(jīng)過一段時(shí)間后斜筐,再對(duì)另一個(gè)數(shù)碼管做同樣的操作。
矩陣鍵盤
程序源代碼
#include"reg51.h"
#include"intrins.h"
#define uchar unsigned char
#define uint unsigned int
sbit OE = P1^3;
sbit LE1 = P1^4;
sbit LE2 = P1^5;
data uchar h,m,i,s;
uchar code dis_code[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
uchar code reg[8]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
void show();
void delay(uint t){
uchar i;
while(t--)
for(i=0;i<200;i++);
}
void main(){
while(1){
TMOD=0x01; // 設(shè)置定時(shí)器T0為方式1定時(shí)
TH0=(65536-50000)/256; // 給T0裝入初值
TL0=(65536-50000)%256; // 給T0裝入初值
ET0=1; // 允許T0中斷
TR0=1;
EA=1;
show();
} //CPU開中斷
}
void T0_int(void) interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
i++;
if(i==20) //1s時(shí)間
{ i=0;
s++;
}
if(s==60) //1s時(shí)間
{ s=0;
m++;
}
if(m==60) //1s時(shí)間
{ m=0;
h++;
}
}
void show()
{
uint i;
for(i=0;i<8;i++)
{
OE = 1;
LE2 = 1;
OE = 0;
P0=~reg[i];
LE2 = 0;
OE=1;
LE1 = 1;
OE = 0;
//OE =0;
if(i==2||i==5)
{
P0=0x40;//發(fā)送段碼
delay(4); //間隔一段時(shí)間掃描
}
if(h<10)
{
if(i==7)
{
P0=dis_code[0];//發(fā)送段碼
delay(4); //間隔一段時(shí)間掃描
}
if(i==6)
{
P0=dis_code[h];//發(fā)送段碼
delay(4); //間隔一段時(shí)間掃描
}
}
if(m<10)
{
if(i==4)
{
P0=dis_code[0];//發(fā)送段碼
delay(4); //間隔一段時(shí)間掃描
}
if(i==3)
{
P0=dis_code[m];//發(fā)送段碼
delay(4); //間隔一段時(shí)間掃描
}
}
if(s<10)
{
if(i==1)
{
P0=dis_code[0];//發(fā)送段碼
delay(4); //間隔一段時(shí)間掃描
}
if(i==0)
{
P0=dis_code[s];//發(fā)送段碼
delay(4); //間隔一段時(shí)間掃描
}
}
if(h>=10)
{
if(i==7)
{
P0=dis_code[h/10];//發(fā)送段碼
delay(4); //間隔一段時(shí)間掃描
}
if(i==6)
{
P0=dis_code[h%10];//發(fā)送段碼
delay(4); //間隔一段時(shí)間掃描
}
if(h>=24)h=0;
}
if(m>=10)
{
if(i==4)
{
P0=dis_code[m/10];//發(fā)送段碼
delay(4); //間隔一段時(shí)間掃描
}
if(i==3)
{
P0=dis_code[m%10];//發(fā)送段碼
delay(4); //間隔一段時(shí)間掃描
}
if(m>60)m=1;
}
if(s>=10)
{
if(i==1)
{
P0=dis_code[s/10];//發(fā)送段碼
delay(4); //間隔一段時(shí)間掃描
}
if(i==0)
{
P0=dis_code[s%10];//發(fā)送段碼
delay(4); //間隔一段時(shí)間掃描
}
if(s>60)s=1;
}
// delay(100);
OE=0;
}
}
注意:如果在仿真實(shí)驗(yàn)中數(shù)碼管無(wú)法一起點(diǎn)亮蛀缝,可能是延時(shí)需要改進(jìn),延時(shí)的總數(shù)在300-400之間合適目代,比如本實(shí)驗(yàn)的延時(shí)函數(shù)中是100個(gè)數(shù)屈梁,那么在外層自定義的數(shù)就定在4嗤练,共延時(shí)400個(gè)數(shù),延時(shí)函數(shù)需要根據(jù)實(shí)驗(yàn)的不同進(jìn)行調(diào)整在讶。
程序相對(duì)簡(jiǎn)易煞抬,沒有使用算法,主要思想就是將時(shí)构哺、分革答、秒作為全局變量,在定時(shí)器中計(jì)時(shí)曙强,通過單獨(dú)的顯示函數(shù)來(lái)顯示残拐,主函數(shù)只進(jìn)行中斷開關(guān)和調(diào)用顯示函數(shù),所以代碼相對(duì)易懂碟嘴,需要注意的是溪食,在定時(shí)的過程中,當(dāng)時(shí)間到達(dá)最大時(shí)需要及時(shí)歸零娜扇,比如計(jì)時(shí)到達(dá)60s是要將秒的全局變量歸零错沃,另外,想要做鬧鐘或者定時(shí)器的朋友可以沿用本實(shí)驗(yàn)電路和代碼雀瓢,矩陣鍵盤已連接枢析,只需在代碼加入矩陣鍵盤的操作就能實(shí)現(xiàn)想要的功能。