本设计的主要任务是计时和显示。

设计任务的具体要求如下:

  1. 计时:第一种是通过单片机内部的定时器/计数器来实现为软时钟。第二种是通过专用的硬件时钟芯片来实现为硬时钟。
  2. 显示:第一种是数码管显示,分为静态显示和动态显示,动态显示需要占用cpu大量时间来运行,不需要复杂的驱动程序,制作成本不高。第二种是LCD1602液晶显示,能显示出较多的信息并且数字清晰,应用广泛,但是不便于观察。

总设计思路阐述

1.时钟方案设计及选择:目前有DS3231、DS302、DS12C887三种时钟芯片。本次设计选择DS3231,

需要应用IC总线协议。

2.核心控制区设计方案:选用STC89C51作为核心控制单元。

3.显示原件:采用LCD1602液晶显示。

4.键盘设置:设计为时、分、秒的调整按键。

5.控制继电器:选择5V/1A继电器,驱动LCD液晶显示。

6.外围电路:复位电路,晶振。

7.时钟时序问题

代码如下:

/*******************************************************************************
实验名 :高精度时钟显示和控制
使用的IO  : P3^0  SDAP3^1  SCL
实验效果:1602 显示时钟,按S4进入时钟设置并暂停时钟,按S1选择时钟设置的时分秒日月周年,按S3使时间加一
*******************************************************************************/#include<reg51.h>
#include"lcd.h"
#include"ds3231.h"sbit K1=P3^5;//按键IO口定义
sbit K2=P3^4;
sbit K3=P3^3;
sbit K4=P3^2;void Int0Configuration();//外部中断初始化函数声明
void LcdDisplay();//LCD初始化函数声明
unsigned char SetState,SetPlace;
void Delay10ms(void);   //10ms延迟函数
/*******************************************************************************
* 函数名          : main
* 函数功能        : 主函数
* 输入            : 无
* 输出            : 无
*******************************************************************************/void main()
{unsigned char i;Int0Configuration();//外部中断初始化LcdInit();//LCD初始化DS3231_Init();//DS3231模块初始化while(1){    if(SetState==0)//标志位为0时读取时间{DS3231_Read_time(); }else{if(K1==0)     //检测按键K1是否按下{Delay10ms();   //消除抖动if(K1==0){while(!K1);//检测是否松手SetPlace++;if(SetPlace>=7)SetPlace=0;                   }}if(K2==0)       //检测按键K2是否按下{Delay10ms();   //消除抖动if(K2==0){while(!K2);//松手检测TIME[SetPlace]++;if((TIME[SetPlace]>=60)&&(SetPlace<2))     //分秒只能到60{TIME[SetPlace]=0;}if((TIME[SetPlace]>=24)&&(SetPlace==2))      //小时只能到23{TIME[SetPlace]=0;}if((TIME[SetPlace]>=32)&&(SetPlace==3))      //日只能到31{TIME[SetPlace]=0; }if((TIME[SetPlace]>=13)&&(SetPlace==4))      //月只能到12{TIME[SetPlace]=0;}    if((TIME[SetPlace]>=8)&&(SetPlace==5))        //周只能到7{TIME[SetPlace]=1;}     }while((i<50)&&(K2==0))     //检测按键是否松开{Delay10ms();i++;}i=0;}                       }LcdDisplay();  //LCD显示函数}}
/*******************************************************************************
* 函数名         : LcdDisplay()
* 函数功能       : 显示函数
* 输入            : 无
* 输出            : 无
*******************************************************************************/void LcdDisplay()
{LcdWriteCom(0x80+0X40);LcdWriteData('0'+TIME[2]/10);               //时LcdWriteData('0'+(TIME[2]%10));                LcdWriteData('-');LcdWriteData('0'+TIME[1]/10);               //分LcdWriteData('0'+(TIME[1]%10));   LcdWriteData('-');LcdWriteData('0'+TIME[0]/10);                //秒LcdWriteData('0'+(TIME[0]%10));LcdWriteCom(0x80);LcdWriteData('2');LcdWriteData('0');LcdWriteData('0'+TIME[6]/10);         //年LcdWriteData('0'+(TIME[6]%10));LcdWriteData('-');LcdWriteData('0'+TIME[4]/10);           //月LcdWriteData('0'+(TIME[4]%10));LcdWriteData('-');LcdWriteData('0'+TIME[3]/10);           //日LcdWriteData('0'+(TIME[3]%10));LcdWriteCom(0x8D);LcdWriteData('0'+(TIME[5]%10));   //星期
}
/*******************************************************************************
* 函数名         : Int0Configuration()
* 函数功能       : 配置外部中断0
* 输入            : 无
* 输出            : 无
*******************************************************************************/void Int0Configuration()
{//设置INIT0IT0=1;//跳边沿触发方式(下降沿)EX0=1;//打开INT0中断允许EA=1;//    打开总中断
}
/*******************************************************************************
* 函数名         : Int0()
* 函数功能       : 外部中断0中断服务函数
* 输入            : 无
* 输出            : 无
*******************************************************************************/void Int0() interrupt 0 using 1
{Delay10ms();if(K4==0){while(!K4);//松手检测SetState=~SetState;//标志位取反SetPlace=0;DS3231_Init();//DS3231初始化}
}
/*******************************************************************************
* 函数名         : Delay10ms()
* 函数功能       : 延迟函数,延时10ms
* 输入            : 无
* 输出            : 无
*******************************************************************************/
void Delay10ms(void)   //Îó²î 0us
{unsigned char a,b,c;for(c=1;c>0;c--)for(b=38;b>0;b--)for(a=130;a>0;a--);
}
/********************************************************************************************************************************************************************/
#ifndef __DS3231_H_
#define __DS3231_H_//---包含头文件---//
#include<reg51.h>
#include<intrins.h>//---重定义关键词---//
#ifndef uchar
#define uchar unsigned char
#endif#ifndef uint
#define uint unsigned int
#endif//---定义ds1302使用的IO口---//
sbit DS3231_IIC_SDA=P3^0;
sbit DS3231_IIC_SCL=P3^1;//---定义全局函数---//                                                               //时基、走时函数
void DS3231_Read_time();                                                 //读取时间
void DS3231_write_time();                                                 //写入时间
void DS3231_Init();                                                                 //时间模块初始化//---加入全局变量--//
extern uchar TIME[7];   //加入全局变量#endif
/********************************************************************************************************************************************************************/
#include"ds3231.h"//---DS3231写入和读取时分秒的地址命令//
//---秒分时日月周年最低读写位;-------//
uchar code READ_RTC_ADDR[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d};
uchar code WRITE_RTC_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};
uchar code rtc_address[7]={0x00,0x01,0x02,0x04,0x05,0x03,0x06};//秒分时日月周年最低读写位
uchar RTC_Data[8];
uchar RTC_Data1[8];
uchar RTC_Set_ID;
bit T0_Flag;
bit Open_Flag;
bit shezhi_display_flag;
//---DS3231初始化时间格式为2021年6月28日星期一22点00分00秒---//
//---存储顺序是秒分时日月周年,存储格式是用BCD码---//
uchar TIME[7] = {0, 0, 0x22, 0x28, 0x06, 0x01, 0x21};/*******************************************************************************
* 函数名         : Ds3231Write
* 函数功能       : 向DS3231命令(地址+数据)
* 输入            : addr,dat
* 输出            : 无
*******************************************************************************/void DS3231_IIC_delay()//IIC延迟函数
{_nop_();_nop_();_nop_();_nop_();
}void DS3231_IIC_start()//起始信号
{   DS3231_IIC_SDA=1;DS3231_IIC_SCL=1;DS3231_IIC_delay();DS3231_IIC_SDA=0;DS3231_IIC_delay();DS3231_IIC_SCL=0;
}void DS3231_IIC_stop()//停止信号
{DS3231_IIC_SDA=0;DS3231_IIC_delay();DS3231_IIC_SCL=1;DS3231_IIC_delay();DS3231_IIC_SDA=1;DS3231_IIC_delay();
}bit DS3231_IIC_Tack()//接收应答
{bit ack;DS3231_IIC_SDA=1;DS3231_IIC_delay();DS3231_IIC_SCL=1;DS3231_IIC_delay();ack=DS3231_IIC_SDA;DS3231_IIC_delay();DS3231_IIC_SCL=0;DS3231_IIC_delay();return ack;
}void DS3231_IIC_write_byte(uchar Data)//写入数据函数
{uchar i;for(i=0;i<8;i++){if(Data&0x80)DS3231_IIC_SDA=1;elseDS3231_IIC_SDA = 0;DS3231_IIC_delay();DS3231_IIC_SCL=1;DS3231_IIC_delay();DS3231_IIC_SCL=0;DS3231_IIC_delay();Data=Data<<1;}
}uchar DS3231_IIC_read_byte()//读取数字函数
{uchar i;uchar Data;      for(i=0;i<8;i++){DS3231_IIC_SCL=1;DS3231_IIC_delay();Data=Data<<1;DS3231_IIC_delay();if(DS3231_IIC_SDA)Data=Data|0x01;DS3231_IIC_SCL=0;DS3231_IIC_delay();}return Data;
}void DS3231_IIC_single_byte_write(uchar Waddr,uchar Data)//写入数据函数
{DS3231_IIC_start();DS3231_IIC_write_byte(0xd0);DS3231_IIC_Tack();DS3231_IIC_write_byte(Waddr);DS3231_IIC_Tack();DS3231_IIC_write_byte(Data);DS3231_IIC_Tack();DS3231_IIC_stop();
}uchar DS3231_IIC_single_byte_read(uchar Waddr)//读取数字函数
{uchar Data;DS3231_IIC_start();DS3231_IIC_write_byte(0xd0);DS3231_IIC_Tack();DS3231_IIC_write_byte(Waddr);DS3231_IIC_Tack();DS3231_IIC_stop();DS3231_IIC_start();DS3231_IIC_write_byte(0xd1);DS3231_IIC_Tack();Data=DS3231_IIC_read_byte();DS3231_IIC_delay();DS3231_IIC_stop();return Data;
}void DS3231_Read_time()//读取时间
{uchar i,tmp,tmp1,tmp2;         for(i=0;i<7;i++){tmp = DS3231_IIC_single_byte_read(rtc_address[i]);tmp1 = tmp/16;tmp2 = tmp%16;TIME[i]=tmp1*10+tmp2;}
}void DS3231_write_time()//写入时间
{uchar i,tmp;for(i=0;i<8;i++){      tmp=RTC_Data[i]/10;//BCD??RTC_Data1[i]=RTC_Data[i]%10;RTC_Data1[i]=RTC_Data1[i]+tmp*16;}for(i=0;i<7;i++){DS3231_IIC_single_byte_write(rtc_address[i],RTC_Data1[i]);}DS3231_IIC_single_byte_write(0x0e,0x0c);
}void DS3231_Init()//DS3231初始化函数
{uchar n;DS3231_IIC_SDA=1;DS3231_IIC_SCL=1;DS3231_IIC_single_byte_write(0x0e,0x0c);for (n=0; n<7; n++)//дÈë7¸ö×Ö½ÚµÄʱÖÓÐźţº·ÖÃëʱÈÕÔÂÖÜÄê{DS3231_IIC_single_byte_write(rtc_address[n],TIME[n]); }DS3231_IIC_single_byte_write(0x8E,0x80);        //´ò¿ªÐ´±£»¤¹¦ÄÜ
}
/********************************************************************************************************************************************************************/
#ifndef __LCD_H_
#define __LCD_H_
/**********************************
当使用的是4位数据传输的时候定义,
使用8位取消这个定义
**********************************/
//#define LCD1602_4PINS/**********************************
包含头文件
**********************************/
#include<reg51.h>//---重定义关键词---//
#ifndef uchar
#define uchar unsigned char
#endif#ifndef uint
#define uint unsigned int
#endif/**********************************
PIN口定义
**********************************/
#define LCD1602_DATAPINS P2
sbit LCD1602_E=P0^5;
sbit LCD1602_RW=P0^6;
sbit LCD1602_RS=P0^7;/**********************************
函数声明
**********************************/
/*在51单片机12MHZ时钟下的延时函数*/
void Lcd1602_Delay1ms(uint c);   //误差 0us
/*LCD1602写入8位命令子函数*/
void LcdWriteCom(uchar com);
/*LCD1602写入8位数据子函数*/
void LcdWriteData(uchar dat)    ;
/*LCD1602初始化子程序*/
void LcdInit();                       #endif
/********************************************************************************************************************************************************************/
#include"lcd.h"/*******************************************************************************
* 函 数 名         : Lcd1602_Delay1ms
* 函数功能         : 延时函数,延时1ms
* 输    入         : c
* 输    出         : 无
* 说    名         : 该函数是在12MHZ晶振下,12分频单片机的延时。
*******************************************************************************/void Lcd1602_Delay1ms(uint c)   //误差 0us
{uchar a,b;for (; c>0; c--){for (b=199;b>0;b--){for(a=1;a>0;a--);}      }}/*******************************************************************************
* 函 数 名         : LcdWriteCom
* 函数功能         : 向LCD写入一个字节的命令
* 输    入         : com
* 输    出         : 无
*******************************************************************************/
#ifndef     LCD1602_4PINS    //当没有定义这个LCD1602_4PINS时
void LcdWriteCom(uchar com)   //写入命令
{LCD1602_E = 0;     //使能LCD1602_RS = 0;      //选择发送命令LCD1602_RW = 0;    //选择写入LCD1602_DATAPINS = com;     //放入命令Lcd1602_Delay1ms(1);        //等待数据稳定LCD1602_E = 1;           //写入时序Lcd1602_Delay1ms(5);      //保持时间LCD1602_E = 0;
}
#else
void LcdWriteCom(uchar com)   //写入命令
{LCD1602_E = 0;     //使能清零LCD1602_RS = 0;  //选择写入命令LCD1602_RW = 0;    //选择写入LCD1602_DATAPINS = com; //由于4位的接线是接到P0口的高四位,所以传送高四位不用改Lcd1602_Delay1ms(1);LCD1602_E = 1;     //写入时序Lcd1602_Delay1ms(5);LCD1602_E = 0;//    Lcd1602_Delay1ms(1);LCD1602_DATAPINS = com << 4; //发送低四位Lcd1602_Delay1ms(1);LCD1602_E = 1;   //写入时序Lcd1602_Delay1ms(5);LCD1602_E = 0;
}
#endif
/*******************************************************************************
* 函 数 名         : LcdWriteData
* 函数功能         : 向LCD写入一个字节的数据
* 输    入         : dat
* 输    出         : 无
*******************************************************************************/
#ifndef     LCD1602_4PINS
void LcdWriteData(uchar dat)            //写入数据
{LCD1602_E = 0;    //使能清零LCD1602_RS = 1;  //选择输入数据LCD1602_RW = 0;    //选择写入LCD1602_DATAPINS = dat; //写入数据Lcd1602_Delay1ms(1);LCD1602_E = 1;   //写入时序Lcd1602_Delay1ms(5);   //保持时间LCD1602_E = 0;
}
#else
void LcdWriteData(uchar dat)            //写入数据
{LCD1602_E = 0;      //使能清零LCD1602_RS = 1;      //选择写入数据LCD1602_RW = 0;    //选择写入LCD1602_DATAPINS = dat;    //由于4位的接线是接到P0口的高四位,所以传送高四位不用改Lcd1602_Delay1ms(1);LCD1602_E = 1;      //写入时序Lcd1602_Delay1ms(5);LCD1602_E = 0;LCD1602_DATAPINS = dat << 4; //写入低四位Lcd1602_Delay1ms(1);LCD1602_E = 1;     //写入时序Lcd1602_Delay1ms(5);LCD1602_E = 0;
}
#endif
/*******************************************************************************
* 函 数 名       : LcdInit()
* 函数功能       : 初始化LCD屏
* 输    入       : 无
* 输    出       : 无
*******************************************************************************/
#ifndef     LCD1602_4PINS
void LcdInit()                        //LCD初始化子程序
{LcdWriteCom(0x38);  //开显示LcdWriteCom(0x0c);  //开显示不显示光标LcdWriteCom(0x06);  //写一个指针加1LcdWriteCom(0x01);  //清屏LcdWriteCom(0x80);  //设置数据指针起点
}
#else
void LcdInit()                        //LCD初始化子程序
{LcdWriteCom(0x32);  //将8位总线转为4位总线LcdWriteCom(0x28);     //在四位线下的初始化LcdWriteCom(0x0c);  //开显示不显示光标LcdWriteCom(0x06);  //写一个指针加1LcdWriteCom(0x01);  //清屏LcdWriteCom(0x80);  //设置数据指针起点
}
#endif

效果如下:

DS3231高精度时钟,LCD1602显示,QXmini151版本相关推荐

  1. Arduino开发实例-DS3231实时时钟+LCD显示

    DS3231实时时钟+LCD显示 1.DS3231介绍 DS3231是低成本.高精度I2C实时时钟(RTC),具有集成的温补晶振(TCXO)和晶体.该器件包含电池输入端,断开主电源时仍可保持精确的计时 ...

  2. 51单片机DS1302时钟LCD1602显示(可以按键设置时钟)

    DS1302实时时钟具有能计算2100年之前的秒.分.时.日.日期.星期.月.年的能力,还有闰年调整的能力. 图1:DS1302引脚示意图 其中: X1.X2:32.768KHz晶振接入引脚. GND ...

  3. 51单片机定时器电子时钟 LCD1602显示时间日期带闹钟功能

    首先直接附上我的文件(懒得在csdn二次编辑了),里面说明文档,和电路图,protues仿真程序,keil程序.https://pan.baidu.com/s/1TC4AxBZJZ8d1Cv-X_dt ...

  4. Arduino UNO DS3231高精度RTC芯片 制作时钟

    DS3231 模块 是一个时钟模块,上面包含一个纽扣电池位置,可以在主机断电的情况下还可以继续计算时间,以便以后记录使用. 模块参数:   1.尺寸:38mm(长)*22mm(宽)*14mm(高)   ...

  5. STC8H开发(十三): I2C驱动DS3231高精度实时时钟芯片

    目录 STC8H开发(一): 在Keil5中配置和使用FwLib_STC8封装库(图文详解) STC8H开发(二): 在Linux VSCode中配置和使用FwLib_STC8封装库(图文详解) ST ...

  6. 8266+DS3231时钟之显示TM1638的使用【四】下

    这个时钟系列目前五篇分别是: <8266+DS3231时钟之开发个时钟遇到的N个坑[一]> <8266+ds3231时钟之arduino官网发布的DS3231库的分析[二]> ...

  7. 8266+DS3231时钟之显示TM1638的使用【四】上

    今天继续8266+DS3231时钟项目的显示部分功能的详解. 这个时钟系列目前五篇分别是: <8266+DS3231时钟之开发个时钟遇到的N个坑[一]> <8266+ds3231时钟 ...

  8. DIY一块DS3231的高精度时钟模块,让时钟DS3231/DS1302自动识别

    [DIY]DIY一块DS3231的高精度时钟模块,让时钟DS3231/DS1302自动识别 水晶城堡在设计之初,采用全直插设计理念,保证玩家在自行DIY的过程中,不会因为焊接贴片元器件而烦恼.所以水晶 ...

  9. 单片机+DHT11的温湿度采集监测系统,LCD1602显示,带报警功能,C代码、原理图和Proteus仿真

    设计要求 1.设计一个基于51单片机和DHT11传感器的温湿度监测系统: 2.传感器DHT11实现对环境温湿度参数的准确测量,单片机对数据进行分析和处理: 3.用户可根据需要,通过按键自主调节温湿度上 ...

最新文章

  1. 四个月没返校,挂在宿舍的内裤变“鸟窝”,网友:画面太美,不敢面对
  2. 【算法笔记】一步一步推出来的同余最短路优化思路(千字长文,超详细)
  3. python3中的单例模式Singleton
  4. MATLAB句柄相关函数和代码示例(设置美化图表属性)
  5. 操作系统习题6—存储管理2
  6. HDU - 1054 Strategic Game(最小点覆盖-二分图最大匹配)
  7. 过程重要,还是结果重要?
  8. 国产数据库存储引擎X-Engine的科研之路
  9. 函数式编程 -- 函数组合
  10. python scipy.stats.norm.cdf_Python stats.norm方法代码示例
  11. Linux 信号详解五(信号阻塞,信号未决)
  12. IHttphandler之“验证码”服务器控件
  13. maria安装包mysql_mariadb安装
  14. 罗云彬:实现水波特效的代码例子
  15. Java面试题总结-2022版
  16. hyu 1698 Just a Hook
  17. 禁止百度,神马,搜狗等搜索引擎转码
  18. 多语言多用户商城系统 中英文电商系统困境及解决思路
  19. Exchange 2003升级到Exchange 2010 之启用Outlook Anywhere!
  20. h5平台腾讯定位地图应用key申请的方法

热门文章

  1. 英语歌曲开启九月之旅
  2. [18考研]如何选择研究生导师?
  3. Excel_通过VBA高亮选择单元格的行列
  4. java过滤器怎么写_java过滤器怎么写
  5. 程序员为什么要多读源码?
  6. eclipse技巧 [摘]
  7. Oracle和Java数据类型对应关系
  8. 用Python比较图片的不同
  9. python linspace函数_numpy中linspace用法
  10. python drf_drf,_Python教程 | 登博教程