這個是嚴格按照老師考試要求實作的,自動化的學弟學妹留着積福啊。。。哈哈
圖檔什麼的統統掠過,資源裡可下載下傳。。
代碼:
《source.c》
#include"reg52.h"
#include"dis.h"
#define uint unsigned int
#define uchar unsigned char
uint code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //0~9編碼
void delay(uint xms); //延時函數,約XMS毫秒
void timer0_init(); //定時器、序列槽、數位管端口初始化
void display(uint h,uint m,uint s); //顯示函數
void display1(uint year,uint month,uint day); //顯示函數
uint keyscan(); //鍵盤掃描
uint wait=5; //延時時間
/
void timer0_init()
{
display_init(); //顯示函數初始化
PCON |= 0x80; //SMOD=1,波特率加倍
TMOD=0x21; //設定定時器0工作方式為1(0000 0001);序列槽工作:定時器1工作方式2(0010 0000)
TH0=(65535-50000)/256; //裝定時器初值,定時50ms後發生中斷
TL0=(65535-50000)%256;
TH1=0xf3; //定時時間243μs
TL1=0xf3; //波特率4800
TR0=1; //啟動定時器0
TR1=1; //啟動定時器1
ET0=1; //開定時器0中斷
SM0=0; //8位UART波特率可變(T1溢出率/N)方式1
SM1=1;
PS=1; //序列槽中斷高優先級
REN=1; //允許序列槽接收
EA=1; //開總中斷
ES=1; //開序列槽中斷
}
/
void delay(uint xms)
{
uint i,j;
for(i=0;i<30;i++)
for(j=xms;j>0;j--)
;
}
/
void display(uint h,uint m,uint s)
{
P0=table[h/10];
P1=0xfe;
delay(wait);
P1=0xff;
P0=table[h%10];
P1=0xfd;
delay(wait);
P1=0xff;
//
//
P0=0x40;
P1=0xfb;
delay(wait);
P1=0xff;
//
//
P0=table[m/10];
P1=0xf7;
delay(wait);
P1=0xff;
P0=table[m%10];
P1=0xef;
delay(wait);
P1=0xff;
///
///
P0=0x40;
P1=0xdf;
delay(wait);
P1=0xff;
//
//
P0=table[s/10];
P1=0xbf;
delay(wait);
P1=0xff;
P0=table[s%10];
P1=0x7f;
delay(wait);
P1=0xff;
//
//
}
/
void display1(uint year,uint month,uint day)
{
P0=table[year/1000];
P1=0xfe;
delay(wait);
P1=0xff;
P0=table[year%1000/100];
P1=0xfd;
delay(wait);
P1=0xff;
P0=table[year%100/10];
P1=0xfb;
delay(wait);
P1=0xff;
P0=table[year%10];
P1=0xf7;
delay(wait);
P1=0xff;
//
//
P0=table[month/10];
P1=0xef;
delay(wait);
P1=0xff;
P0=table[month%10];
P1=0xdf;
delay(wait);
P1=0xff;
//
//
P0=table[day/10];
P1=0xbf;
delay(wait);
P1=0xff;
P0=table[day%10];
P1=0x7f;
delay(wait);
P1=0xff;
}
/
uint keyscan()
{
uint temp,key=250; //定義變量temp,key;
P2=0xfe; //先置P2.0電位為0;
temp=P2; //P2狀态賦予temp;
temp=temp&0xf0; //temp與0xf0做與運算,供下句判斷高4位是否有按鍵被按下;
if(temp!=0xf0)
{
delay(50); //延時約30ms消抖;
temp=P2; //再次讀取P2口的值,再作判斷,确定并非抖動,而是被按下;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P2; //重新讀取P2口的置賦予temp,判斷P2口哪兩個口電平為0;
switch(temp)
{
case 0xee:
key=15;break;
case 0xde:
key=14;break;
case 0xbe:
key=13;break;
case 0x7e:
key=12;break;
}
while(temp!=0xf0) //等待按鍵釋放,若按鍵沒有釋放,while條一直成立,程式停于此處;
{
temp=P2; //不斷讀取P2口狀态賦予temp,以供判斷按鍵是否放開;
temp=0xf0&temp;
}
}
}
P2=0xfd;
temp=P2;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(50);
temp=P2;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P2;
switch(temp)
{
case 0xed:
key=11;break;
case 0xdd:
key=10;break;
case 0xbd:
key=9;break;
case 0x7d:
key=8;break;
}
while(temp!=0xf0)
{
temp=P2;
temp=0xf0&temp;
}
}
}
P2=0xfb;
temp=P2;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(50);
temp=P2;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P2;
switch(temp)
{
case 0xeb:
key=7;break;
case 0xdb:
key=6;break;
case 0xbb:
key=5;break;
case 0x7b:
key=4;break;
}
while(temp!=0xf0)
{
temp=P2;
temp=0xf0&temp;
}
}
}
P2=0xf7;
temp=P2;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(50);
temp=P2;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P2;
switch(temp)
{
case 0xe7:
key=3;break;
case 0xd7:
key=2;break;
case 0xb7:
key=1;break;
case 0x77:
key=0;break;
}
while(temp!=0xf0)
{
temp=P2;
temp=0xf0&temp;
}
}
}
return key;
}
<clock.c>
#include"reg52.h" //調用官方頭檔案,包含相關端口定義
#include"source.h" //調用自制頭檔案,包含相關功能函數
void get_uart_deal(); //處理序列槽接收到的資料
void getkey_deal(); //記錄鍵盤輸入并處理
uint buf1[6]={0}; //記錄時間時分秒
uint buf2[8]={0}; //記錄時間年月日
uchar uart[9]="000000000"; //記錄序列槽接收到的字元串
uint uart_deal[8]={0}; //存放處理後的序列槽字元資料
uint adjust=0,x=10,show=1; //調整時間标志、記錄按鍵标志、選擇顯示标志
uint hx=0,mx=0,sx=0,days=1,months=5,years=2013,t=0; //時分秒 年月日 進入中斷标志次數
uint num1=0,num2=0; //鍵盤接收相關變量
uint num=0,i=0,temp1,temp2,flag; //序列槽修改相關變量
uchar tab[]="-----我收到了 "; //序列槽顯示字元
/
void main()
{
timer0_init();
while(1)
{
getkey_deal();
}
}
/
void get_uart_deal()
{
if(num==9)
{
ES=0;
for(i=1;i<9;i++)
{
uart_deal[i]=uart[i]-48;
}
if(uart[0]==115) //修改時分秒
{
hx=uart_deal[1]*10+uart_deal[2];
if(hx>=24)
hx=0;
mx=uart_deal[4]*10+uart_deal[5];
if(mx>=60)
mx=0;
sx=uart_deal[7]*10+uart_deal[8];
if(sx>=60)
sx=0;
}
if(uart[0]==110) //修改年月日
{
years=uart_deal[1]*1000+uart_deal[2]*100+uart_deal[3]*10+uart_deal[4];
months=uart_deal[5]*10+uart_deal[6];
if(months>=13)
months=1;
days=uart_deal[7]*10+uart_deal[8];
if((years % 400 == 0)||(years % 4 == 0)&&(years % 100 != 0)) //二月29天(閏年)
{
if(months==2)
{
if(days>=30)
days=1;
}
}
else //二月28天(平年)
{
if(months==2)
{
if(days>=29)
days=1;
}
}
if(months==4||months==6||months==9||months==11) //小月份30天
{
if(days>=31)
days=1;
}
else //大月份31天
{
if(days>=32)
days=1;
}
}
for(i=0;i<14;i++)
{
SBUF=tab[i];
while(!TI);
TI=0;
}
for(i=0;i<9;i++)
{
SBUF=uart[i];
while(!TI);
TI=0;
}
ES=1;
num=0;
}
}
/
void getkey_deal()
{
get_uart_deal();
x=keyscan();
if(x==10)
{
ET0=0;
adjust++; //改年月日或時分秒标志位
if(adjust==3)
{
adjust=0;
ET0=1;
}
}
改時分秒标志位//
if(adjust==1)
{
if(x!=250&&x<10)
{
buf1[num1]=x;
num1++;
if(num1==6)
{
num1=0;
hx=buf1[0]*10+buf1[1];
if(hx>=24)
hx=0;
mx=buf1[2]*10+buf1[3];
if(mx>=60)
mx=0;
sx=buf1[4]*10+buf1[5];
if(sx>=60)
sx=0;
}
}
}
改年月日标志位//
if(adjust==2)
{
if(x!=250&&x<10)
{
buf2[num2]=x;
num2++;
if(num2==8)
{
num2=0;
years=buf2[0]*1000+buf2[1]*100+buf2[2]*10+buf2[3];
months=buf2[4]*10+buf2[5];
if(months>=13)
months=1;
days=buf2[6]*10+buf2[7];
if((years % 400 == 0)||(years % 4 == 0)&&(years % 100 != 0)) //二月29天(閏年)
{
if(months==2)
{
if(days>=30)
days=1;
}
}
else //二月28天(平年)
{
if(months==2)
{
if(days>=29)
days=1;
}
}
if(months==4||months==6||months==9||months==11) //小月份30天
{
if(days>=31)
days=1;
}
else //大月份31天
{
if(days>=32)
days=1;
}
}
}
}
選擇顯示函數/
if(x==15)
{
show++;
if(show==3)
show=1;
}
if(show==1)
display(hx,mx,sx);
if(show==2)
display1(years,months,days);
}
/
void timer0() interrupt 1
{
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
t++;
if(t==20)
{
t=0;
sx++;
if(sx==60)
{
sx=0;
mx++;
if(mx==60)
{
mx=0;
hx++;
if(hx==24)
{
hx=0;
days++;
if((years % 400 == 0)||(years % 4 == 0)&&(years % 100 != 0)) //二月29天(閏年)
{
if(months==2)
{
if(days>29)
{
days=1;
months++;
}
}
}
else //二月28天(平年)
{
if(months==2)
{
if(days>28)
{
days=1;
months++;
}
}
}
if(months==4||months==6||months==9||months==11) //小月份30天
{
if(days>30)
{
days=1;
months++;
}
}
else //大月份31天
{
if(days>31)
{
days=1;
months++;
}
}
if(months>12)
{
months=1;
years++;
}
}
}
}
}
}
/
void uart_isr() interrupt 4
{
if(RI==1)
{
RI=0;
uart[num]=SBUF;
num++;
}
}
<dis.c>
#include"reg52.h" //調用官方頭檔案,包含相關端口定義
#define N 7 //宏定義N,基本循環次數
#define M 50 //宏定義M,延時用
#define W 10 //宏定義W,基本循環次數
void display_init(); //顯示函數初始化
void dis0(); //顯示函數0
void dis1(); //顯示函數1
void dis2(); //顯示函數2
void dis3(); //顯示函數3
void dis4(); //顯示函數4
void dis5(); //顯示函數5
void dis6(); //顯示函數6
void dis7(); //顯示函數7
void dis8(); //顯示函數8
void delayms(int ms); //延時函數ms
char code tabx[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //0~9編碼
char code table1[]={0x39,0x3f,0xf3,0xee}; //編碼
int waits=5,ix=0,jx=0; //延時時間參數
void display_init()
{
P1=0xff; //初始化數位管顯示端口
P0=0x00; //初始化數位管顯示端口
for(ix=0;ix<8;ix++)
for(jx=15;jx>0;jx--)
{
dis0();
}
for(ix=0;ix<N;ix++)
for(jx=W;jx>0;jx--)
{
dis1();
}
for(ix=0;ix<N;ix++)
for(jx=W;jx>0;jx--)
{
dis2();
}
for(ix=0;ix<N;ix++)
for(jx=W;jx>0;jx--)
{
dis3();
}
for(ix=0;ix<N-1;ix++)
for(jx=W;jx>0;jx--)
{
dis4();
}
for(ix=0;ix<N-2;ix++)
for(jx=W;jx>0;jx--)
{
dis5();
}
for(ix=0;ix<N-3;ix++)
for(jx=W;jx>0;jx--)
{
dis6();
}
for(ix=0;ix<N-4;ix++)
for(jx=W;jx>0;jx--)
{
dis7();
}
for(ix=0;ix<N;ix++)
for(jx=14;jx>0;jx--)
{
dis8();
}
}
void dis0()
{
P0=table1[0];
P1=0xfe;
delayms(waits);
P1=0xff;
P0=table1[1];
P1=0xfd;
delayms(waits);
P1=0xff;
P0=table1[2];
P1=0xfb;
delayms(waits);
P1=0xff;
P0=table1[3];
P1=0xf7;
delayms(waits);
P1=0xff;
//
//
P0=tabx[7];
P1=0xdf;
delayms(waits);
P1=0xff;
//
//
P0=tabx[4];
P1=0xbf;
delayms(waits);
P1=0xff;
P0=tabx[8];
P1=0x7f;
delayms(waits);
P1=0xff;
}
void dis1()
{
P0=tabx[1];
P1=0xfe;
delayms(waits);
P1=0xff;
}
void dis2()
{
P0=tabx[1];
P1=0xfe;
delayms(waits);
P1=0xff;
P0=tabx[0];
P1=0xfd;
delayms(waits);
P1=0xff;
}
void dis3()
{
P0=tabx[1];
P1=0xfe;
delayms(waits);
P1=0xff;
P0=tabx[0];
P1=0xfd;
delayms(waits);
P1=0xff;
P0=tabx[0];
P1=0xfb;
delayms(waits);
P1=0xff;
}
void dis4()
{
P0=tabx[1];
P1=0xfe;
delayms(waits);
P1=0xff;
P0=tabx[0];
P1=0xfd;
delayms(waits);
P1=0xff;
P0=tabx[0];
P1=0xfb;
delayms(waits);
P1=0xff;
P0=tabx[4];
P1=0xf7;
delayms(waits);
P1=0xff;
}
void dis5()
{
P0=tabx[1];
P1=0xfe;
delayms(waits);
P1=0xff;
P0=tabx[0];
P1=0xfd;
delayms(waits);
P1=0xff;
P0=tabx[0];
P1=0xfb;
delayms(waits);
P1=0xff;
P0=tabx[4];
P1=0xf7;
delayms(waits);
P1=0xff;
//
//
P0=tabx[4];
P1=0xef;
delayms(waits);
P1=0xff;
}
void dis6()
{
P0=tabx[1];
P1=0xfe;
delayms(waits);
P1=0xff;
P0=tabx[0];
P1=0xfd;
delayms(waits);
P1=0xff;
P0=tabx[0];
P1=0xfb;
delayms(waits);
P1=0xff;
P0=tabx[4];
P1=0xf7;
delayms(waits);
P1=0xff;
//
//
P0=tabx[4];
P1=0xef;
delayms(waits);
P1=0xff;
P0=tabx[3];
P1=0xdf;
delayms(waits);
P1=0xff;
}
void dis7()
{
P0=tabx[1];
P1=0xfe;
delayms(waits);
P1=0xff;
P0=tabx[0];
P1=0xfd;
delayms(waits);
P1=0xff;
P0=tabx[0];
P1=0xfb;
delayms(waits);
P1=0xff;
P0=tabx[4];
P1=0xf7;
delayms(waits);
P1=0xff;
//
//
P0=tabx[4];
P1=0xef;
delayms(waits);
P1=0xff;
P0=tabx[3];
P1=0xdf;
delayms(waits);
P1=0xff;
//
//
P0=tabx[0];
P1=0xbf;
delayms(waits);
P1=0xff;
}
void dis8()
{
P0=tabx[1];
P1=0xfe;
delayms(waits);
P1=0xff;
P0=tabx[0];
P1=0xfd;
delayms(waits);
P1=0xff;
P0=tabx[0];
P1=0xfb;
delayms(waits);
P1=0xff;
P0=tabx[4];
P1=0xf7;
delayms(waits);
P1=0xff;
//
//
P0=tabx[4];
P1=0xef;
delayms(waits);
P1=0xff;
P0=tabx[3];
P1=0xdf;
delayms(waits);
P1=0xff;
//
//
P0=tabx[0];
P1=0xbf;
delayms(waits);
P1=0xff;
P0=tabx[7];
P1=0x7f;
delayms(waits);
P1=0xff;
}
void delayms(int ms)
{
int tx,kx;
for(tx=ms;tx>0;tx--)
for(kx=M;kx>0;kx--)
;
}