?? fil12.c
字號(hào):
// 本實(shí)驗(yàn)采用c語(yǔ)言實(shí)現(xiàn)了數(shù)字鐘實(shí)驗(yàn),主要功能包括 用戶設(shè)置時(shí),分
// 考慮到鍵盤(pán)不多以及結(jié)構(gòu)問(wèn)題,本程序并沒(méi)有實(shí)現(xiàn)一些復(fù)雜的功能。
// 采用模塊化設(shè)計(jì),用戶要增加自己的功能也非常方便。
// 參見(jiàn)主程序的模塊組織結(jié)構(gòu)
#include <8051.h>
#define uchar unsigned char
#define uint unsigned int
#define key1 P3_3 //鍵盤(pán)定義
#define key2 P3_4
#define key3 P3_5
#define segdata P0 //數(shù)據(jù) 輸出
#define sege P2_7 //顯示 選中
#define segb P2_6 //位 選
#define segd P2_5 //段 選
uchar flag; //鍵盤(pán)模式,=1增加,=0減少
// 這里定義了一組顯示碼表。前面的code 關(guān)鍵字表示,這組碼表定義
// 在程序存儲(chǔ)器區(qū)域,而不是采用數(shù)據(jù)存儲(chǔ)器來(lái)定義;
// 在一般做這種固定數(shù)組時(shí),都應(yīng)該把他們放置在程序存儲(chǔ)區(qū)。
uchar code disbuf_u[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,
0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,
0x00,0x10,0x08,0x03,0x46,0x21,0x06,0x0e};
uchar led_buf[6]; //段
uchar timead,t_s,t_m,t_h; //基準(zhǔn)時(shí)間,秒,分,時(shí)
void reset(); //上電復(fù)位模塊
void delay(uint ysz);//模糊延時(shí)
void led_buf_flush(void);//緩沖
void disp(void);//顯示
void off_led(void);//關(guān)顯示
void display(unsigned char disseg,unsigned char disdata);//顯示輸出
uchar keyb(); //鍵盤(pán)程序
void settimer();
void main()
{
SP=0x50; //設(shè)置堆棧
reset();
while(1)
{
led_buf_flush();
disp();
off_led();
settimer();
}
}
void reset()
{
TMOD = 0x1; //定時(shí)器T0模式1
TL0 = 0x0cf;//定時(shí)初值
TH0 = 0x3c;
TR0 = 1; //開(kāi)始運(yùn)行
ET0 = 1; //允許定時(shí)器T0中斷
EA = 1; //總的中斷允許
t_m = 0;
t_s = 0;
t_h = 0;
flag = 1; //鍵盤(pán)模式
P3_7 = 0; //關(guān)閉蜂鳴器
P0 = 0; //關(guān)閉數(shù)碼管顯示
P2 = 255;
}
//中斷
void time0() interrupt 1 using 1
{
TR0 = 0;
TL0=0x0cf;
TH0=0x3c;
timead+=1;
if(timead==20) //12M==50ms延時(shí),6M=100ms延時(shí)
{
timead=0;
t_s += 1; //1s到了,把秒單元加1
P1_0=~P1_0; //同時(shí)閃爍p1.0/1兩個(gè)燈
P1_1=~P1_1;
if(t_s==60) //一些進(jìn)位的判斷
{
t_s = 0,t_m ++;
if(t_m ==60)
t_m =0,t_h ++;
if(t_h == 24)
t_h = 0;
}
}
TR0 = 1; //開(kāi)始計(jì)數(shù),由于前面一些函數(shù)也需要占用時(shí)間
//因此,需要在定時(shí)初值中減去這段時(shí)間的延時(shí)常數(shù)
}
//延時(shí)
void delay(uint ysz)
{
while(ysz--){};
}
//設(shè)置時(shí)間
void settimer()
{
switch(keyb())
{
case 3:{
if(flag)
{if(t_h != 23) t_h ++;} //設(shè)置時(shí)
else
{if(t_h !=0 ) t_h --;}
break;}
case 2:{if(flag)
{if(t_m != 59) t_m ++;} //設(shè)置分
else
{if(t_m !=0 ) t_m --;}
break;}
case 1:{if(flag) flag = 0; //設(shè)置模式切換
else flag = 1;
break;}
}
}
//顯示緩沖區(qū)
void led_buf_flush(void)
{
led_buf[0]=t_s%10;
led_buf[1]=t_s/10;
led_buf[2]=t_m%10;
led_buf[3]=t_m/10;
led_buf[4]=t_h%10;
led_buf[5]=t_h/10;
}
//顯示刷新子程序
void disp()
{
uchar i;
for(i=0;i<6;i++)
{
display(i,led_buf[i]); //調(diào)用輸出顯示
}
}
//顯示
//這里是顯示子程序,入口參數(shù)為
// disseg -> 位選 可選范圍 0-7 一共8個(gè)數(shù)碼管
// disdata -> 段選 可選范圍 0-31 一個(gè)32個(gè)字符
// 段選 0-15 16個(gè)字符 為 "0"->"F"
// 段選 16-31 16個(gè)字符 為 "0."->"F."
void display(unsigned char disseg,unsigned char disdata)
{
unsigned char dataf;
dataf = 1;
while(disseg)
{
dataf <<= 1;
disseg--;
}
sege = 0;
segdata = dataf; //這里首先把要顯示的數(shù)據(jù)放到數(shù)據(jù)總線
segb = 1; //這里給出一個(gè)脈沖,數(shù)據(jù)送往位選端
segb = 0;
segdata = disbuf_u[disdata];
segd = 1; //這里給出一個(gè)脈沖,數(shù)據(jù)送往段選端
segd = 0;
delay(50);
}
//關(guān)顯示
void off_led(void)
{
segdata = 255;
segd = 1; //這里給出一個(gè)脈沖,數(shù)據(jù)送往段選端
segd = 0;
}
uchar keyb()
{
uchar key,keytmp;
key1 = 1; //將輸出線拉高
key2 = 1;
key3 = 1;
key = P3 ; //讀回來(lái)
key = key & 0x38; //獲得鍵盤(pán)結(jié)果
if(key == 56 ) return 0; //如果用戶沒(méi)有按鍵返回 0
else
{
keytmp = key;
delay(1000); //判斷是不是干擾
key = P3;
key = key & 0x38;
if (key != keytmp ) return 0; //是干擾,返回 0
else //不是干擾,等待用戶釋放按鍵
{
do{
key1 = 1; //輸出拉高
key2 = 1;
key3 = 1;
key = P3 & 0x38; //讀回來(lái)
}while(key != 56 ); //等待用戶釋放
P1_2 = 1; //用戶釋放以后,清除p1.0指示燈
switch(keytmp)
{
case 24: return 3;//返回用戶按鍵結(jié)果
case 40: return 2;
case 48: return 1;
}
}
}
return 0;
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -