apcfy 发表于 2008-3-8 14:02:31

用马老师书上的时钟实例移值的C51时钟

马老师讲得很精彩,以前也做过时钟,但比起马老师的这个,差远了。忍不住发贴,让初学的朋友借鉴。
以下是原理图及程序:
1http://cache.amobbs.com/bbs_upload782111/files_9/ourdev_226435.JPG

/****************************************************
File name                : time
Chip type         : AT89C51
Program type             : Application
Clock frequency   : 12.00000MHZ
Memory model      : Small
External SRAM size: 0
DataStack size      : I don't know
****************************************************/

#include <reg51.h>

#define uchar unsigned char
#define uint unsigned int
#define key_state_0   0       //按键状态
#define key_state_1   1
#define key_state_2   2

sbit key_input=P1^0;   // 按键输入
const ucharled[] = {0x3F,0x06,0x5b,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; //0—9数字码
const ucharposition[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf}; //动态扫描位置码
uchar time={59,58,23}; //时间
uchar dis_buff;//显示缓存数据
uchar posit;           //扫描位置
uchar key_stime_counter,time_counter;//时间计数单元
bit posit_on,key_stime_ok,time_1s_ok;//秒闪烁标志,按键扫描标志,1秒标志

void display(void);
uchar key_read(void);
void time_to_buffer(void);
void _time(void);

/*==============display=============*/
void display(void)
{
P2 = 0xff;
P0 = led];//显示数值
if(posit_on&&(posit==2||posit==4))//秒闪烁
      P0 |= 0x80;
P2 = position; //动态扫描
if(++posit>=6)
      posit = 0;
}


/*=============key read============*/
uchar key_read(void)
{
   static uchar key_state = 0;
   uchar key_press,key_return=0;

   key_press = key_input; //输入按键值
       switch(key_state)
       {
              case key_state_0:
                     if(!key_press)
                              key_state = key_state_1; //进入key状态1
                              break;

                  case key_state_1:
                     if(!key_press)
                           {
                              key_state = key_state_2; //进入key状态2
                                  key_return = 1;
                           }
                           else
                              key_state = key_state_0;
                           break;

                  case key_state_2:
                     if(key_press)
                              key_state = key_state_0;
                           break;
       }
       return key_return;           //返回key值
}


/*=============time0 2ms interrupt================*/
void time0() interrupt 1
{
   TH0 = 0xF8;
       TL0 = 0x2F;
   display();
       if(++key_stime_counter>=5)//如果满10MS则将标志位置1
       {       
               key_stime_counter = 0;
               key_stime_ok = 1;
             if(++time_counter>=100)
             {
                   time_counter = 0;
                   time_1s_ok = 1;
               }
   }
}


/*===============give to buffer================*/
void time_to_buffer(void)
{
   uchar i,j=0;
       for(i=0;i<3;i++)
       {
           dis_buff = time%10;
           dis_buff = time/10;
       }
}


/*===============main=============*/
void main(void)
{
   P0 = 0xFF;
       P2 = 0xFF;
       TMOD = 0x01;
       EA = 1;
       ET0 = 1;
       TH0 = 0xF8;
       TL0 = 0x2F;
       posit = 0;
       time_to_buffer();
       TR0 = 1;
   while(1)
       {
              if(time_1s_ok)
                  {
                  _time();
                  time_1s_ok = 0;
                        posit_on = ~posit_on;//秒标志
                       
                  }
                  if(key_stime_ok)
                  {
                     key_stime_ok = 0;
                           if(key_read())
                           {
                          _time();
                           }
                        }
       }
}


/*===============the time=============*/
void _time(void)
{
   if(++time>=60)          //如果到60s清零秒位,进位分位。
       {
          time = 0;
                if(++time>=60)
                {
                  time=0;
                  if(++time>=24)
                  time=0;                                
               }
       }
          time_to_buffer();//送至显示缓存区
}

machao 发表于 2008-3-8 15:23:02

谢谢LZ的表扬.不过的确在我书中的很多思想方法都可以在51上使用(我以前使用51也是采用这些方法).

liqu 发表于 2008-4-1 15:25:48

顶一个。看过“时间触发与嵌入式系统设计”,编了一个键处理,今天看了马老师的《AVR单片机嵌入式系统原理与应用实践》---font color=FF0000第二篇-font 基本接口单元的应用设计(2),9-11章 (ourdev_cn 我们的电子开发社区).mht,结构清晰,好理解,就顺手改了。
页: [1]
查看完整版本: 用马老师书上的时钟实例移值的C51时钟