2021-08-22 13:21:09 索炜达电子 569
项目编号:E421
文件大小:733K
源码说明:带中文注释
开发环境:C编译器
简要概述
本文将向你介绍如何利用89c51系列单片机实现数字闹钟。包含时间调整和闹钟设定(本篇文章面向一点都不懂得小白,很啰嗦,高手略过文字)注意:本文hex文件超过4k,请选择较大内存的单片机
需求分析
首先我们需要了解需求:做一个数字闹钟,可以计时,可以通过按钮调时,通过按钮设定闹铃时间。我们平时所见的数字钟,总是有一个‘:’在不停闪动表示频率。同时时间以时、分、秒的形式显示。所以我们需要驱动八个数码管,用以实现日、时、分、秒(当然,你也可以选择月日时分,只要你明白其中运行的原理)。本例将使用闪动的‘.’代替‘:’,使用5个按钮实现调时,设钟。
标题所需材料
-STC89C52 *1
-7seg mpx8 ca 数码管 *1
-10Ω排阻(RX8) *1
-100Ω电阻 *1
-1KΩ电阻*1
-无源蜂鸣器 *1
-晶体管2N4403 *1
-12MHz晶振 *1
-47uF电容 *3
-按钮 *5
-开关*1
-导线若干 如果没有,可以用模拟器实现
电路原理图
程序设计
这里是关键的一步,关系到我们的时钟能否点亮和正常运行。 时钟需要计时,并且经过显示才能被我们看到。我们需要单片机在后台计时,并通过驱动数码管显示时间。单片机驱动数码管的方式是扫描,我们使用的是7seg-mpx8-ca数码管(七段八位数码管)
上图是七段一位数码管 只有一个阴极端口和和七个阳极端口,想要让它显示数字需要让a-g的阳极端按照一定规律接入高电平,阴极需要接地。a-g和dp都是一个单独的LED。
#define FOSC 120000L//晶振频率
void delay(unsigned int ms)
{
unsigned int t = FOSC/1200;//计算周期为12
for(;ms != 0;ms--,t = FOSC/1200)
while(t--);
}
但本文采用单片机内置定时/计数器计算时间。(因为机器周期是可调的,并且机器在做任何计算的过程中都会占用计算周期,计算的步骤和方式消耗时间是不定的,而且会占用当前线程,所以delay有时是不准确的,占位置的。)
定时器的操作比delay要复杂一些,但优势在于它计时较为准确(时钟的必需品),而且计时器不会干扰到我们的主线程(节约资源)。
上图为七段八位数码管 可以看做八个一位数码管共用七段阳极接口。
你可能会想这么多管共用七个端口,它们怎么会显示不同的数字呢? 这就是为什么需要扫描的原因了——当我们希望在数码管显示‘12’的时候,需要在第一个数码管的七段中输入‘1’,并且设置第一个阴极口为低电平,第二个阴极口为高电平,这样第一个数码管显示‘1’第二个数码管黑屏;以极快的速度,再将七段接口输入‘2’,同时第二个数码管置低电平,第一个置高电平,如此循环。这样就造成了交替闪烁的‘12’。由于人眼有视觉残留,所以看到的是静止的‘12’(扫描周期小于20ms效果更好)。
讲完如何驱动数码管,现在需要考虑如何让单片机在后台计时了。 后台计时的方法有很多种, 有根据晶振频率和机器计算周期的比计时。
目录│文件列表:
└ C52DigitalClock
│ LICENSE.txt
├ keil
│ │ STARTUP.A51
│ │ timer2.c
│ │ timer2.uvgui.Klaoye
│ │ timer2.uvopt
│ │ timer2.uvproj
│ ├ Listings
│ │ │ STARTUP.lst
│ │ │ timer2.lst
│ │ └ timer2.m51
│ └ Objects
│ │ STARTUP.obj
│ │ timer2
│ │ timer2.build_log.htm
│ │ timer2.hex
│ │ timer2.lnp
│ └ timer2.obj
├ pictures
│ │ 1.PNG
│ │ main.PDF
│ │ main.png
│ │ thread.png
│ └ 捕获.PNG
└ protues
│ Backup Of main.pdsbak
│ Last Loaded main.pdsbak
│ main.pdsprj
└ main.pdsprj.Klaoye-PC.Klaoye.workspace