求助 如何用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
回复
提示