提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
提示:以下是本篇文章正文内容,下面案例可供参考
一、设计原理
1.DS1302介绍
DS1302 是美国DALLAS公司推出的一种高性能、低功耗、带RAM的实时时钟电路,它可以对年、月、日、周、时、分、秒进行计时,具有闰年补偿功能,工作电压为2.0V~5.5V。该芯片采用普通32.768kHz晶振,DS1302 工作时功耗很低,保持数据和时钟信息时功率小于1mW,非常适合用于制作电子钟。
DS1302芯片管脚和实例电路如图:
DS1302共8个引脚,其中VCC供电口共有两个,VCC1为主供电口,VCC2为备用供电口,备用电源口可以保证DS1302在主供电断电情况下依然可以正常计时,使用过程中仅使用VCC2备用电源作为供电,可保证完整功能。
DS1302需要与单片机交互的接口为,SCLK、I/O、RST三个,与单片机的数据交换使用I/O接口,为串行通信模式。SCLK为串行时钟输入引脚,保证数据同步传输。RST为复位口。
DS1302命令字和对应的操纵如下图:
DS1302向单片机返回的时间日期数值采用压缩BCD码,即用16进制数表示10进制数,比如返回55秒对应的值为0x55,在数据解算时需要按照16进制规则计算。
2.闹钟音乐播放原理
闹钟音乐使用无源蜂鸣器播放,基本原理为通过单片机向无源蜂鸣器输出不同频率的方波信号,无源蜂鸣器则对应播放出不同音调的声音,即播放出不同的音符。通过连续播放不同音符并控制每个音符播放的时间,可以组合成完整的音乐。
单片机输出不同频率的方波使用定时中断实现,首先将每个音符对应的中断计时时间储储存在单片机中,通过在程序中不断改变中断的时间,可以控制单片机输出方波的频率。以此利用无源蜂鸣器播放出音乐。
二、程序设计
程序共包括4个文件,分别为main.c、DS1302.h、ds1302.c、music.h三个部分。其中main.c为主程序文件,主要包括lcd1602显示相关函数、可调时钟日期函数、闹钟函数;DS1302.h为ds1302.c的声明文件,声明ds1302.c中的相关函数;ds1302.c中定义了单片机与DS1302芯片通信的主要函数文件,主要包括命令输入,数据读取和输入;music.h定义了音乐播发函数,用于闹钟调用。
以下为示例代码,完整代码免费分享,见文末。
1.DS1302.h
#ifndef __DS1302_H
#define __DS1302_H
void Write_Ds1302(unsigned char temp); //向DS1302写命令函数
void Write_Ds1302_Byte( unsigned char address,unsigned char dat ); //用户输入的时间日期输入DS1302函数
unsigned char Read_Ds1302_Byte( unsigned char address ); //读取DS1302时间日期函数
#endif
2.ds1302.c
代码如下(示例):
#include <reg52.h>
#include <intrins.h>
//定义引脚
sbit SCK=P2^0;//CLK
sbit SDA=P2^1;//DIO
sbit RST = P2^2;//CE
void Write_Ds1302(unsigned char temp)
{
unsigned char i;
for (i=0;i<8;i++)
{
SCK=0; //开传输
SDA=temp&0x01; //与0x01相与,每次只取temp最后一位发送
temp>>=1; //temp右移位
SCK=1; //该位传输结束
}
}
void Write_Ds1302_Byte( unsigned char address,unsigned char dat )
{
RST=0; _nop_();
SCK=0; _nop_();
RST=1; _nop_();
Write_Ds1302(address); //写入对应寄存器输入地址
Write_Ds1302(dat); //向对应寄存器中输入数据
RST=0;
}
unsigned char Read_Ds1302_Byte ( unsigned char address )
{
unsigned char i,temp=0x00;
RST=0; _nop_();
SCK=0; _nop_();
RST=1; _nop_();
Write_Ds1302(address); //写入对应寄存器读取地址
for (i=0;i<8;i++) //串口读取
{
SCK=0;
temp>>=1; //temp右移位
if(SDA) temp|=0x80; //如果IO口给高电平,temp最高位置1,相当于保存IO的高电平数据
//如果IO口给低电平,temp不操作,保持0,相当于保存IO的低电平数据
SCK=1;
}
RST=0; _nop_();
SCK=0; _nop_();
SCK=1; _nop_();
SDA=0; _nop_();
SDA=1; _nop_();
return (temp); //以char类型返回temp的数据
}
3.music.h
#ifndef __music_H
#define __music_H
#include <reg52.h>
#include <stdio.h>
sbit beep = P2^3;
sbit key1=P1^0;
unsigned char timer0h, timer0l, time;
//设置好高低音对应的频率
code unsigned char high_v[] = {
0xF8, 0xF9, 0xFA, 0xFA, 0xFB, 0xFB, 0xFC,//低音1234567
0xFC, 0xFC, 0xFD, 0xFD, 0xFD, 0xFD, 0xFE,//中音1234567
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF,//高音1234567
};
code unsigned char low_v[] = {
0x8C, 0x56, 0x22, 0x64, 0x04, 0x90, 0x0C,//低音1234567
0x44, 0xAA, 0x08, 0x32, 0x82, 0xC8, 0x06,//中音1234567
0x22, 0x56, 0x84, 0x9A, 0xC0, 0xE4, 0x02,//高音1234567
};
4.main.c
#include<reg52.h>
#include "ds1302.h"
#include "music.h"
typedef unsigned char u8;
typedef unsigned char u16;
sbit lcdrs=P2^6; //定义LCD寄存器选择位。高电平时选择数据位寄存器,低电平时选择指令寄存器
sbit lcdrw=P2^5; //定义LCD读写信号位。高电平时读操作,低电平时写操作。
sbit lcden=P2^7; //定义LCD使能端
sbit k1=P1^0;
sbit k2=P1^1;
sbit k3=P1^2;
sbit sound=P2^3;
void ds1302_init();
void ds1302_read();
void diplay();
void delay(unsigned int x);
void delay_ms(unsigned int n);
void control();
void time_alter();
void alarm_alter();
void lcdwritecmd (unsigned char cmd); //用来给LCD输入指令
void lcdwritedata(unsigned char dat); //用来给LCD输入要显示的数据
void clear();
void lcdinit();
void showstring(unsigned char b[]);
void delay_ms(unsigned int n);
void alarm_sound();
u8 code read_addr[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d};
u8 code write_addr[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};
u8 code number[] = "0123456789:. ";
unsigned char code low[10] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09};
unsigned char code high[10] = {0x00,0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80,0x90};
//01秒02分03时 4日 5月 周6 07年
u8 timer[]={0x00,0x00,0x00,0x04,0x05,0x06,0x07};
//闹钟设置10秒00分00时 音乐2
u8 alarms[]={0x10,0x00,0x00,0x04};
unsigned int choose;
三、电路图
四、运行结果
1.proteus仿真
Lcd1602正确显示时间日期,测试CONTROL、K1、K2按钮,所有功能正常。proteus中使用发光二极管D1代表实际开发版上发声元件,当闹钟开始时,蜂鸣器播放选择的音乐,lcd1602显示“alarm!!!”字样,按下CONTROL自动结束闹钟,回到正常显示,同时闹钟不消除,下次同一时间继续响应闹钟。
时间日期显示:
响应闹钟:
2.开发板实验
将程序下载到开发版,依照上述电路图正确连线,lcd1602正常显示时间日期,闹钟正常响应,蜂鸣器播放设定的音乐。所有现象与proteus仿真一致。
五、总结
编译过程中,因为在程序中定义了大量的变量,使得变量所需存储空间一度超出了单片机允许的128字节data,查询相关资料后可知,对于那些仅在程序中读取而不需要更改的变量,可以使用code、xdata数据类型,保存在单片机的其他储存空间之中,可以很好地解决变量溢出的问题。
注意:在proteus仿真或者开发板实验的时候,如果遇到按键响应过快的问题(即按下一次按键后,单片机判断按键被按下多次),可以尝试更改代码中按键后的延时时间实现。例如下图画红线位置:
六、附件
1.DS.uvproj(Keil项目文件,以下为项目下包括文件)
main.c
ds1302.h
ds1302.c
music.h
2.clock.pdsprj(proteus仿真项目文件)文章来源:https://www.toymoban.com/news/detail-783897.html
下载地址:基于51单片机、DS1302时钟模块的电子闹钟设计.rar文章来源地址https://www.toymoban.com/news/detail-783897.html
到了这里,关于基于51单片机、DS1302时钟模块的电子闹钟设计的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!