求助 如何用AT89C51制作數字時鐘
請問那位大俠有用AT89C51實現數字時鐘的電路和程序,小弟我初入單片機,希望能得到大俠指教,不甚感激!!!
全部回復(2)
正序查看
倒序查看
#include //8051 registers
#define Tick 2000 // 2000 x 500us = 1s
#define T500us (256-250) // 500us時間常數(6M)
//0,1,2,3,4,5,6,7,8,9,-,"全滅"
code unsigned char LEDMAP[]=
{ 0x3f, 0x06, 0x5b, 0x4f, 0x66,0x6d,
0x7d, 0x07,0x7f, 0x6f,0x40,0x00}; //八段管顯示碼
unsigned char LED[6]; //LED各個顯示位的值(段碼)
unsigned char Hour,Minute,Second; //顯示的時、分、秒
unsigned int C500us; //500us記數單元
unsigned char Status_dis; //LED顯示狀態.
unsigned int Key_value; //鍵值
unsigned char Key_sum; //鍵值總和
unsigned char BEEP; //蜂鳴標志
signed char Flash_CNT; //閃爍計數器
//延時子程序
void Delay(Length) //延時,ms數量級
unsigned char Length; //延時長度
{
unsigned char i;
for (i=0; i<=Length; i++)
{
i=i;
}
}
//將LED[]的各個元素送出顯示
//閃爍位主要用于修改數據,在某一位被修改時,相應的LED位閃爍
void DisplayLED(Flash)
unsigned char Flash; //LED閃爍位
{
unsigned char i; //LED段碼位計數
unsigned char j; //LED位選
j=0x01;
Flash_CNT++; //閃爍計數加一
//值小于0時,閃爍位熄滅
//值大于0時,閃爍位點亮
for (i=0;i<6;i++)
{
P0=LED[i]; //段碼賦值
P1=~j; //選通位選
if (i==Flash) //閃爍
{ if (Flash_CNT<=0) P1|=j;
if (Flash_CNT>=15) Flash_CNT=-15;
}
Delay(250); //延時,形成視覺暫留
j*=2; //位選左移一位
P1=0xff; //關顯示
}
P1=0xff;
}
void KeyScan(void)
{
unsigned char row; //行列值寄存器
unsigned char column; //行列值寄存器
row=0;
column=0;
P2|=0x7f;
P2&=0x8f; //先掃描列值
column=(~P2)&0x0f; //端口值取反并屏蔽高四位
if (column!=0) DisplayLED(6); //延時12ms消抖
column=(~P2)&0x0f; //重新讀端口值
if (column!=0)
{ BEEP=0x55; //確認有按鍵按下,蜂鳴
P2|=0x7f;
P2&=0xf0; //掃描行值
row=(~P2)&0x70; //取反,屏蔽其他位,右移四位得到行值
Key_value=(row+1)*column; //鍵值=(行值+1)×列值
} //加一避免鍵值重復
if (column==0) BEEP=0; //無鍵按下,解除蜂鳴
}
//鍵值轉換子程序
unsigned char Key_number(unsigned int value)
{ switch(value)
{ case 0x088: return 0;break; //按下"0"
case 0x044: return 1;break; //按下"1"
case 0x022: return 2;break; //按下"2"
case 0x011: return 3;break; //按下"3"
case 0x108: return 4;break; //按下"4"
case 0x084: return 5;break; //按下"5"
case 0x042: return 6;break; //按下"6"
case 0x021: return 7;break; //按下"7"
case 0x208: return 8;break; //按下"8"
case 0x104: return 9;break; //按下"9"
case 0x082: return 10;break; //按下"A"
case 0x041: return 11;break; //按下"B"
default: return 20 ;break;
}
}
//密碼調整子程序
void PWD_Adjust(void)
{
}
//時間調整子程序
void Time_Adjust(void)
{ unsigned char i;
unsigned char number;
number=Key_number(Key_value);
}
//記錄產量子程序
void REC_Start(void)
{
}
//產量記錄清除子程序
void REC_Erase(void)
{
}
//按鍵響應子程序
void KeyAction(void)
{ switch (Key_value)
{ case 0x32A: PWD_Adjust(); break; //修改密碼
case 0x1E6: Time_Adjust(); break; //調整時間
case 0x0A2: REC_Start(); break; //開始記錄產量
case 0x0c3: REC_Erase(); break; //產量記錄清除
default: break;
}
}
void T0Int() interrupt 1 //定時器中斷子程序
{
C500us--;
if (C500us == 0)
{
C500us=Tick; // 500us 記數器為0, 重置記數器
Second++;
if (Second==60) //進位
{ Second=0;
Minute++;
if (Minute==60)
{ Minute=0;
Hour++;
if (Hour==24) Hour=0;
}
}
}
if (BEEP==0) P2&=0x7f; //取消蜂鳴
if (BEEP!=0) P2|=0x80; //開始蜂鳴
}
void main (void) //main program
{
P2&=0x7f;
Hour=0;
Minute=0;
Second=0;
Key_value=0;
BEEP=0;
TMOD=0x02; //方式2,定時器
TH0=T500us;
TL0=T500us;
IE=0x82; //EA=1,IT0=1
C500us=Tick;
TR0=1; //開始定時
Status_dis=0;
Flash_CNT=12;
while (1) // repeat forever
{
if (Status_dis==0)
{
LED[5]=LEDMAP[Hour/10]; //查表顯示小時
LED[4]=LEDMAP[Hour%10]|0x80; //增加小數點
LED[3]=LEDMAP[Minute/10]; //查表顯示分鐘
LED[2]=LEDMAP[Minute%10]|0x80; //增加小數點
LED[1]=LEDMAP[Second/10]; //查表顯示秒
LED[0]=LEDMAP[Second%10];
}
DisplayLED(6); //LED顯示
KeyScan(); //按鍵掃描
KeyAction(); //鍵值處理
}
}
#define Tick 2000 // 2000 x 500us = 1s
#define T500us (256-250) // 500us時間常數(6M)
//0,1,2,3,4,5,6,7,8,9,-,"全滅"
code unsigned char LEDMAP[]=
{ 0x3f, 0x06, 0x5b, 0x4f, 0x66,0x6d,
0x7d, 0x07,0x7f, 0x6f,0x40,0x00}; //八段管顯示碼
unsigned char LED[6]; //LED各個顯示位的值(段碼)
unsigned char Hour,Minute,Second; //顯示的時、分、秒
unsigned int C500us; //500us記數單元
unsigned char Status_dis; //LED顯示狀態.
unsigned int Key_value; //鍵值
unsigned char Key_sum; //鍵值總和
unsigned char BEEP; //蜂鳴標志
signed char Flash_CNT; //閃爍計數器
//延時子程序
void Delay(Length) //延時,ms數量級
unsigned char Length; //延時長度
{
unsigned char i;
for (i=0; i<=Length; i++)
{
i=i;
}
}
//將LED[]的各個元素送出顯示
//閃爍位主要用于修改數據,在某一位被修改時,相應的LED位閃爍
void DisplayLED(Flash)
unsigned char Flash; //LED閃爍位
{
unsigned char i; //LED段碼位計數
unsigned char j; //LED位選
j=0x01;
Flash_CNT++; //閃爍計數加一
//值小于0時,閃爍位熄滅
//值大于0時,閃爍位點亮
for (i=0;i<6;i++)
{
P0=LED[i]; //段碼賦值
P1=~j; //選通位選
if (i==Flash) //閃爍
{ if (Flash_CNT<=0) P1|=j;
if (Flash_CNT>=15) Flash_CNT=-15;
}
Delay(250); //延時,形成視覺暫留
j*=2; //位選左移一位
P1=0xff; //關顯示
}
P1=0xff;
}
void KeyScan(void)
{
unsigned char row; //行列值寄存器
unsigned char column; //行列值寄存器
row=0;
column=0;
P2|=0x7f;
P2&=0x8f; //先掃描列值
column=(~P2)&0x0f; //端口值取反并屏蔽高四位
if (column!=0) DisplayLED(6); //延時12ms消抖
column=(~P2)&0x0f; //重新讀端口值
if (column!=0)
{ BEEP=0x55; //確認有按鍵按下,蜂鳴
P2|=0x7f;
P2&=0xf0; //掃描行值
row=(~P2)&0x70; //取反,屏蔽其他位,右移四位得到行值
Key_value=(row+1)*column; //鍵值=(行值+1)×列值
} //加一避免鍵值重復
if (column==0) BEEP=0; //無鍵按下,解除蜂鳴
}
//鍵值轉換子程序
unsigned char Key_number(unsigned int value)
{ switch(value)
{ case 0x088: return 0;break; //按下"0"
case 0x044: return 1;break; //按下"1"
case 0x022: return 2;break; //按下"2"
case 0x011: return 3;break; //按下"3"
case 0x108: return 4;break; //按下"4"
case 0x084: return 5;break; //按下"5"
case 0x042: return 6;break; //按下"6"
case 0x021: return 7;break; //按下"7"
case 0x208: return 8;break; //按下"8"
case 0x104: return 9;break; //按下"9"
case 0x082: return 10;break; //按下"A"
case 0x041: return 11;break; //按下"B"
default: return 20 ;break;
}
}
//密碼調整子程序
void PWD_Adjust(void)
{
}
//時間調整子程序
void Time_Adjust(void)
{ unsigned char i;
unsigned char number;
number=Key_number(Key_value);
}
//記錄產量子程序
void REC_Start(void)
{
}
//產量記錄清除子程序
void REC_Erase(void)
{
}
//按鍵響應子程序
void KeyAction(void)
{ switch (Key_value)
{ case 0x32A: PWD_Adjust(); break; //修改密碼
case 0x1E6: Time_Adjust(); break; //調整時間
case 0x0A2: REC_Start(); break; //開始記錄產量
case 0x0c3: REC_Erase(); break; //產量記錄清除
default: break;
}
}
void T0Int() interrupt 1 //定時器中斷子程序
{
C500us--;
if (C500us == 0)
{
C500us=Tick; // 500us 記數器為0, 重置記數器
Second++;
if (Second==60) //進位
{ Second=0;
Minute++;
if (Minute==60)
{ Minute=0;
Hour++;
if (Hour==24) Hour=0;
}
}
}
if (BEEP==0) P2&=0x7f; //取消蜂鳴
if (BEEP!=0) P2|=0x80; //開始蜂鳴
}
void main (void) //main program
{
P2&=0x7f;
Hour=0;
Minute=0;
Second=0;
Key_value=0;
BEEP=0;
TMOD=0x02; //方式2,定時器
TH0=T500us;
TL0=T500us;
IE=0x82; //EA=1,IT0=1
C500us=Tick;
TR0=1; //開始定時
Status_dis=0;
Flash_CNT=12;
while (1) // repeat forever
{
if (Status_dis==0)
{
LED[5]=LEDMAP[Hour/10]; //查表顯示小時
LED[4]=LEDMAP[Hour%10]|0x80; //增加小數點
LED[3]=LEDMAP[Minute/10]; //查表顯示分鐘
LED[2]=LEDMAP[Minute%10]|0x80; //增加小數點
LED[1]=LEDMAP[Second/10]; //查表顯示秒
LED[0]=LEDMAP[Second%10];
}
DisplayLED(6); //LED顯示
KeyScan(); //按鍵掃描
KeyAction(); //鍵值處理
}
}
0
回復
@yu_jsh
#include //8051registers#defineTick 2000 //2000x500us=1s#defineT500us(256-250) //500us時間常數(6M)//0,1,2,3,4,5,6,7,8,9,-,"全滅"codeunsignedcharLEDMAP[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d, 0x7d,0x07,0x7f,0x6f,0x40,0x00}; //八段管顯示碼unsignedcharLED[6]; //LED各個顯示位的值(段碼)unsignedcharHour,Minute,Second; //顯示的時、分、秒unsignedint C500us; //500us記數單元unsignedcharStatus_dis; //LED顯示狀態.unsignedint Key_value; //鍵值unsignedcharKey_sum; //鍵值總和unsignedcharBEEP; //蜂鳴標志signed charFlash_CNT; //閃爍計數器//延時子程序voidDelay(Length) //延時,ms數量級unsignedcharLength; //延時長度{ unsignedchari; for(i=0;i
很久很久前寫的,可以正常運行.或許你用的到
0
回復