搜索
bottom↓
回复: 2

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

[复制链接]

出0入0汤圆

发表于 2008-3-8 14:02:31 | 显示全部楼层 |阅读模式
马老师讲得很精彩,以前也做过时钟,但比起马老师的这个,差远了。忍不住发贴,让初学的朋友借鉴。
以下是原理图及程序:
1

/****************************************************
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 uchar  led[] = {0x3F,0x06,0x5b,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; //0—9数字码
const uchar  position[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf}; //动态扫描位置码
uchar time[3]={59,58,23}; //时间
uchar dis_buff[6];  //显示缓存数据
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[dis_buff[posit]];  //显示数值
  if(posit_on&&(posit==2||posit==4))//秒闪烁
      P0 |= 0x80;
  P2 = position[posit]; //动态扫描
  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[j++] = time%10;
           dis_buff[j++] = 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[0]>=60)          //如果到60s清零秒位,进位分位。
         {
            time[0] = 0;
                if(++time[1]>=60)
                {
                  time[1]=0;
                  if(++time[2]>=24)
                  time[2]=0;                                
                 }
         }
          time_to_buffer();  //送至显示缓存区
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2008-3-8 15:23:02 | 显示全部楼层
谢谢LZ的表扬.不过的确在我书中的很多思想方法都可以在51上使用(我以前使用51也是采用这些方法).

出0入0汤圆

发表于 2008-4-1 15:25:48 | 显示全部楼层
顶一个。看过“时间触发与嵌入式系统设计”,编了一个键处理,今天看了马老师的《AVR单片机嵌入式系统原理与应用实践》---font color=FF0000第二篇-font 基本接口单元的应用设计(2),9-11章 (ourdev_cn 我们的电子开发社区).mht,结构清晰,好理解,就顺手改了。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-25 22:57

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表