单片机驱动的发光二极管做的数码管时钟

发布者:ArtisticSoul最新更新时间:2017-09-02 来源: elecfans关键字:单片机驱动  发光二极管  数码管时钟 手机看文章 扫描二维码
随时随地手机看文章

我是电子制作爱好者,最近从网上看到这款单片机驱动的发光二极管做的数码管时钟,作者:whw8099,以下是作者的介绍“以前做的数码管时钟,总觉得太小了,远处看不清,就用发光二极管自己制作了一个数码管,这样就亮多了。技术的含量不是很高,但是费功夫,单片机程序是在书上看到的,作了一些小修改。硬件中没有用DS1302,单片机晶振用12M(程序以12M晶振进行计算的),走时比用DS1302还要准。”特此收集转载。

   点击图片或使用键盘← →翻页

 点击图片或使用键盘← →翻页

接口:
数码管:P0^0~P0^7
位选:   P2^0~P2^3
设置键   P1^5~P1^7(短按:设置显示时间,长按:设置闹钟时间)
加1键    P1^6
减1键    P1^7
Beep     P3^7

//作者:whw8099
#include
#include
#define uchar unsigned char
#define uint  unsigned int

#define  KSET       0x60  //设置当前时间键
#define  KSET_LONG  0x61    //设置闹铃时间键
#define  KINC       0x50  //加1键
#define  KDEC       0x30     //减1键

sbit     SPK=P3^7;   //蜂鸣器控制引脚

uchar code MAX[2]={24,60};  //时、分的最大值
uchar code segtab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0x89,0x8c,0xff};
uchar dbuf[4]={0,0,0,0}; //4位显示缓存
uint  count;      //用于累加定时器T0的溢出中断次数,取值为0到4000

uchar time[3]={0,0,0}; //当前时、分、秒  
uchar ala[2]={0,0};    //报警时、分
uchar  state;          //state=0:正常走时方式;
                           //state=1:设置方式;
                           //state=2:正在闹铃
        
bit  update;             //时间更改标志                   
uchar flash=00;         //闪烁控制字
uchar disp_on=0xf0;     //显示控制位

void delay(void)
{ uchar i;
  for(i=0;i<200;i++);
}

void hexbcd(uchar *tp)
{   dbuf[3]=tp[0]/10;   //将时拆分为BCD码送显示缓存
    dbuf[2]=tp[0]|0x80; 
    dbuf[1]=tp[1]/10;   //将分拆分为BCD码送显示缓存
    dbuf[0]=tp[1];
}
void disp(void)
 { static uchar  cn=0;
   uchar n,bsel;
   bsel=0xfe;                    //最初点亮最低位
   for(n=0;n<4;n++)
    { P2=bsel|disp_on;         //位选口
      P0=segtab[dbuf[n]&0x7f];//显示缓冲单元的数据查出字段码表
      if((dbuf[n]&0x80)!=0)
         P0=P0&0x7f;
      bsel=_crol_(bsel,1);    //准备显示下一位
      delay();                  //每位显示约1毫秒
      P0=0xff;           //熄灭数码管,防止当前位在下一位置显示出来
    }
    cn++;       //每显示一遍,cn加1
    if(cn==200)
      { disp_on=disp_on^flash;
        dbuf[2]=dbuf[2]^0x80;
        cn=0;
      }
 }

void  time0(void) interrupt 1  using 1
{ static uint  n=0,m=0;
  count++;                          //中断次数加1
  if(count==4000)         //满1s
    { count=0;          //count清0
   time[2]++;          //秒加1
      if(time[2]==60)        //满60秒
        { time[2]=0;            //秒清0
          time[1]++;         //分加1
          if(state!=1) update=1; //更新标志
          if(time[1]==60)    //满60分
            { time[1]=0;        //分清0
              time[0]++;        //时加1
              if(time[0]==24)   //满24小时
                   time[0]=0; //时清0
            }
        }
      if((state==0)&&(time[2]==0))//当前为走时状态且刚满1分(60秒)
        { if((time[0]==ala[0])&&(time[1]==ala[1])) //闹铃时间到
             { flash=0x0f;        //当前时间闪烁
      disp_on=0xf0;
               state=2;                 //当前状态设置为正在闹铃
               dbuf[2]=dbuf[2]|0x80;  //将时与分的分隔符显示出来
             }
        }
    }
  if(state==0x02)   //如果当前正在闹铃
    { if(count%2==0)      //如果满500?s(用来产生频率为1KHZ的方波)
         {  n++;  
            if(n<500)      //在1秒的前1/4秒内
      SPK=~SPK;   //蜂鸣器发声
            else
               SPK=1;               //产生3/4秒的停顿
            if(n==2000)          //如果满1 S(每次鸣叫间隔1S)
              {  n=0;              //n清0,重新再由0计到2000(1S)
                 m++;              //n计满2000(1S)m加1
                 if(m==6)         //如果满6秒
                    { state=0;     //闹铃时间结束
                      m=0;          //m清0
                      flash=0x00;  //恢复正常显示
             disp_on=0xf0;
     }
              }
       }
    }
}

uchar getkey(void)
{ uchar  key;
  uchar  t;
  disp();
  if((key=P1&0x70)==0x70) return 0xff;
  for(t=0;t<5;t++) disp();
  if((key=P1&0x70)==0x70) return 0xff;
  while((P1&0x70)!=0x70)         //检测按键时间
         { disp();
           if(t<250) t++;
         }
  if((t>200)&&(key==0x60)) return 0x61;
  return key;
}
void set_time(uchar *tp)
{ uchar p=0;
  uchar k;
  state=1;          //当前为设置状态
  flash=0x0c;  //LED显示器最高2位(时)闪烁
  while(1)
   { hexbcd(tp); //将要设置的时、分转换成BCD码送显示缓存
     k=getkey(); //读取按键键值
     if(k==KSET) //如果是SET键
          { p++; //调整下标p,使其指向是时或分
            p=p&0x01;   //防止下标出界
   disp_on=0xf0;  //恢复正常显示
            if(p==0x00)   //如果指向的是时
                 flash=0x0c; //LED显示器的高2位闪烁
            else
                 flash=0x03; //LED显示器的低2位闪烁
          }
     else if(k==KINC)  //如果是加1键
          { tp[p]++;   //时/分加1
            if(tp[p]==MAX[p]) tp[p]=0;  //检查时/分是否超出范围
          }
     else if(k==KDEC)  //如果是减1键
          { tp[p]--;   //时/分减1
            if(tp[p]==0xff) tp[p]=MAX[p]-1;//检查时/分是否超出范围
          }
     else if(k==KSET_LONG)    //如果长按SET键,准备返回
           break;
   }
  hexbcd(time);                 //恢复当前时间的显示
  flash=0x00;        //LED显示器恢复正常显示
  disp_on=0xf0;
  state=0;         //当前状态恢复为正常走时状态
}
void  main(void)
{
  uchar  k;
  state=0;       //正常显示时钟方式
  count=0;      //计数器清0
  flash=0x00;   //显示器正常显示
  disp_on=0xf0;
  time[0]=12;   //初始化当前时、分、秒
  time[1]=25;
  time[2]=55;
  ala[0]=12;   //初始化 时、分
  ala[1]=26;
  hexbcd(time); //将当前时间转换为BCD码到显示缓存
  TMOD=0x02;    //T0工作于定时方式2
  TH0=-250;     //T0的定时时间为250?s
  TL0=-250;   
  ET0=1;      //允许T0中断
  TR0=1;      //启动定时
  EA=1;       //开中断
  while(1)
    { disp();
      k=getkey();      //读取按键状态
      if(state==0x02) //如果当前正在闹铃
        { if(k!=0xff)    //只要有键按下
           { state=0x00; //退出闹铃方式,回到正常走时状态
             flash=0x00; //正常显示,不闪烁  
             disp_on=0xf0;
           }  
        }
      else if (k==KSET_LONG) //如果长按SET键
          {     
            set_time(ala);      //设置报警时间
          }
      else if(k==KSET)   //如果是SET键
          { TR0=0;        //关闭定时器T0
            set_time(time);      //设置当前时间
            TR0=1;        //重新开启定时器
          }
      if(update==1)
         { update=0;
           hexbcd(time);
         }
    }
}



关键字:单片机驱动  发光二极管  数码管时钟 引用地址:单片机驱动的发光二极管做的数码管时钟

上一篇:电子小制作单片机最小系统_按键控制数码管显示
下一篇:STC12C2052单片机LED点阵电子时钟制作

推荐阅读最新更新时间:2024-03-16 15:35

利用单片机I/O口直接驱动LCD
  如何将小家电成本降低的同时,又保证其性能,是对应用工程师提出的更高要求。本控制板需要进行温度控制,显示界面要求LCD显示。带专用LCD驱动器,又带A/D转换器的单片机成本太高,因此选用台湾义隆公司带A/D的单片机EM78P259N直接驱动LCD。该款单片机性价比高,性能可靠,很适合在家电控制中应用。 1 LCD简介   目前,市面主流LCD(液晶显示器)分成以下几大类:TN(扭曲阵列型)、STN(超扭曲阵列型)、DSTN(双层超扭曲阵列)、HPA(高性能定址或快速DSTN)、TFT(薄膜场效应晶体管)等。由于成本因素,目前小家电大多数采用的是TN型单色液晶显示器,它的原理是把液晶灌入两个列有细槽的平面之间。这两个平面上的槽
[应用]
AT89S51单片机驱动3.5寸TFT模块的设计
前市场流行的3.5寸屏基本上都是只内置了驱动器,而不带控制器,这样给用户的使用造成了一些难度。基本上很多朋友在用彩屏时选择一些带LCD控制器的ARM7或ARM9去开发,对于不会ARM开发的朋友来说,只使用普通MCU,这样可以选择的3.5寸TFT模块,就很难找到了。 本文就是基于市场上一款比较使用的3.5寸TFT模块编写的,用户只需要帮该TFT模块当作普通的单色液晶的开发思路来使用,就可以很容易去编程。 一、 硬件选择 1、 MCU:AT89S51 2、 开发编译环境:KeilC51 3、 3.5寸TFT模块型号:MzT35C1 二、 TFT模块基本性能: 1、基本参数 模块结构: 内置控制器 屏
[单片机]
AT89S51<font color='red'>单片机</font><font color='red'>驱动</font>3.5寸TFT模块的设计
采用混合信号高电压单片机实现LED降压-升压驱动电路
  LED背景知识 近年来,LED逐渐成为一种可行的新兴光源,它们已经不再仅仅用作电子设备的“状态指示灯”。技术进步使得LED的发光效率通常可达白炽灯的三倍多,此外,LED还非常耐用,寿命超过上万小时。   针对照明应用的大功率LED要采用恒流源驱动,一些标准驱动电流常常用在不同LED生产商的产品中,其中,350mA和700 mA最为常见。根据串联结的类型和数量,LED两端的正向压降可能不同。许多生产厂商的大功率LED产品都在单个模块中集成了多个结。   驱动LED的一种简单方法是采用串联电阻来限制电流。线性稳压器或运算放大器也可连接成恒流配置。然而,此类线性方法无法在所需要的功率水平下提供足够的效率。   开关电源(
[单片机]
采用混合信号高电压<font color='red'>单片机</font>实现LED降压-升压<font color='red'>驱动</font>电路
基于STM32单片机的DLP驱动电路的研究
DLP投影技术是应用美国德州仪器公司开发的数字微镜元件——DMD(Digital Micromirror Device)作为主要关键处理元件以实现数字光学处理过程的技术。DLP显示的色彩清晰度高、艳丽、细腻、逼真,且为全数字显示即可靠性极高,能在各类产品(如大屏幕数字电视、公司/家庭/专业会议投影机和数码相机(DLP Cinema))中提供最佳图像效果。目前,大部分的家用或商用DLP投影机都采用了单片结构,使得其便于移动携带,因而得到越来越广泛的应用。在目前应用发展的基础上,又对其结构的精简性、携带的方便性提出了更高的要求。传统的DLP投影仪是通过DVI接口接收外部信号,并且经过信号转换传送给DLP控制器来控制DLP的显示,占
[单片机]
基于STM32<font color='red'>单片机</font>的DLP<font color='red'>驱动</font>电路的研究
卖LCD驱动IC厂赚了,MCU龙头瑞萨史上首度赚钱
全球最大微控制器(MCU)厂商瑞萨电子(Renesas Electronics)5日于日股盘后发布新闻稿宣布,因日圆走贬、出售中小尺寸液晶面板用驱动IC研发/销售子公司 Renesas SP Drivers(以下简称RSP) 提列相关获利,加上固定成本删减措施奏功,故预估今年度(2014年4月-2015年3月)合并纯益将达740亿日圆(上年度为净损52亿日圆),将为史上(2010年由NEC电子、瑞萨科技合并以来)首度摆脱亏损局面;合并营益预估将大增44.9%至980亿日圆,合并营收预估将年减5.6%至7,860亿日圆、其中半导体事业营收预估将年减6%至7,480亿日圆。 此为瑞萨首度公布今年度财测预估。瑞萨表示,上述财测预估是
[电源管理]
51单片机驱动步进电机(汇编语言)
在这里介绍一下用51单片机驱动步进电机的方法。 这款步进电机的驱动电压12V,步进角为 7.5度 . 一圈 360 度 , 需要 48 个脉冲完成!!! 该步进电机有6根引线,排列次序如下:1:红色、2:红色、3:橙色、4:棕色、5:$、6:黑色。 采用51驱动ULN2003的方法进行驱动。 ULN2003的驱动直接用单片机系统的5V电压,可能力矩不是很大,大家可自行加大驱动电压到12V。 ;******************************************************************   ;****************************步进电机的驱动*************
[单片机]
51<font color='red'>单片机</font><font color='red'>驱动</font>步进电机(汇编语言)
FFT算法在单片机中的使用&&LCD12864驱动
本次创新基金我是要做一个简易的频谱仪,核心就是要进行一个FFT运算。大家知道,如果采用DSP芯片效果那是相当好的。但由于项目资金以及时间不够等情况,我采用的是ATMEL公司的AVR单片机,这款单片机的FLASH存储和内存比51单片机犀利得多。 由于采用的是12864液晶,也就是一个横128点竖64点的一个点阵,因而采用128点FFT运算已然够了,因为即使得到再多的数据也无法在液晶上可视化显示出来。本文是基于128点FFT运算。 程序如下: #include iom16v.h #include macros.h #include math.h #define N 128 #define PI 3.141592653589 #de
[单片机]
单片机驱动点阵16*16综合C程序-包含各种效果
一、硬件简介: 经过努力,终于完成了我以前一直的梦想,点阵各种模式能独立原创出点阵屏各种模式:间断、上移、下移、左移、右移、上拉幕、下拉幕、左拉幕、右拉幕、左覆盖、右覆盖等等模式,我认为点阵只要是上移、左移会了,基本其它的都会了!一定要理解了,才算哟,太高兴了,现在和大家分享下了,我的硬件是:行是译码器74HC154+S8550,列是74HC595移位寄存器. 祥细视频如下 http://www.tudou.com/programs/view/D0SCJyO4RBQ/   完整的程序源代码下载: http://www.51hei.com/f/dz854.rar 二、具体原理图见 电路介绍: http://www.51he
[单片机]
<font color='red'>单片机</font><font color='red'>驱动</font>点阵16*16综合C程序-包含各种效果
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved