基于DS1307的可调实时时钟系统设计
利用
实时时钟 芯片 DS1307 设计一个能够调节时间的实时时钟。 介绍采用 I2C 总线接口实时时钟芯片 DS1307 进行准确定时的设计原理, 提出实时时钟芯片 DS1307 与单片机接口电路的设计方法,同时给出几个典型程序实例,通过 Proteus 软件进行仿真实现。先来说说实时时钟DS1307的使用!
DS1307 是一款十分常用的实时时钟芯片,它可以记录年、月、日、时、分、秒等信息,提供至2100年的记录。可使用电池供电,也就是说,即使Arduino 在断电状态下,时钟芯片仍然是在运行的。它使用十分常用的两线式串行总线(I2C),只要两根线即可和Arduino 通信。
电控单元的时钟基准通常可利用 CPU 内部定时器作为时钟基准,并通过软件编程和 CPU 时钟中断来构造一个软时钟。 这种方法的优点是无需额外硬件支持,但缺点是时钟的计时精度受 CPU 主晶振以及与其相连的起振电容的影响而无法做到很高, 因此累积误差较大。同时在主电源掉电时为了维持时钟不停摆,系统必须由备用电源给整个 CPU 供电,这将导致功耗增大。
I2C总线虚拟技术
DS1307是一款具有I2C总线接口的实时时钟芯片,要驱动具有I2C总线接口的DS1307芯片,一种办法是选择一款带有I2C总线接口的高档单片机,然而,在很多小型仪器仪表中以及在单片机的教学环境中,使用带有I2C总线接口的高档单片机在经济上是不合算的,在这种情况下,可以采用I2C总线虚拟技术,选用普遍使用的51单片机,利用单片机的通用I/O端口模拟实现I2C总线接口。
硬件接口电路设计
本系统的电路由单片机AT89C51、日历时钟芯片DS1307、独立按键及显示电路组成。
DS1307与AT89C51的接口
为了使AT89C51单片机能够驱动DS1307芯片,本文采用了I2C总线虚拟技术,将单片机P2.6口和P2.7口来虚拟I2C总线接口。I2C总线是同步串行数据传输总线,其内部为双向传输电路,端口输出为开漏结构,故总线上必须有上拉电阻,通常可取5~10kΩ。因单片机P2口内部有上拉电阻,故DS1307芯片的SCL引脚与SDA引脚与单片机接口时,不需再添加上拉电阻。此外,按照DALLAS公司推荐的硬件接法,往往需要精度很高的晶体,为了提高其可靠性并节约成本,可将DS1307的X2引脚添加上拉电阻,从而可以克服使用普通晶振时DS1307不起振的问题,进而保证了DS1307的起振。日历时钟芯片DS1307与AT89C51的接口电路如图1所示。
时钟显示电路
为了将系统时间实时显示出来,本系统没有采用常用的数码管作为显示方式,而是采用1602LCD液晶实时显示时间,这样电路的设计就会相对简单一些,所用到的I/O口也较少。1602液晶的接口电路如图2所示。
时钟调节电路
为了能够及时对时间进行调节,本系统设计了时钟调节电路,由K0、K1、K2三个按键组成,且分别由单片机的P2.0、P2.1和P2.2口控制。其中,K0做为时钟调节的菜单键,第一次按下表示可以调节时间秒,第二次可以调节时间分,第三次按下调节时,第四次按下退出调时菜单,时钟继续开始走动。K1和K2分别是时分秒调节的加减键。在本电路中,根据经验总结,额外添加三个上拉电阻,以保证在没有按键按下时,进入单片机三个I/O口的按键均处于高电平状态,防止干扰产生。时钟调节电路如图3所示。
接口程序设计
软件程序设计采用模块化设计思想,包括主程序、初始化子程序、时钟运行子程序,按键扫描子程序。其中,初始化子程序主要工作有:初始化I2C总线,使总线处于备用状态;初始化LCD液晶显示器让其正常显示;初始化定时器0并开启定时器0中断。时钟运行子程序主要负责让DS1307芯片更新时间并在LCD上显示。按键扫描子程序负责检测按键的状态并将更改后的时间显示出来。主程序主要负责初始化及键盘扫描工作。本系统主程序的流程图如图4所示。
在本系统中,因采用了I2C总线虚拟技术,需严格按照时序图的要求进行操作,因此,在程序设计当中,分别添加了几个子程序,用于实现单片机与DS1307进行通信。下面是根据本文电路对I2C总线上的信号进行模拟的几个子程序:
void start() //模拟 I2C 启动信号
{
SDA = 1;
Nop ();
SCL = 1;
Nop ();
SDA = 0;
Nop ();
SCL = 0;
}
void stop() //模拟 I2C 停止信号
{
SDA = 0;
Nop ();
SCL = 1;
Nop ();
SDA = 1;
Nop ();
}
void ack() //模拟 I2C 应答信号
{
SDA = 1;
Nop ();
SCL = 1;
Nop ();
SCL = 0;
}
void un_ack() //模拟 I2C 非应答信号
{
uchar i;
i=0;
SCL=1;
while(SDA==1&&i《200) i++;
Nop ();
SCL = 0;
}
需要注意的是,DS1307的各类时间数据均以BCD码的格式存储在相应的时间寄存器中,而1602液晶显示器只能识别字符码,即ASCLL码,因而1602在向DS1307读取或写入时间数据时,需要进行数据类型转换。本文采用以下两个子程序用来完成上述功能:
uchar dec_to_bcd (uchar dec) //ASCLL 码 (十 进 制 )转BCD 码
{
Uchar x, y;
x=dec/10;
y=dec%10;
y=(x《《4)|y;
return y;
}
uchar bcd_to_dec(uchar bcd) //BCD 码 转 ASCLL 码(十
进制)
{
Uchar x, y;
y=bcd/16;
x=bcd % 16;
y=y*10+x;
return y;
}
仿真分析
本文最后使用Proteus软件对本实时时钟系统进行仿真,将代码下载到单片机当中并启动Proteus后,液晶显示器与DS1307时钟显示模块同时显示初始时间并开始计时, 适当调节三个独立按键 K0~K2 后,液晶显示器显示调整后的 时间并且把新的 时间写入DS1307,DS1307 从新的时间开始计时。 仿真效果如图5 所示。
本文设计了一个基于 DS1307 可调实时时钟系统,提出了实时时钟芯片 DS1307 与单片机接口电路的设计方法,因本系统采用了 I2C 总线虚拟技术,需严格按照 I2C 总线时序图的要求对 DS1307 进行操作,本文给出了对I2C 总线上的信号进行模拟的几个典型程序实例,最后通过 Proteus 软件成功仿真实现。
51单片机定时器用法之1秒定时程序设计
动画演示
在我们的DIY电子时钟里,需要用到单片机定时器来做秒的显示,说是显示,其实就是实现数码管上“:”点的闪烁。这里初步定义为每秒亮1次,亮0.5秒,灭0.5秒。实现显示秒的功能。这里也可以用DS1302的秒数据来做,但是实现起来麻烦,达到一样的效果,我们追求的是程序越简单越好,所以在此我们用单片机定时器来实现。
我们DIY时钟板子上的单片机为STC15W408AS,单片机自带IRC可调时钟和搞可靠复位,为了降低功耗(工作频率越低,功耗越小),本时钟采用12M的工作频率(烧写程序是在软件上选择),那当定时器工作在12T模式下时,一个机械周期就是1us。
接下来我们就该看看单片机的数据手册了。以下是今天我们需要关注的寄存器:
TCON位定义
TMOD寄存器位定义
T0工作方式设置
TCON为定时器T0和T1的控制寄存器,可以位寻址(直接操作位);TMOD是T0、T1工作方式控制寄存器,不可以位寻址(只能操作寄存器),高四位控制T1,低四位控制T0;定时器的工作方式由TOMD寄存器中的M1和M0选择,具体如上图。
本例中我们要用T0实现1秒的定时时间,这里我们用T0工作在方式0,也就是16位的自动重载方式(传统的51单片机只有8位的自动重载,需要做高精度的定时时最好用自动重载方式)。我们不需要外部中断来开启定时器,所以GATE位=0,T0工作在定时模式,CT=0,所以我们TMOD寄存器的值为0x00;在TCON寄存器里和T0相关的位有TF0和TR0;TF0=0:T0中断标志位,当定时器中断产生是,TF0自动置位,CPU相应中断后硬件自动清零;TR0=1:开启定时器,相当于定时器的开关。
除了这些寄存器外,定时器溢出后,也会产生中断,所以还需要去设置中断部分:
EA=1:,开启总中断,相当于中断总开关;ET0=1;开启定时器T0中断,相当于中断的子开关,只有中断的总开关和相应的子开关都开启后,CPU才能相应中断信号,具体请看中断部分数据手册。我们用的STC15W系列单片机属于增强型单片机,为了和传统51单片机兼容,还专门设有一个寄存器AUXR,此寄存器可设置T 0工作在1T还是12T模式,此处我们让T0工作在12T模式下,AUXR=0x00。最后就是定时器的初值寄存器了,我们需要定时的时间是500ms,16位的定时器再12M频率下最大定时时间为65535us,而我们需要的是500ms,明显达不到,那我们就需要做组合定时的方式,这里我们设定定时器的中断频率为10ms,那我们中断1次后在中断函数里将某个变量加1,当变量加到50的时候就是500ms,当变量加到100的时候就是1s了。这就是我们实现1s定时的思路。
具体实现程序如下:(因头条原因,代码图片无法加入,需要请移步关注微信公众号)
如上图中程序所示,定时器初始化时设置T0位16位自动重载模式,工作在12T模式,初值10ms,开启定时器,开启中断。这样定时器就工作了;在定时器中断函数里,每次进入中断后我们就给变量T_a自加1,当变量小于50的时候(小于500ms),让D=1(D即为我们电路中控制秒显示的那两个点,高电平有效),大于50小于100的时候D=0,关闭秒显示。这样一来就实现了秒显示在1秒内亮500ms,灭50ms了。上图中中断函数名后面的interrupt 1这是中断函数的入口地址,C语言中叫中断号(为小白说明,老司机略过),具体的个中断对应的入口地址对照表如下图(部分):
中断号对照表
相关问答
求一个51 单片机 定时闹钟程序。要C语言。能够调时间 - 小红薯...我来发一个C语言211351单片机时钟程序,希望5261能帮到你/*程序功能:4102带定时闹铃时钟*//*-------...
单片机 控制电压输出 可调 的芯片有哪些?降压dcdc,也就是buck吧,用单片机给占空比,然后加个输出采样闭环调节,就能保持输出电压稳定了降压dcdc,也就是buck吧,用单片机给占空比,然后加个输出采样闭环...
STC89C52RC 单片机 的缺点?STC89C52RC比普通89C52多了后缀“RC”,虽然它们都是单片机芯片,但是带有“RC”字样的单片机自带RC时钟振荡电路(有的频率可调有的频率不可调),可以在不接外...
stc15w4k58s4输出 可调 电压stc15w4k58s4是一种单片机芯片,具有输出可调电压的功能。该芯片可以通过外部电路设计和编程控制,实现不同范围的电压输出。这种芯片在电子设备、通信、工业控...
本人新手,使用STC12C5A60S2 单片机 ,希望输出 可调 电压信号0-5V,请教各位高手如何实现,不甚感激?如果只用单片机的话,就用单片机的PWM模式输出对应的占空比。占空比和输出电压是成正比的。这里输出的是脉冲波形,如果要稳定一些需要加滤波器如果只用单片机...
单片机 pwm口怎么定义?分两点讨论:1.PWM脉冲宽度调制(PWM),是英文“PulseWidthModulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有...
求 单片机 控制PWM输出0~10V连续 可调 电压不进0.05程序电路?加低通滤波就可以了搞定如果负载那边输入阻抗很高,所谓低通滤波就可以用最简单的RC电路实现,RC时间常数比PWM周期大几倍就可以了。补充:单片机输出的话,先...
如何运用51 单片机 和mc145162、MC1648产生10MHZ的正弦调谐信号?mc1648压控产生方波就可以,51可控制da控mc1648,通过mc145162倍频,只是产生的是正弦,如果频率不可调可以用有源或者无源做带通既可得到正弦,至于可调就没法mc1...
不带 可调 的开关电源怎么改成输出电压可调的,比如12V改成10-15可调,就像那种自带可调的一样?你要了解开关电源的工作方式,用单片机就要自己做闭环,如果不用单片机,就在反馈那上个可调电阻你要了解开关电源的工作方式,用单片机就要自己做闭环,如果不...
金坛/常州地区找工作?职位名称公司名称工作区域薪酬店长店员导购营业员促销员金坛市某知名品牌管理机构金坛市3000-5000办公室文员月5k工/普工作轻松(常州市)苏州捷...