带你使用51单片机做一款简易的电子时钟

发布者:zeta16最新更新时间:2024-03-21 来源: elecfans关键字:51单片机  电子时钟 手机看文章 扫描二维码
随时随地手机看文章

一、前言


今天给大家推荐一个51单片机小实验,带你使用51单片机做一款简易的电子时钟,其中计时模块采用DS1302硬件模块,显示采用LCD显示屏,具体怎么实现开来一起看看吧!


二、DS1302模块介绍


DS1302 是 DALLAS 公司推出的涓流充电时钟芯片,内含有一个实时时钟和31字节静态 RAM,通过简单的串行接口与单片机进行通信。实时时钟、日历电路提供秒、分、时、日、周、月、年的信息,每月的天数和闰年自动补偿等多种功能。时钟操作可通过 AM/PM 指示,DS1302 与单片机之间能简单地采用同步串行的方式进行通信,简易三线SPI通信模式:


RES 复位


I/O 数据线


SCLK 串行时钟


SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省空间,提供方便,正是出于这种简单易用的特性,现在越来越多的芯片集成了这种通信协议,比如MSP430单片机系列处理器。


DS1302时钟芯片的工作原理如下:


DS1302芯片内部有一组定时器和寄存器,通过这些寄存器可以实现时钟的读写操作。


DS1302通过三根引脚与外部设备连接,分别是RST、DAT和CLK。RST引脚用于复位


DS1302,DAT引脚用于数据传输,CLK引脚用于时钟信号。


DS1302芯片使用BCD码表示时间信息,即用4位二进制数表示一个十进制数。例如,分的BCD码为00H到59H。


三、驱动DS1302的代码


以下是使用51单片机驱动DS1302时钟芯片的代码,具体实现步骤如下:


3.1 初始化DS1302时钟芯片


voidDS1302Init(){

//初始化DS1302时钟芯片

DS1302WriteByte(0x8E,0x00);

//关闭写保护

DS1302WriteByte(0x90,0x00);

}


3.2 读取DS1302时钟芯片的时间


voidDS1302ReadTime(unsignedchar*p){

//读取DS1302时钟芯片的时间

unsignedchari;

DS1302WriteByte(0xBF,0x00);

for(i=0;i< 7; i++) {

        p[i] = DS1302ReadByte();

    }

}

3.3 设置DS1302时钟芯片的时间


voidDS1302WriteTime(unsignedchar*p){

//设置DS1302时钟芯片的时间

unsignedchari;

DS1302WriteByte(0xBE,0x00);

for(i=0;i< 7; i++) {

        DS1302WriteByte(p[i], 0x00);

    }

}

3.4 读取DS1302时钟芯片的RAM


//从DS1302读取一个字节的数据

voidDS1302ReadByte(uchar*dat){

uchari;


for(i=0;i< 8; i++) {

        SCLK = 0;

        _nop_();

        *dat |= IO << i;

        SCLK = 1;

        _nop_();

    }

}

四、读取DS1302时钟芯片的RAM


DS1302时钟芯片有31个字节的RAM空间,可以用来存储一些数据。在实际应用中,我们可能需要读取这些存储的数据。读取DS1302的RAM和读取寄存器类似,也需要先向DS1302发送读取RAM的命令,然后再读取RAM的内容。


读取DS1302的RAM需要使用到DS1302的另一个引脚——CE(片选使能)引脚,该引脚在读写DS1302的RAM时需要保持为低电平。读取RAM的过程如下:


4.1 发送读取RAM的命令


向DS1302写入读取RAM的命令:0x61。DS1302会自动切换到RAM读取模式,准备将RAM中的数据传输给单片机。


DS1302Write(0x61);//发送读取RAM命令

4.2 读取RAM的内容


发送读取RAM命令后,就可以读取RAM中的数据了。读取RAM的数据需要先读取DS1302的数据引脚(IO引脚)上的高电平脉冲,然后再读取8个位的数据。具体的读取过程可以使用DS1302ReadByte函数实现,该函数会读取一个字节的数据。


for(i=0;i< 31; i++) {

    DS1302ReadByte(&byte); // 读取一个字节的数据

    ram[i] = byte; // 存储到数组中

}

读取完RAM后,我们可以将其存储到一个数组中,方便后续的使用。


4.3 读取部分单独代码实现(注重逻辑)


#include

#include


#defineucharunsignedchar

#defineuintunsignedint


sbitSCLK=P2^0;

sbitIO=P2^1;

sbitCE=P2^2;


uchards1302_read_ram(ucharaddress)

{

uchari,dat;


CE=0;

_nop_();

SCLK=0;

_nop_();

CE=1;

_nop_();


IO=0;//写指令

SCLK=0;

_nop_();

SCLK=1;

_nop_();

IO=address|0xc0;//选择地址并读取RAM

for(i=0;i< 8; i++) {

        SCLK = 0;

        _nop_();

        SCLK = 1;

        _nop_();

    }

    IO = 0; // 接收数据

    for (i = 0; i < 8; i++) {

        dat >>=1;

if(IO)dat|=0x80;

SCLK=0;

_nop_();

SCLK=1;

_nop_();

}

CE=0;


returndat;

}

在上述代码中,ds1302_read_ram 函数接收一个参数 address,用于指定要读取的 RAM 地址,返回一个字节表示该地址处的 RAM 数据。


该函数的具体实现过程如下:


置 CE 为低电平,并延迟一段时间。


置 SCLK 为低电平,并延迟一段时间。


置 CE 为高电平,并延迟一段时间。


置 IO 为低电平,表示写指令。


置 SCLK 为低电平,并延迟一段时间。


置 SCLK 为高电平,并延迟一段时间。


置 IO 为 address | 0xc0,即选择地址并读取 RAM。


依次进行 8 次时钟上升沿,在每个上升沿时读取数据位。


置 CE 为低电平。


返回读取到的数据。


需要注意的是,读取 RAM 数据时需要将地址的最高位(即 bit7)置为 1,以表示要读取 RAM。另外,在读取数据位时需要依次进行 8 次时钟上升沿,且每次读取时需要先右移数据,再将新数据左移并或上读到的数据位。


五、整体代码实现


下面是使用51单片机和DS1302时钟芯片实现的简易电子时钟的代码实现。代码中包含了DS1302的初始化、时钟读取、RAM读写等基本功能。


#include

#include'LCD1602.h'

#include'DS1302.h'


#defineucharunsignedchar

#defineuintunsignedint


sbitbeep=P3^6;//定义蜂鸣器接口


voidmain()

{

ucharyear,month,day,hour,minute,second;//年月日时分秒

ucharstr_data[11],str_time[11];//用于存放LCD上显示的日期和时间


LCD_Init();//初始化LCD显示屏

DS1302_Init();//初始化DS1302时钟芯片


//将时间初始化为2023年2月21日0时0分0秒

DS1302_Write(0x8e,0);//关闭写保护

DS1302_Write(0x80,0x23);//年份

DS1302_Write(0x82,0x02);//月份

DS1302_Write(0x84,0x21);//日期

DS1302_Write(0x86,0x00);//时钟

DS1302_Write(0x88,0x00);//分钟

DS1302_Write(0x8a,0x00);//秒钟

DS1302_Write(0x8e,0x80);//开启写保护


while(1)

{

//读取DS1302时钟芯片中的年月日时分秒

year=DS1302_Read(0x80);

month=DS1302_Read(0x82);

day=DS1302_Read(0x84);

hour=DS1302_Read(0x86);

minute=DS1302_Read(0x88);

second=DS1302_Read(0x8a);


//将年月日时分秒转换成字符串

sprintf(str_data,'Data:20%02x-%02x-%02x',year,month,day);

sprintf(str_time,'Time:%02x:%02x:%02x',hour,minute,second);


//在LCD上显示日期和时间

LCD_Write_String(0,0,str_data);

LCD_Write_String(0,1,str_time);


Delay_Ms(1000);//延时1秒

}

}

六、显示效果

5d037f88-b32c-11ed-bfe3-dac502259ad0.png?imageView2/2/w/1000


关键字:51单片机  电子时钟 引用地址:带你使用51单片机做一款简易的电子时钟

上一篇:51单片机编程:双路计数器详解
下一篇:MCS-51的中断响应过程解析

推荐阅读最新更新时间:2026-03-23 15:38

51单片机电子时钟C语言程序
以 电子时钟 为结尾篇,附上代码。代码有些不怎么完美。但终究是差不多写出来了。结合了IIC通信,中断定时器的使用,键盘使用,还有液晶的显示。 #include reg52.h sbit RS = P2^7; sbit RW = P2^6; sbit E = P2^5; sbit Sda = P2^0; sbit Scl = P2^1; sbit keyleft = P1^0; sbit keyup = P1^1; sbit keydown = P1^2; sbit keyright = P1^3; unsigned char sec=0,min=0,hour=0; unsigned char Year = 2012
[单片机]
51单片机lcd1602d电子时钟设计
由于课程设计需要,本人做了一个基于51单片机控制的lcd1602d显示的电子时钟电子设计产品。可以显示万年历,星期。 本来还想加上温湿度的检测,发现屏幕空间不够用了。。有需要可以再另外共享那个设计。第一次 单片机源程序如下: #include reg52.h #define uint unsigned int #define uchar unsigned char sbit rs=P1^0; sbit rw=P1^1; sbit en=P1^2; sbit key_set=P3^4; sb
[单片机]
<font color='red'>51单片机</font>lcd1602d<font color='red'>电子时钟</font>设计
利用51单片机制作的电子时钟
最近研究起来了单片机,用的是国产STC98C52芯片。 STC89C52是STC公司生产的一种低功耗、高性能CMOS8位微控制器,具有 8K 在系统可编程Flash存储器。STC89C52使用经典的MCS-51内核,但做了很多的改进使得芯片具有传统51单片机不具备的功能。在单芯片上,拥有灵巧的8 位CPU 和在系统可编程Flash,使得STC89C52为众多嵌入式控制应用系统提供高灵活、超有效的解决方案。 买了很长时间了可是一直在那里放着,今天重新拿出来写了一段电子时钟的C++程序,利用充电宝供电,当作电子时钟挺不错的。 功能: 4个七段数码管作为时钟显示的主体两个显示小时,两个显示分钟,8个LED灯作为秒数的闪烁,4个独
[单片机]
利用<font color='red'>51单片机</font>制作的<font color='red'>电子时钟</font>
51单片机 + ds12c887时钟芯片 开发的电子时钟
原文地址: 51单片机 + ds12c887时钟芯片 开发的电子时钟 作者: 紫暮秋 风 主要代码如下 void delay(int z) { int x,y; for(x=z;x 0;x--) for(y=110;y 0;y--); } void write_com(char com) //写指令操作 { rs=0; lcden=0; //这一步万万不可少,否则不出结果 P0=com; delay(5); lcden=1; delay(5); lcden=0; } void didi() { beep=0
[单片机]
51单片机电子时钟
直在电脑前,写了三天,这才完成了第二步,可以调时间 了,接下来就是闹钟的事情,也就是最后一步,继续努力! org 0000h ajmp main org 000bh ajmp inti0 org 0030h main:mov tmod,#01h mov ie,#82h mov th0,#4ch mov tl0,#00h mov sp,#60h mov r0,#20 setb tr0 loop:lcall display lcall keysan ajmp loop inti0:push psw push acc clr ea mov th0,#4ch mov tl0,#00h djnz
[单片机]
89C52单片机电子时钟的设计
1.实验任务 (1).开机时,显示12:00:00的时间开始计时; (2).P0.0/AD0控制“秒”的调整,每按一次加1秒; (3).P0.1/AD1控制“分”的调整,每按一次加1分; (4).P0.2/AD2控制“时”的调整,每按一次加1个小时; 2.电路原理图 图4.20.1 3.系统板上硬件连线 (1).把“单片机系统”区域中的P1.0-P1.7端口用8芯排线连接到“动态数码显示”区域中的A-H端口上; (2).把“单片机系统:区域中的P3.0-P3.7端口用8芯排线连接到“动态数码显示”区域中的S1-S8端口上; (3).把“单片机系统”区域中的P0.0/AD0、P0.1/AD1、P0.2/AD2端口分别用导线连
[单片机]
89C52单片机<font color='red'>电子时钟</font>的设计
基于STM8的PCF8563电子时钟实验
实验目的: 通过STM8芯片的两个引脚模拟I2C总线时序来读写PCF8563电子时钟的时间 2. 寄存器结构 3. I2C 总线协议 单片机源程序如下: /*********************************************************************** * 说 明: 点亮第一个发光二极管 * 开发平台: 剑齿虎STM8开发板 * * 作 者: 刘洋 张殿东 * 版 本: V1.0 * 日 期: 2016-05-03 * * IAR开发环境 版本 V2.20.1 * ST库函数 版本 V2.2.0
[单片机]
基于STM8的PCF8563<font color='red'>电子时钟</font>实验
基于8051实现的电子时钟(Version1.1)
程序实现的功能: 1. 实验箱上电后, 不显示当前时间. 2. 向8051发送 Start.E 后, 电子时钟开始工作, 并显示当前时间(时 分 秒). 3. 向8051发送 Stop.E 后, 电子时钟暂停工作, 并隐藏当前时间. #include STC89C5xRC.H #include string.h unsigned char code DIG_CODE = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f};//对应数码管显示0~9 char buf ;//存放收到的数据 int tcount = 0;//记录经过的
[单片机]
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

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

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved