說明: 驅(qū)動四位一體數(shù)碼管動態(tài)顯示數(shù)字,可方便的移植到其它程序中。
例如:1、硬件改為三位一體或二位一體數(shù)碼管,只需修改Display_Scan()函數(shù)COM個數(shù)。
2、本例中,采用了共陰數(shù)碼管,如果用在共陽數(shù)碼管,只需修改相應(yīng)段碼表。
本程序使用P0口作為段碼數(shù)據(jù)發(fā)送端,P2.0-P2.3作為數(shù)碼管掃描選通,
使用P0口時,因單片機內(nèi)部沒有上拉電阻,所以要外接上拉電阻(參考阻值470歐姆).
// STC89C52RC
// +---------------+
// | |
// | | Digital Number
// | | _______________________
// | | | __ __ __ __ |
// | P0.0--P0.7|===>| | | | | | | | | |
// | (a,b...g,h)| | |--| |--| |--| |--| | 4位共陰數(shù)碼管
// | | | |__|.|__|.|__|.|__|.|
// | | -----------------------
// | | | | | |
// | | | | | |
// | P2.7(COM3)|--------+ | | |
// | | | | |
// | P2.6(COM2)|-------------+ | |
// | | | |
// | P2.5(COM1)|------------------+ |
// | | |
// | P2.4(COM0)|-----------------------+
// +---------------+
#include
// 函數(shù)聲明
//=======================================================================
void DisplayNumber(unsigned int Num);
void delayms( int ms);
//=======================================================================
unsigned char code LED_table[]={ //使用附帶“51單片機工具箱”可以很容易編碼
0x3f, //"0"
0x06, //"1"
0x5b, //"2" AAAA
0x4f, //"3" F B
0x66, //"4" F B
0x6d, //"5" GGGG
0x7d, //"6" E C
0x07, //"7" E C
0x7f, //"8" DDDD H
0x6f, //"9"
0x00, //black
0x80 //dot
};
#define black 10 // 空白
#define dot 11 // 小數(shù)點
unsigned char DisBuff[4]; //定義顯示緩沖數(shù)組
unsigned char COM;
// 定義通信端口
//===========================================================================
sbit COM0=P2^4;
sbit COM1=P2^5; //對應(yīng)口線由硬件確定
sbit COM2=P2^6;
sbit COM3=P2^7;
//===========================================================================
void Sys_Init()
{
TMOD=0x01; //定時器/計數(shù)器0為定時器方式 16位工作模式
TH0=(65536-1000)/256; //初始時間常數(shù)
TL0=(65536-1000)%6; //1.0ms
ET0=1; //定時器/計數(shù)器0中斷允許
EA=1; //總中斷允許
TR0=1; //啟動定時器/計數(shù)器開始工作
}
void DisplayNumber(unsigned int Num) //顯示程序
{
unsigned char i;
EA=0; //禁止總中斷
for(i=0;i<4;i++)
{
DisBuff[i]=Num; //拆分數(shù)字
Num/=10;
}
for(i=3;i>=0;i--) //循環(huán)4次
{
if (DisBuff[i]==0) DisBuff[i]=black; //消隱無效"0"
else break; //例如將 0123 改成 123,僅顯示有效數(shù)字
}
EA=1; //總中斷允許
}
void Display_Scan() interrupt 1 // 中斷服務(wù)程序,數(shù)碼管選通掃描
{
TR0=0;
TH0=(65536-1000)/256; //高8位和低8位時間常數(shù)
TL0=(65536-1000)%6;
TR0=1; //啟動定時器0
if(COM>3) COM=0;
COM0=COM1=COM2=COM3=1; //將COM0-COM3置1,全暗
switch(COM)
{
case 0: P0=LED_table[DisBuff[0]]; COM0=0; break; //分別選通COM0-COM3 低電平有效
case 1: P0=LED_table[DisBuff[1]]; COM1=0; break;
case 2: P0=LED_table[DisBuff[2]]; COM2=0; break;
case 3: P0=LED_table[DisBuff[3]]; COM3=0; break;
} // 與decp(0x20)位或,恰好點亮小數(shù)點位段
COM++;
}
void delayms(int ms)
{
unsigned int i;
for(;ms>0;ms--) //循環(huán)ms次
{
for(i=0;i<123;i++); // for(i=0;i<123;i++); 每次1ms延遲@ 12.0MHz
} // for(i=0;i<113;i++); 每次1ms延遲@ 11.0592MHz
}
void main()
{
unsigned int i; //定義變量
Sys_Init(); //初始化timer0
while(1) //死循環(huán),單片機必須是死循環(huán)
{
DisplayNumber(i); //調(diào)用數(shù)碼管顯示函數(shù)
delayms(200); //調(diào)用延時函數(shù),使顯示數(shù)字保持一段時間
i++; //這里演示一個數(shù)字累加的程序
//也可以直接寫一個常數(shù)用來顯示,看實際效果
} //例如DisplayNumber(1234); 編譯后將HEX文件
} //下載到學(xué)板里應(yīng)該正常顯示數(shù)字 1234 。
// 另一種段編碼方法
//===========================================================================
//宏定義,數(shù)碼管a-g各段對應(yīng)的比特,更換硬件只用改動以下8行
#define a 0x04 // AAAA
#define b 0x01 // F B
#define c 0x10 // F B
#define d 0x40 // GGGG
#define e 0x80 // E C
#define f 0x02 // E C
#define g 0x08 // DDDD H
#define h 0x20
//用宏定義自動生成段碼表,很好的寫法,值得學(xué)習(xí)
//更換硬件無需重寫段碼表
unsigned char code LED_table[]={
a+b+c+d+e+f, //"0"
b+c, //"1"
a+b+d+e+g, //"2"
a+b+c+d+g, //"3"
b+c+f+g, //"4"
a+c+d+f+g, //"5"
a+c+d+e+f+g, //"6"
a+b+c, //"7"
a+b+c+d+e+f+g, //"8"
a+b+c+d+f+g, //"9"
b+c+e+f+g, //"H"
a+f+e+g, //"C"
d+e+f, //"L"
g, //"-"
0x00 //black
};
#undef a
#undef b
#undef c
#undef d
#undef e
#undef f
#undef g