• 回复
  • 收藏
  • 点赞
  • 分享
  • 发新帖

求助 如何用AT89C51制作数字时钟

请问那位大侠有用AT89C51实现数字时钟的电路和程序,小弟我初入单片机,希望能得到大侠指教,不甚感激!!!
全部回复(2)
正序查看
倒序查看
yu_jsh
LV.2
2
2006-04-19 13:09
#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();                          //键值处理
     }
}
0
回复
yu_jsh
LV.2
3
2006-04-19 13:10
@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
回复