历史上的今天
今天是:2024年11月01日(星期五)
2021年11月01日 | AT89C51单片机数字电子钟的设计
2021-11-01 来源:eefocus
一、 设计目的与要求
设计目的:通过设计,培养运用已学知识解决实际问题的能力、查阅资料的能力、自学能力和独立分析问题、解决问题的能力和能通过独立思考。
设计要求:设计一个时、分可调的数字电子钟、断电后将数据保存,开启后时间将从断电后时间继续行走。
二、 设计内容与方案制定
具有校时功能,按键控制电路其中时键、分键六个键分别控制时、分时间的调整。按下小时数实现对小时数加减,按下分钟数实现对分钟数进行加减,并设置有复位键,启始键。
以AT89C51单片机进行实现秒、分、时上的正常显示和进位,其中显示功能由单片机控制共阴极数码管来实现,数码管进行动态显示。
通过AT24C02分别写入时、分、秒数据在断电后实现保存,在下次通电后将数据读出保持为断电前数据。
三、 芯片简介1、 AT89C52
AT89C52是一个低电压,高性能CMOS8位单片机,片内含8k bytes的可反复擦写的Flash只读程序存储器和256 bytes的随机存取数据存储器(RAM),器件采用ATMEL公司的高密度、非易失性存储技术生产,兼容标准MCS-51指令系统,片内置通用8位中央处理器和Flash存储单元,AT89C52单片机在电子行业中有着广泛的应用。
AT89C52有40个引脚,32个外部双向输入/输出(I/O)端口,同时内含2个外中断口,3个16位可编程定时计数器,2个全双工串行通信口,2 个读写口线,AT89C52可以按照常规方法进行编程,也可以在线编程。其将通用的微处理器和Flash存储器结合在一起,特别是可反复擦写的 Flash存储器可有效地降低开发成本。
AT89C52为8 位通用微处理器,采用工业标准的C51内核,在内部功能及管脚排布上与通用的8xc52 相同,其主要用于会聚调整时的功能控制。功能包括对会聚主IC 内部寄存器、数据RAM及外部接口等功能部件的初始化,会聚调整控制,会聚测试图控制,红外遥控信号IR的接收解码及与主板CPU通信等。主要管脚有:XTAL1(19 脚)和XTAL2(18 脚)为振荡器输入输出端口,外接12MHz 晶振。RST/Vpd(9 脚)为复位输入端口,外接电阻电容组成的复位电路。VCC(40 脚)和VSS(20 脚)为供电端口,分别接+5V电源的正负端。P0~P3 为可编程通用I/O 脚,其功能用途由软件定义,在本设计中,P0 端口(32~39 脚)被定义为N1功能控制端口,分别与N1的相应功能管脚相连接,13 脚定义为IR输入端,10 脚和11脚定义为I2C总线控制端口,分别连接N1的SDAS(18脚)和SCLS(19脚)端口,12 脚、27 脚及28 脚定义为握手信号功能端口,连接主板CPU的相应功能端,用于当前制式的检测及会聚调整状态进入的控制功能。
2、 AT24C02
AT24C02支持I2C,总线数据传送协议I2C,总线协议规定任何将数据传送到总线的器件作为发送器。任何从总线接收数据的器件为接收器。数据传送是由产生串行时钟和所有起始停止信号的主器件控制的。主器件和从器件都可以作为发送器或接收器,但由主器件控制传送数据(发送或接收)的模式,由于A0、A1和A2可以组成000~111八种情况,即通过器件地址输入端A0、A1和A2可以实现将最多8个AT24C02器件连接到总线上,通过进行不同的配置进行选择器件。
AT24C02的存储容量为2K bit,内容分成32页,每页8Byte,共256Byte,操作时有两种寻址方式:芯片寻址和片内子地址寻址。
(1)芯片寻址:AT24C02的芯片地址为1010,其地址控制字格式为1010A2A1A0R/W。其中A2,A1,A0可编程地址选择位。A2,A1,A0引脚接高、低电平后得到确定的三位编码,与1010形成7位编码,即为该器件的地址码。R/W为芯片读写控制位,该位为0,表示芯片进行写操作。
(2)片内子地址寻址:芯片寻址可对内部256B中的任一个进行读/写操作,其寻址范围为00~FF,共256个寻址单位。
四、 设计步骤1.2.各单元电路及工作原理
(1)按键控制电路
键盘可实现对时间的校对,用四个按键来实现。按下小时数加实现对小时数进行加一,按下小时数减实现对小时数减一,按下分钟数加一实现对分钟数加一,按下分钟数减一实现对分钟数减一。当按下复位键时时间回到初始时间,按下启停键时时钟开始工作在次按下停止工作。
其电路连接图如下:

LED显示器是现在最常用的显示器之一发光二极管(LED)分段式显示器由7条线段围成8字型,每一段包含一个发光二极管。外加正向电压时二极管导通,发出清晰的光。只要按规律控制各发光段亮、灭,就可以显示各种字形或符号。显示电路显示模块需要实时显示当前的时间,即时、分、秒,因此需要6个数码管,采用动态显示方式显示时间,其硬件连接方式如下图所示。
(3)AT24C02连接电路
AT24C02支持I2C,总线数据传送协议I2C,总线协议规定任何将数据传送到总线的器件作为发送器。任何从总线接收数据的器件为接收器。数据传送是由产生串行时钟和所有起始停止信号的主器件控制的。通过AT24C02分别写入时、分、秒数据在断电后实现保存,在下次通电后将数据读出保持为断电前数据。
1.3.绘制原理图
其计时周期为24小时,显示满刻度为23时59分59秒。整个设计图由复位电路、AT89C51单片机、键盘控制电路组成。 显示电路将“时”、“分”、“秒”通过七段显示器显示出来,6个数码管的段选接到单片机的P0口,位选接到单片机的P2口。数码管按照数码管动态显示的工作原理工作。 把定时器定时时间设为50ms,则计数溢出20次即得时钟计时最小单位秒,而20次计数可用软件方法实现,每累计60秒进1分,每累计60分钟,进1小时。时采用24进制计时器,可实现对一天24小时的累计。 校时电路时用来对“时”、“分”显示数字进行校对调整,时分秒三个控制键分别接单片机的p3.2、p3.3、P3.4、P3.5进行控制。按一下分键秒单元就加1 ,按一下时键分就加1。将AT24C02接入P3.1和P3.2对断电后数据保存,通电后数据从断电前恢复运行。
1.4.元件清单列表
| 单片机 | AT89C51 | *1 |
数码管 | 7SEG-MPX8-CA-BLUE | *1 |
三极管 | NPN | *8 |
按钮 | BUTTON | *6 |
上位排阻 | RESPACK-8 | *1 |
EEPROM | AT24C02 | *1 |
2、程序设计2.1程序流程
数字电子钟采用内部硬件定时器来进行定时。sec等于60,应将sec清零,同时min加1。如果min等于60,应将min清零,同时h加1。如果h大于23时,应将h清零,当h小于10时十位不显示。通过分析可知,程序中可分别由
{
num2=0;
sec++;
if(sec==60)
{
sec=0;
min++;
if(min==60)
{
min=0;
h++;
if(h==24)
h=0;
}
}
}
这段程序负责秒、分、时的计时。
按钮K1、K2和K3、K4为调时、调分控制按键。这两个按钮信号的输入采用外部中断方式来实现。若产生外部中断时,通过调用H或_min来实现调时或调分操作。通过displays()显示时分秒中间用“-”隔开每隔一秒实现闪烁。
断电后数据保存,通过AT24C02芯片采用IIC串口通信解决掉电保护,具体将时、分、秒,数据每隔一秒时间将数据写入AT24C02中,在断电后数据停留在断电前,通电后数据恢复。
2.2主程序:
void main()
{
init();
sec=read_add(0);
if(sec>60)
sec=0;
min=read_add(1);
if(min>60)
min=0;
h=read_add(2);
if(h>24)
h=0;
if(write==1)
{
write=0;
write_add(0,sec);
write_add(1,min);
write_add(2,h);
}
}
}
在主程序中先将读出保存数据分别赋给h、min、sec然后判断计时器是否到了一秒,如果到了就在24C02的地址0中写入sec在地址1中写入min在地址2中写入h。最终实现数据断电的保存。
2.2.源程序:
#include
#define uchar unsigned char
#define uint unsigned int
Ucharcode tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
bit write=0;
sbit key1=P3^2;
sbit key2=P3^3;
sbit key3=P3^4;
sbit key4=P3^5;
sbit key5=P3^6;
sbit key6=P3^7;
sbit sda=P3^1;
sbit scl=P3^0;
void delayms(uint);
void display();
sbit key=P3^2;
ucharnum2,secshi,secge,minshi,minge,hshi,hge;
uchar mun=0,sec=0,min=20,h=5;
void displays();
void keyscan();
void delay()
{;;}
void start()
{
sda=1;
delay();
scl=1;
delay();
sda=0;
delay();
}
void stop()
{
sda=0;
delay();
scl=1;
delay();
sda=1;
delay();
}
void respons()
{
uchari;
scl=1;
delay();
while((sda==1)&&(i<250))
i++;
scl=0;
delay();
}
void init()
{
sda=1;
delay();
scl=1;
delay();
}
void write_byte(uchar date)
{
uchari,temp;
temp=date;
for(i=0;i<8;i++)
{
temp=temp<<1;
scl=0;
delay();
sda=CY;
delay();
scl=1;
delay();
}
scl=0;
delay();
sda=1;
delay();
}
uchar read_byte()
{
uchari,k;
scl=0;
delay();
sda=1;
delay();
for(i=0;i<8;i++)
{
scl=1;
delay();
k=(k<<1)|sda;
scl=0;
delay();
}
returnk;
}
void write_add(ucharaddress,uchar date)
{
start();
write_byte(0xa0);
respons();
write_byte(address);
respons();
write_byte(date);
respons();
stop();
start();
write_byte(0xa1);
respons();
write_byte(address);
respons();
write_byte(date);
respons();
stop();
start();
write_byte(0xa2);
respons();
write_byte(address);
respons();
write_byte(date);
respons();
stop();
}
uchar read_add(uchar address)
{
uchardate;
start();
write_byte(0xa0);
respons();
write_byte(address);
respons();
start();
write_byte(0xa1);
respons();
date=read_byte();
stop();
start();
write_byte(0xa2);
respons();
write_byte(address);
respons();
start();
write_byte(0xa3);
respons();
write_byte(address);
respons();
returndate;
}
void main()
{
init();
sec=read_add(0);
if(sec>60)
sec=0;
min=read_add(1);
if(min>60)
min=0;
h=read_add(2);
if(h>24)
h=0;
TMOD=0x01;
EA=1;
ET0=1;
TH0=(65536-45872)/256;
TL0=(65536-45872)%256;
TR0=1;
while(1)
{
displays();
display();
if(write==1)
{
write=0;
write_add(0,sec);
write_add(1,min);
write_add(2,h);
}
keyscan();
}
}
void displays()
{
if(num2==0)
{
P2=0xdb;
P0=0x40;
delayms(2);
}
}
void display( )
{
secshi=sec/10;
secge=sec%10;
minshi=min/10;
minge=min%10;
hshi=h/10;
hge=h%10;
P2=0xbf;
P0=tab[secshi];
delayms(2);
P2=0x7f;
P0=tab[secge];
delayms(2);
P2=0xf7;
P0=tab[minshi];
delayms(2);
P2=0xef;
P0=tab[minge];
delayms(2);
P2=0xfe;
P0=tab[hshi];
delayms(2);
P2=0xfd;
P0=tab[hge];
delayms(2);
}
void delayms(uint xms)
{
uintx,y;
for(x=xms;x>0;x--)
for(y=110;y>0;y--);
}
void keyscan()
{
if(key1==0)
{
delayms(10);
if(key1==0)
{
h++;
if(h==24)
{
h=0;
}
上一篇:数码管与中断系统知识笔记
下一篇:关于51单片机数码管消影
史海拾趣
|
BL8505-33 1 SM ,呵呵,最后一个器件终于联系上了,听有的公司说国外都没货了呢,:(\" 峰回路转,试着打了一个网上留的电话,竟然可以免费提供,虽然钱不多,但解决了一个大问题呢,这里感谢下华芯邦的天涯… 查看全部问答> |
|
我编了个程序,想让10秒钟,LED的走马灯的方向改变一次,但是,实际上,我测试出来的实际是24秒,奇怪了!单片机的频率是12MHz 代码如下: #include sbit L1=P0^0; sbit L2=P0^1; sbit L3=P0^2; int y=1; bit n=1; void delay02s(void) ...… 查看全部问答> |
|
自己做的开发板,仿真机是XDS560PLUS 用JTAG口连接,连接时出现了以下错误 Trouble Reading Register: Error 0x80002044/-275 Fatal Error during: Register, Initialization, Control, This error was generated by TI\\\'s USCIF driver. SC ...… 查看全部问答> |
|
关于STM32F10XR.LIB和STM32F10XD.LIB文件的疑惑 在编译C:KeilARMExamplesSTSTM32F10x下的例程的时候都会用到这两个文件,他们的源文件在哪里?把他们去掉后再加入 ...… 查看全部问答> |
|
我用的仿真设备是(msp-fetp4301f1.3)不知道是不是这样看的,使用时是不是直接把它接到计算机的并口就可以开始仿真了?cpu是msp430f149的,如果我要写一个AD采样程序,要不要外加电源?可不可以直接使用例子??… 查看全部问答> |
|
早在看 重构 时,就一直想学会写 测试程序。后来因为 搜索百度,据称,C下有一个 CUnit,和JUnit大致是一回事。那时候就一直在找资料看,琢磨着,怎么把这个东东用在 单片机上。不过关于这个问题,现在还没想明白,怎么玩。因为搜索到的 工具 CUnit ...… 查看全部问答> |
|
【MSP430 LaunchPad应用笔记】用G2231ADC实现示波器 使用LaunchPad MSP430G2231内建的10位200KSPS ADC 采集数据,通过串口发送到主机。 上位机软件使用CSharp开发,接收LaunchPad的数据并将波形显示在屏幕上。 LaunchPad源码 /** //数据头长度为格式为8个字节,//[0]~[3]0x00,0xff,0xff,0x00为起始 ...… 查看全部问答> |
|
走进Linux 操作系统摘要:本期涉猎了操作系统的来龙去脉后与大家携手步入Linux世界。我们力图展示给大家一幅Linux系统的全景图,并为了加深对linux系统的全面认知,亲手搭建了一个能运行在内存中的试验系统。同时为大家提供了几个shell脚本帮助建立 ...… 查看全部问答> |




