|
/* Main.c file generated by New Project wizard
*
* Created: 周六 1月 7 2023
* Processor: AT89C52
* Compiler: Keil for 8051
*/
#include <reg52.h>
sbit P0_4=0x84; //P0.4位地址84H
sbit P0_5=0x85; //P0.5位地址85H
/****************************************
* 大量宏定義,便于代碼移植和閱讀 *
*****************************************/
#define HIGH 1 //定義HIGH為高電平
#define LOW 0 //定義LOW為低電平
#define LS164_DATA(x) {if((x))P0_4=1;else P0_4=0;}
#define LS164_CLK(x) {if((x))P0_5=1;else P0_5=0;}
#define SEG_PORT P0 //控制數(shù)碼管字型碼端口
unsigned char Timer0lRQEvent=0; //T/CO 中斷事件
unsigned char TimelSecEvent=0; //定時 1 秒事件
unsigned int TimeCount=0; //時間計數(shù)值
unsigned char SegCurPosition=0; //當(dāng)前點(diǎn)亮的數(shù)碼管
//為了驗證共陽極的字型碼是共陰極的反碼,共陽極字型碼為共陰極的反碼
//共陽極字型碼存儲在代碼區(qū),用關(guān)鍵字“code”聲明
code unsigned char SegCode[10]={~0x3F,~0x06,~0x5B,~0x4F,~0x66,~0x6D,~0x7D, ~0x07,~0x7F,~0x6F};
//片選數(shù)碼管數(shù)組,存儲在代碼區(qū),用關(guān)鍵字"code"聲明
code unsigned char SegPosition[4]={0xf7,0xfb,0xfd,0xfe};
//數(shù)碼管顯示數(shù)據(jù)緩沖區(qū)
unsigned char SegBuf [4] ={0};
/**********************************************
*函數(shù)名稱:LS164Send
*輸 入:無
*輸 出:無
*功 能:74LS164發(fā)送單個字節(jié)
**********************************************/
void LS164Send(unsigned char byte)
{
unsigned char j ;
for (j=0;j<=7;j++) //對輸入數(shù)據(jù)進(jìn)行移位檢測
{
if(byte&(1<<(7-j))) //檢測字節(jié)當(dāng)前位
{
LS164_DATA(HIGH); //串行數(shù)據(jù)輸入引腳為高電平
}
else
{
LS164_DATA(LOW); //串行數(shù)據(jù)輸入引腳為低電平
}
LS164_CLK(LOW); //同步時鐘輸入端以一個上升沿結(jié)束確定該位的值
LS164_CLK(HIGH);
}
}
/**********************************************
*函數(shù)名稱:SegRef reshDisplayBuf
*輸 入:無
*輸 出:無
*功 能:數(shù)碼管刷新顯示緩存
**********************************************/
void SegRefreshDisplayBuf(void)
{
SegBuf[0]=TimeCount%10; //個位
SegBuf[1]=TimeCount/10%10; //十位
SegBuf[2]=TimeCount/100%10; //百位
SegBuf[3]=TimeCount/1000%10; //千位
}
/***********************************************
*函數(shù)名稱:SegDisplay
*輸 入:無
*輸 出:無
*功 能:數(shù)碼管顯示數(shù)據(jù)
***********************************************/
void SegDisplay(void)
{
unsigned char t;
SEG_PORT=0x0F; //熄滅所有數(shù)碼管
t=SegCode[SegBuf[ SegCurPosition]]; //確定當(dāng)前的字型碼
LS164Send(t);
SEG_PORT=SegPosition[SegCurPosition]; //選中一個數(shù)碼管來系顯示
if(++SegCurPosition>=4) //下次要點(diǎn)亮的數(shù)碼管
{
SegCurPosition=0;
}
}
/***********************************************
*函數(shù)名稱:TimerInit
*輸 入:無
*輸 出:無
*功 能:T/C初始化
***********************************************/
void TimerInit(void)
{
TH0=(65536-5000)/256;
TL0=(65536-5000)%256; //定時5ms
TMOD=0x01; //T/C0 模式1
}
/***********************************************
函數(shù)名稱:Timer0Start
*輸 入:無
*輸 出:無
*功 能:T/C0啟動
***********************************************/
void Timer0Start(void)
{
TR0=1;
ET0=1;
}
/***********************************************
*函數(shù)名稱:PortInit
*輸 入:無
*輸 出:無
*功 能:I/O口初始化
***********************************************/
void PortInit(void)
{
P0=P1=P2=P3=0xFF;
}
/***********************************************
*函數(shù)名稱:main
*輸 入:無
*輸 出:無
*功 能:函數(shù)主體
***********************************************/
void main(void)
{
PortInit();
TimerInit();
Timer0Start();
SegRefreshDisplayBuf();
EA=1;
while(1)
{
if(Timer0lRQEvent) //檢測定時中斷事件是否產(chǎn)生
{
Timer0lRQEvent=0;
if(TimelSecEvent) //檢測1秒事件是否產(chǎn)生
{
TimelSecEvent=0;
if(++TimeCount>=9999) //計數(shù)值自加
{
TimeCount=0;
}
SegRefreshDisplayBuf( ); //刷新緩沖區(qū)
}
SegDisplay( ); //點(diǎn)亮選中的數(shù)碼管
}
}
}
/***********************************************
*函數(shù)名稱:Timer0IRQ
*輸 入:無
*輸 出:無
*功 能:T/CO中斷服務(wù)函數(shù)
***********************************************/
void Timer0IRQ(void) interrupt 1
{
static unsigned int cnt=0;
TH0=(65536-5000)/256;
TL0=(65536-5000)%256; //重載初值
Timer0lRQEvent=1;
if(++cnt>=200)
{
cnt=0;
TimelSecEvent=1;
}
}
|
|