历史上的今天
返回首页

历史上的今天

今天是:2024年12月17日(星期二)

正在发生

2020年12月17日 | 一款51单片机电子钟制作(C语言)

2020-12-17 来源:51hei

/*一款电子钟程序,此电子钟是四位电子钟数码管组成的,功能分别有走时、响闹、走时间调整、闹钟时间调整等功能!调整部分分别由三个按键实现,一个功能键,一个+(加)键,另一个为-(减)键,其它功能键是复用功能!*/

硬键介绍:数码管个位.十位.百位.千位.小数点分别接P0.0 P0.1 P0.2 P0.3 P0.4。蜂鸣器接P3.5脚,功能按键接P3.2 加按键接P3.3 减按键接P3.4

以下是两张图片!!!



#include //头文件
#define uchar unsigned char//宏定义
#define uint unsigned int//宏定义
uchar shi,fen,nshi,nfen,mao,ding,ding1,ding3,yin;//变量定义
sbit ge=P0^0;//数码管个位
sbit shi4=P0^1;//数码管十位
sbit bai=P0^2;//数码管百位
sbit qian=P0^3;//数码管千位
sbit dian=P0^4;//两小数点位
sbit bbt=P3^5;//闹钟输出口
sbit key=P3^2;//功能按键定义
sbit key1=P3^3;//++按键定义
sbit key2=P3^4;//--按键定义
bit  a=0;//调时间功能时位定义
bit  b=0;//调小时位定义
bit  c=0;//调分钟位定义
bit  d=0;//调闹钟小位定义
bit  e=0;//调闹钟分钟定义
bit  g=0;//主程序位定义,它控制主程序中的显示子程序
uchar code table[]={
0xc0,0xf9,0xa4,0xb0,0x99,
0x92,0x82,0xf8,0x80,0x90,
0x88,0x83,0xc6,0xa1,0x86,
0x8e};//数组,即列表
void key11();//声时调时子程序
void delay(uint);//声明延时子程序
void disy(uchar,uchar);//声明时间显示子程序
void ndisy(uchar,uchar);//声明调时显示子程序1
void disy1(uchar);//声明调时时显示小时子程序
void disy2(uchar);//声明调时时显示分子程序
void chushi();//初始化程序
void bbbt();//闹钟子程序

//////////////主程序/////////////////

void main()//主程序开始
{
chushi();//初始化
while(1)//大循环
{
  if(g!=1)//如果g不等于1,就执行下一句,否则跳过下一句
  disy(fen,shi);//调用走时显示子程序
  key11();//调用按键子程序
  bbbt();//调用闹钟子程序
}
}

/////////////按键执行的子程序/////////////

void key11()//按键子函数
{

if(a!=0)//如果a不等于0,则执行大括号语句,否则跳过
{
  dian=0;//将中间两个小数点打开
  delay(10);//延时一会儿
  dian=1;//将点关掉
  delay(10);//延时一会儿,以上即是动态显示
  disy(fen,shi);//调用显示子程序
  delay(4000);//延时,使它闪烁
  }
if(b!=0)//如果b不等于0,则执行大括号语句
{
  disy1(shi);//调用小时显示子程序,此程序在前面声明
  delay(2000);//延时,即使它闪烁
  if(key1==0)//如果+按键有按下,则执行大括号内容
  {
   delay(10);//去抖
   if(key1==0)//再次判断
   {
    shi++;//确实按下了就将小时时间+1
    disy1(shi);//加1后调用小时显示子程序
    delay(10);//延时一会儿
    if(shi==24)//如果小时加到了24就执行下一个语句,否则跳过
    shi=0;//到了24就清0
   }   
  }
  if(key2==0)//如果-按键有按下,则执行大括号内容
  {
   delay(10);//去抖动
   if(key2==0)//再次确认
   {
    shi--;//确实按下就将小时减1
    disy1(shi);//调用显示程序
    delay(10);//延时
    if(shi==(0-1))//如果小时到了(0-1)时,就给23
    shi=23;//给23
   }   
  }
}
if(c!=0)//如果b不等于0,则执行大括号语句
{
  disy2(fen);//调用调分分显示子程序
  delay(2000);//使它闪动
  if(key1==0)//判断+按键是否有按下
  {
   delay(10);//延时
   if(key1==0)//再次确认按下情况
   {
    fen++;//将分加1
    disy2(fen);//调用显示子程序
    delay(10);//延时一会儿
    if(fen==60)//如果分到了60,则执行下一语句
    fen=00;//清0
   }
  }
  if(key2==0)//如果减按键按下了执行下一语句
  {
   delay(10);//延时一会儿
   if(key2==0)//再次判断
   {
    fen--;//将分减1
    disy2(fen);//调用显示子程序
    delay(10);//延时
    if(fen==(0-1))//如果分等于(0-1),则给59
    fen=59;//给59
   }
  
  }

}
if(d!=0)//如果b不等于0,则执行大括号语句
{
  ndisy(nshi,nfen);//调用闹钟显示程序
  delay(2000);//使它闪
  if(key1==0)//如果+按键按下了则执行括号内语句
  {
   delay(10);//去抖
   if(key1==0)//再次判断
   {
    nshi++;//将闹钟时加1
    ndisy(nshi,nfen);//调用显示子程序
    delay(10);//延时
    if(nshi==24)//如果等24就执行下一句话
    nshi=0;//到了24,清0
   }   
  }
  if(key2==0)//如果-按键按下了,则执行括号内容
  {
   delay(10);//去抖
   if(key2==0)//再次判断
   {
    nshi--;//自减1
    ndisy(nshi,nfen);//调用显示程序
    delay(10);//延时
    if(nshi==(0-1))//如果小时等于(0-1),就执行下一句
    nshi=23;//给23
   }   
  }
}
if(e!=0)//如果b不等于0,则执行大括号语句
{
  ndisy(nshi,nfen);//调用显示子程序
  delay(2000);//闪烁
  if(key1==0)//+按键按下了没?
  {
   delay(10);//去抖
   if(key1==0)//再次确认
   {
    nfen++;//将分加1
    ndisy(nshi,nfen);//调用显示子程序
    delay(10);//延时
    if(nfen==60)//到了60?
    nfen=00;//清0
   }
  }
  if(key2==0)//-按键有按下吗?
  {
   delay(10);//延时
   if(key2==0)//再次确认
   {
    nfen--;//分减1
    disy(nfen,nshi);//调用显示
    delay(10);//延时
    if(nfen==(0-1))//如果分等于(0-1),则执行下一句
    nfen=59;//给59
   }
  
  }
}   
}


/////////////闹钟子子程序/////////////

void bbbt()//闹钟子程序
{
  if(ding1==2)//如果计数器ding1到了2次中断?就执行括号内容
{
  ding1=0;//清0计数器
  if(shi==nshi)//走时小时时间与闹钟小时时间相等吗?
  {
   if(fen==nfen)//走时分钟时间与闹钟分钟时间相等吗?
   {
   bbt=~bbt;//将蜂呜器取反,使它发声
   }
  }
   
}
else
bbt=1;//否则将蜂呜器关掉
}


/////////////初始化子程序/////////////

void chushi()//初始化子函数
{
TMOD=0x11;//两个定时器工作在方式1方式下
EA=1;//开总中断
ET0=1;//开定时器0中断允许
ET1=1;//开定时器1中断允许
TR0=1;//开定时器0
TR1=1;//开定时器0
TH0=(65536-50000)/256;//定时器0高位赋值
TL0=(65536-50000)%256;//定时器0低位赋值
TH1=(65536-10000)/256;//定时器1高位赋值
TL1=(65536-10000)%256;//定时器1低位赋值
shi=23;//开机小时显示23
fen=59;//开机分钟显示59
nshi=12;//开机闹钟小时显示12
nfen=00;//开机闹钟分钟显示00
}


/////////////走时显示子程序/////////////

void disy(uchar shi,uchar fen)//走时显示子程序
{
P1=table[shi%10];//小时个位赋值
ge=0;//开个位位选
delay(5);//延时
ge=1;//关个位位选
P1=table[shi/10];//小时十位赋值
shi4=0;//开小时位选端
delay(5);//延时
shi4=1;//关小时位选端
P1=table[fen%10];//分钟个位赋值
bai=0;//将百位打开
delay(5);//延时
bai=1; //将百位关闭
P1=table[fen/10];//分钟十位赋值
qian=0;//打开千位位选
delay(5);//延时
qian=1; //关闭千位
}

/////////////调时显示子程序/////////////

void ndisy(uchar nshi,uchar nfen)//调时显示子程序
{
P1=table[nshi%10&0x7f];//赋值给小时个位
bai=0;//开位选
delay(30);//延时
bai=1;//关位选
P1=table[nshi/10];//赋值给小时十位
qian=0;//开位选
delay(30);//延时
qian=1;//关位选
P1=table[nfen%10];//赋值分十位
ge=0;//开位选
delay(30);//延时
ge=1; //关位选
P1=table[nfen/10];//送分个位
shi4=0;//开位选
delay(30);//延时
shi4=1; //关位选
dian=0;//小数点打开
delay(10);//延时
dian=1;//关闭
}


/////////////调时小时显示子函数/////////////

void disy1(uchar fen)//调时小时显示子函数
{
P1=table[shi%10];//送小时个位
bai=0;//打开小时个位位选
delay(40);//延时
bai=1;//关闭位选
P1=table[shi/10];//关十位代码
qian=0;//打开十位位选
delay(40);//延时
qian=1;//关闭千位
shi4=1; //关闭十位数码管
ge=1; //关闭个位数码管
}


/////////////调时分钟显示子函数/////////////

void disy2(uchar fen)//调时分钟显示子函数
{
P1=table[fen%10];//送分钟个位
ge=0;//打开分个位位选
delay(30);//关闭位选
ge=1;//关十位代码
P1=table[fen/10];//送个位代码
shi4=0;//打开位选
delay(30);//延时
shi4=1;//关闭位选
bai=1;//关闭百位数码管
qian=1; //关闭千位数码管
}


/////////////延时程序/////////////

void delay(uint z)//延时子函数
{
uint x,y;//定义局部变量
for(x=10;x>0;x--)//第一循環
for(y=z;y>0;y--);//内循环
}


/////////////T0中断服务程序/////////////

void zhong() interrupt 1//T0中断服务程序
{
TH0=(65536-50000)/256;//赋值给高位
TL0=(65536-50000)%256;//赋值给低位
ding++; //将走时计数器加1
ding1++;//将响闹计数器加1


/////////////走时程序/////////////

if(ding==10)//走时计数器到了10次中断0.5秒吗?
{
  ding=0;//清0
  dian=~dian;//将小数点取反一次
  mao++;//将秒变量加1
  if(mao==120)//如果秒变量mao到了120次中断(即1分钟),就执行下语句
  {
   mao=0;//将秒mao变量清0
   fen++;//将分变量加1
  }
  if(fen==60)//判断分变量是否到了60
  {
   fen=0;//到了就清0   
   shi++;//将小时加1
   if(shi==24)//如果小到了24就清0
   shi=0;//清0
  }     
}

  
}

/////////////T1中断服务程序/////////////

void zhong1() interrupt 3//T1中断服务程序
{
TH1=(65536-10000)/256;//赋值给高位
TL1=(65536-10000)%256;//赋值给低位
ding3++;//将按键计数器加1

/////////////一键多功能控制程序/////////////

P1=0xff;//先置P1口为高位
switch(yin)//执行一键多功能程序
{
  case 0:if(key==0)//如果0与yin比较相等,则执行break前的所有内容
  {
   delay(10);//延时
   if(ding3==3)//定时器时间到了?作用是实现长按按键才有作用的功能
   {
    ding3=0;//清0
    if(key==0)//再次确认是否有按下
    {
     yin++;//将变量加1,此句很重要,作用是以使下次按下时好执行下一开关语句
     a=1;//将a变为1,即打开按键程序中的第一段程序
     g=1;//将g变1,关闭主程序中的显示,只要按键按下的显示
     bbt=0;//将蜂呜开
     delay(100);//延时
      bbt=1;//关蜂呜器
     TR0=0;//关时间定时器,让时间停止运行,进入调整模式
     disy(fen,shi);//调用调时显示子函数
     while(!key);//按键放开了吗?
    }
   }
  }
  break;//退出开关语句
  case 1: if(key==0)//如果1与yin比较相等,则执行大括号内容
  {
   delay(10);//延时
   if(ding3==3)//定时器时间到了?作用是实现长按按键才有作用的功能
   {
    ding3=0;//清0
    if(key==0)//再次确认是否有按下
    {
     yin++;//将变量加1,此句很重要,作用是以使下次按下时好执行下一开关语句
     b=1;//将b变为1,即打开按键程序中的第二段程序
     a=0;//将a变为1,即关闭按键程序中的第一段程序
     TR0=0;//关时间定时器,让时间停止运行
     bbt=0;//将蜂呜开
     delay(100);//延时
      bbt=1;//关蜂呜器
     while(!key);//按键放开了吗?
    }
   }
  }
  break;//退出开关语句
  case 2: if(key==0)//如果2与yin比较相等,则执行大括号内容
  {
   delay(10);//延时
   if(ding3==3)//定时器时间到了?作用是实现长按按键才有作用
   {
    if(key==0)//再次确认是否有按下
    {
     yin++;//将变量加1,此句很重要,作用是以使下次按下时好执行下一开关语句
     b=0;//将b变为0,即关闭上一次功能
     a=0;//关闭上前面的功能
     c=1;//打开第三次功能
     TR0=0;//关闭定时器0
     bbt=0;//开蜂呜器
     delay(100);//延时
      bbt=1;//关蜂呜器
     while(!key);//按键放开了吗?
    }
   }
  }
  break;//退出开关语句
  case 3: if(key==0)//如果3与yin比较相等,则执行大括号内容
  {
   delay(10);//延时
   if(ding3==3)//定时器时间到了?
   {
    if(key==0)//再次确认是否有按下
    {
     yin++;//将变量加1,以便执行第五次功能
     b=0;//关闭上次功能
     a=0;//关闭上次功能
     c=0;//关闭上次功能
     d=1;//打开第四次功能
     TR0=0;////关闭定时器
     bbt=0;//开响声
     delay(100);//延时
      bbt=1;//关响
     while(!key);//按键放开了吗?
    }
   }
  }
  break;//退出开关语句
  case 4: if(key==0)//如果4与yin比较相等,则执行大括号内容
  {
   delay(10);//延时
   if(ding3==3)//定时器时间到了?
   {
    if(key==0)//再次确认是否有按下
    {
     yin++;//将变量加1,以便执行第五次功能
     b=0;//关闭上次功能
     a=0;//关闭上次功能
     c=0;//关闭上次功能
     d=0;//关闭上次功能
     e=1;//打开第五次功能
     TR0=0;////关闭定时器
     bbt=0;//开响声
     delay(100);//延时
      bbt=1;//关响
     while(!key);//按键放开了吗?
    }
   }
  }
  break;//退出开关语句
  case 5: if(key==0)//如果5与yin比较相等,则执行大括号内容
  {
   delay(10);//延时
   if(key==0)//定时器时间到了?
   {
    yin=0;//将变量清0,以复位按键功能
    a=0;//关闭上次功能
    b=0;//关闭上次功能
    c=0;//关闭上次功能
    g=0;//关闭上次功能
    d=0;//关闭上次功能
    e=0;//关闭上次功能
    TR0=1;//开定时器0,使时间走
    bbt=0;//开响声
    delay(100);//延时
     bbt=1;//关响
    while(!key);//按键放开了吗?
   }
  }
  break;//退出开关语句
}

}

推荐阅读

史海拾趣

DCD [Digital Core Design]公司的发展小趣事

DCD公司自创立之初,就专注于数字核心设计领域的研发。创始人们凭借对电子技术的深刻理解和市场需求的敏锐洞察,带领团队攻克了一个又一个技术难关。在产品研发初期,公司面临着资金短缺和技术难题的双重压力,但团队凭借着坚韧不拔的精神,成功研发出了首款具有竞争力的数字核心设计产品,为公司的发展奠定了坚实的基础。

CLANDELL公司的发展小趣事

在电子产品市场日益同质化的背景下,CLANDELL公司意识到技术创新的重要性。公司投入大量资源研发新型电子元件,通过优化设计和材料选择,成功推出了具有更高性能、更低能耗的电子产品。这一创新不仅提升了CLANDELL公司的市场竞争力,也为整个行业带来了技术进步的推动力。

DMC Tools公司的发展小趣事

DMC Tools公司深知质量是企业的生命线。因此,公司建立了严格的质量管控体系,从原材料采购到生产加工、再到产品检验,每一个环节都严格把关。这种对质量的执着追求使得DMC Tools公司的产品赢得了客户的广泛信任。许多知名电子企业都选择DMC Tools公司作为他们的长期合作伙伴,这也为公司的发展奠定了坚实的基础。

HTSEMI( Jin Yu Semiconductor )公司的发展小趣事

为了加速国际化进程,金宇半导体于2020年制定了详细的国际化战略。公司首先在欧洲设立了研发中心,以吸引更多国际顶尖人才加入。随后,金宇半导体又通过一系列并购整合动作,收购了多家在特定领域具有领先技术的海外企业。这些并购不仅增强了金宇半导体的技术实力和市场影响力,还为其在全球范围内的业务拓展提供了有力支持。通过国际化战略的实施,金宇半导体正逐步成为一家具有全球竞争力的半导体企业。

Aromat Corp公司的发展小趣事

在电子行业的初创期,Aromat Corp以其独特的技术突破而崭露头角。公司创始人带领团队研发出了一款高效能、低功耗的芯片,迅速吸引了市场的关注。通过不断优化产品性能和降低成本,Aromat Corp逐渐在竞争激烈的电子市场中站稳脚跟,为后续的发展奠定了坚实的基础。

ASPEED Technology公司的发展小趣事

2016年,ASPEED Technology宣布并购博通旗下的Emulex Pilot™远程服务器管理芯片业务。这一举措标志着ASPEED在服务器管理芯片领域取得了重要突破,为公司带来了先进的远程服务器管理技术和市场份额。通过并购,ASPEED不仅获得了强大的技术支持,还进一步巩固了其在全球服务器管理芯片市场的地位。

问答坊 | AI 解惑

日本6月芯片设备订单出货比达1.5 创两年来新高

本帖最后由 jameswangsynnex 于 2015-3-3 19:58 编辑 …

查看全部问答>

EEWORLD DIY示波器活动惊喜大奖~~(本活动奖品由泰克提供)

DIY示波器活动仍在进行中...... 目前DIY小组正在进行软、硬件设计及调试,预计9月中、下旬,比较完整的设计将与大家见面。 届时,EEWORLD会组织大家进行团购套件。 对DIY活动之后表现出色的网友,我们将进行奖励。(奖品由泰克提供) 奖励措施 ...…

查看全部问答>

移动通信词汇

主要以:1/4比特数 quarter bit number AGC恢复时间 AGC recovery time AGC启动时间 AGC attack time ATM技术 asynchronous transfer technics, 异步转移模式,为多种速率信 息的情况下研究的一种合适的传输与交换方式。 GSM 泛欧数字蜂窝移动 ...…

查看全部问答>

大家想不想弄个智能家居系统?

突然想弄个智能家居系统,不知道大家感兴趣不?希望能讨论一下。…

查看全部问答>

急聘 兼职网络信息回复员(若干名)100元/天 工资日结

招聘人数: 若干名  薪资待遇: 工作每天3-5小时,100元/天工资每日支付; 岗位描述: 负责公司所要求的信息回复工作(有内容样版),工作地点不限,专兼职均可! 应聘要求: 上网熟练,平均每天工作投入约3小时,具体根据效率自定; 学历不限,在 ...…

查看全部问答>

wince中播放声音的方法

我现在用sndPlaySound播放声音,但是如果有系统弹出对话框播放系统声音时,我先前播放的声音会中断停止,用PlaySound也是如此,还有没有其它的方法播放声音,不会被其他的声音中断停止…

查看全部问答>

如何提高GDI绘图速度

   在wince项目中,使用800x600 24位的bmp做对话框背景,发现切换的速度比较慢。背景的绘制是在OnEraseBkgnd方法中,绘制的方法是直接调用BitBlt,经测试发现绘制一次需要250毫秒以上。而且背景显示的效果是从上到下,渐渐的出来。程序运 ...…

查看全部问答>

nand flash & mtd 驱动高手请进来,高分交流!

   本人目前使用的单板是使用nand flash,本人在上面开发了基于mtd框架的NFTL驱动,目前读写擦除都ok,但是怎么利用mkdosfs为这个nand flash的某个分区生成fat文件系统呢? 我们的nand flash一个页有2048字节,默认的mkdosfs都是用的51 ...…

查看全部问答>

请教一下我用S3C2440驱动三星的LMS283GF03液晶屏问题

1.我用S3C2440驱动三星的LMS283GF03液晶屏,SPI初始化部分是通过了,可以RGB寄存器怎么设置也不对 比如我让显示蓝屏,屏目上有很多黑色的断线,还有显示一段时间后,颜色会慢慢消失,又变成白屏. LCDCON1到LCDCON5也是按屏的数据手册设置的,不知道怎么 ...…

查看全部问答>

请问读FLASH中的数据时,要关闭中断吗?

请问读FLASH中的数据时,要关闭中断吗?…

查看全部问答>