DS1302实时时钟具有能计算2100年之前的秒、分、时、日、日期、星期、月、年的能力,还有闰年调整的能力。

图1:DS1302引脚示意图
其中:
X1、X2:32.768KHz晶振接入引脚。
GND:地。
:复位引脚,低电平有效,操作时高电平。
I/O:数据输入/输出引脚,具有三态功能。
SCLK:串行时钟输入引脚。
Vcc1:工作电源引脚。
Vcc2:备用电源引脚。 接入电池断电时提供1302电源

图2:控制寄存器

图3:日历、时钟寄存器


图4:单字节读写时序

LCD时序图(写命令(RS=L):设置显示坐标,写数据(RS=H))

LCD1602关键性的指令设置
1.清屏指令

功能:<1> 清除液晶显示器,即将 DDRAM 的内容全部填入"空白"的 ASCII
码 20H;
<2> 光标归位,即将光标撤回液晶显示屏的左上方;
<3> 将地址计数器(AC)的值设为 0。

2.进入模式设置指令


功能 : 设定每次定入 1 位数据后光标的移位方向 , 并且设定每次写入的一个字符是否移动。参数设定的情况如下所示:
位名 设置
I/D 0=写入新数据后光标左移 1=写入新数据后光标右移
S 0=写入新数据后显示屏不移动 1=写入新数据后显示屏整体右
移 1 个字符

3:显示开关控制指令

功能:控制显示器开/关、光标显示/关闭以及光标是否闪烁。参数设定的情
况如下:
位名 设置
D 0=显示功能关 1=显示功能开
C 0=无光标 1=有光标
B 0=光标闪烁 1=光标不闪烁

4.功能设定指令

功能:设定数据总线位数、显示的行数及字型。参数设定的情况如下:
位名 设置
DL 0=数据总线为 4 位 1=数据总线为 8 位
N 0=显示 1 行 1=显示 2 行
F 0=5×7 点阵/每字符 1=5×10 点阵/每字符

5:显示字符地址


要显示字符时要先输入显示字符地址,也就是告诉模块在哪里显示字符,例如第二行第一个字符的地址是 40H, 那么是否直接写入 40H 就可以将光标定位
在第二行第一个字符的位置呢?这样不行,因为写入显示地址时要求最高位 D7
恒定为高电平 1 所以实际写入的数据应该是 01000000B(40H)
+10000000B(80H)=11000000B(C0H)。在 1602 中我们就用前 16 个就行了。第二行也一样用前 16 个地址。

/*实验效果       :1602显示时钟,按K3进入时钟设置,按K1选择设置的时分秒日月,按K2选择
选择设置加1。
*/
#include <reg52.h>
#include <intrins.h>
#define lcd1602data P0typedef unsigned char u8;
typedef unsigned int u16;sbit E=P2^7;       //设置液晶端口      使能信号
sbit RW=P2^5;         //读写选择  读:H/写:L
sbit RS=P2^6;         //数据命令选择  数据:H/命令:Lsbit  key1=P3^1;
sbit  key2=P3^0;
sbit  key3=P3^2;sbit SCLK=P3^6;           //设置时钟端口
sbit IO=P3^4;
sbit RST=P3^5;  u16 read[]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};       //设置秒分时日月周年读寄存器
u16 write[]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};          //设置秒分时日月周年写寄存器
u8 time[]={0x30,0x30,0x22,0x08,0x02,0x05,0x19};             //存放初始时间u16 setmark,setplace;                   //setmark检测key3是否按下,setplace选择要调整的时间块。void delay_ms(u16 n);
void initConfiguration();
void lcdDisplay();
void lcdwrite_com(u8 datas);
void lcdwrite_datas(u8 datas);
void lcdinit();
void writebyte(u8 address,u8 datas);
u8 readbyte(u8 address);
void ds1302init();
void read_time();void main()
{u16 i;initConfiguration();         //初始化lcdinit();ds1302init();while(1){if(setmark==0)               //时钟正常运作{read_time();   }else                               //调整时间{if(key1==0){delay_ms(1);if(key1==0){setplace++;                    //按下key1要调整的时间块加一setplace%=7;}while(i<50&&key1==0)                //等待key1松开{i++;delay_ms(10);}i=0;}if(key2==0){delay_ms(1);if(key2==0)                                //按下key2对应的初始时间加一{time[setplace]++;if((time[setplace]&0x0f)>9)                  //换成BCD码。{time[setplace]=time[setplace]+6;}if((time[setplace]>=0x60)&&(setplace<2))       //分秒只能到59{time[setplace]=0;}if((time[setplace]>=0x24)&&(setplace==2))        //小时只能到23{time[setplace]=0;}if((time[setplace]>=0x32)&&(setplace==3))        //日只能到31{time[setplace]=0; }if((time[setplace]>=0x13)&&(setplace==4))        //月只能到12{time[setplace]=0;}    if((time[setplace]>=0x7)&&(setplace==5))      //周只能到7{time[setplace]=1;}}while((i<50)&&(0==key2)){i++;delay_ms(10);}i=0;}}lcdDisplay();}
}void delay_ms(u16 n)            //准确延时一毫秒,晶振12M
{u16 a,b;for(;n>0;n--){for(a=199;a>0;a--){for(b=1;b>0;b--){;}}}
}void initConfiguration()    //初始化外部中断0
{EA=1;IT0=1;EX0=1;
}void init0() interrupt 0       //按下key3时间保持不变
{delay_ms(10);if(key3==0){setmark=~setmark;setplace=0;ds1302init();}
}void lcdDisplay()                //显示函数
{lcdwrite_com(0x80+0x00);              //确定写数据的位置lcdwrite_datas('2');lcdwrite_datas('0');lcdwrite_datas('0'+time[6]/16);                //写入年份的高位lcdwrite_datas('0'+(time[6]&0x0f));     //低位lcdwrite_datas('-');lcdwrite_datas('0'+time[4]/16);lcdwrite_datas('0'+(time[4]&0x0f));   //里面的小括号很重要lcdwrite_datas('-');      lcdwrite_datas('0'+time[3]/16);lcdwrite_datas('0'+(time[3]&0x0f));lcdwrite_com(0x8c);lcdwrite_datas('0'+(time[5]&0x07));lcdwrite_com(0xc0);                          //跳线帽Joe接vcclcdwrite_datas('0'+time[2]/16);lcdwrite_datas('0'+(time[2]&0x0f));lcdwrite_datas('-');lcdwrite_datas('0'+time[1]/16);lcdwrite_datas('0'+(time[1]&0x0f));lcdwrite_datas('-');lcdwrite_datas('0'+time[0]/16);             lcdwrite_datas('0'+(time[0]&0x0f));
}void lcdwrite_com(u8 datas)             //lcd液晶写入指令操作        模拟时序
{E=0;RW=0;RS=0;lcd1602data=datas;delay_ms(1);E=1;//delay_ms(1);E=0;}void lcdwrite_datas(u8 datas)      //lcd液晶写入数据操作
{E=0;RW=0;RS=1;lcd1602data=datas;delay_ms(1);                  //延时不能太长否则调整不灵敏E=1;//delay_ms(1);E=0;}void lcdinit()                        //LCD液晶初始化
{lcdwrite_com(0x38);            //8位总线,显示两行,5x7点阵lcdwrite_com(0x0c);              //开显示功能,无关标lcdwrite_com(0x06);               //光标右移,即数据依次右移lcdwrite_com(0x01);                //清屏lcdwrite_com(0x80);             //第一个数据位置
}void writebyte(u8 address,u8 datas)              //在寄存器里写时间数据,模拟时序
{u8 i;RST=0;_nop_();SCLK=0;_nop_();RST=1;_nop_();for(i=0;i<8;i++){IO=address&0x01;address>>=1;SCLK=1;_nop_();SCLK=0;_nop_(); }for(i=0;i<8;i++){IO=datas&0x01;datas>>=1;SCLK=1;_nop_();SCLK=0;_nop_();    }RST=0;
}u8 readbyte(u8 address)              //读寄存器里的时间数据
{u8 i,datas,dat;RST=0;//_nop_();SCLK=0;//_nop_();RST=1;//_nop_();for(i=0;i<8;i++){IO=address&0x01;address>>=1;SCLK=1;_nop_();SCLK=0;_nop_(); }//_nop_();for(i=0;i<8;i++){dat=IO;datas=(datas>>1)|(dat<<7);SCLK=1;_nop_();SCLK=0;_nop_();}RST=0;//_nop_();SCLK=1;//_nop_();IO=0;//_nop_();IO=1;//_nop_();return datas;
}void ds1302init()                   //在寄存器里写入初始时间
{u8 i;writebyte(0x8e,0x00);          //关闭写保护寄存器for(i=0;i<7;i++){writebyte(write[i],time[i]);}writebyte(0x8e,0x80);                 //打开写保护寄存器
}void read_time()                     //读取时钟时间    time数组存储
{u8 i;for(i=0;i<7;i++){time[i]=readbyte(read[i]);}
}

以上是我在学习过程中的一点总结,用的是普中的51单片机·。

51单片机DS1302时钟LCD1602显示(可以按键设置时钟)相关推荐

  1. 51单片机ADC0832模数转换+ LCD1602显示+Proteus仿真

    51单片机ADC0832模数转换+ LCD1602显示+Proteus仿真 Proteus仿真 在Proteus SP2仿真过程中发现无法读取ADC0832的数据.解决办法:在proteus安装目录下 ...

  2. 4. 51 测量空气的温度和湿度(51单片机 + DHT11温湿度 + LCD1602显示)

    51单片机 + DHT11温湿度 + LCD1602显示 DHT11温湿度相关介绍 DHT11产品概述 测量范围 接口说明 电源引脚 串行接口 (单线双向) 相关时序及代码 用代码实现上述时序图(起始 ...

  3. 51单片机矩阵键盘——LCD1602显示

    1.前言 本次的实验需要用到LCD1602液晶屏,需要用到LCD1602.c 与LCD1602.h文件链接: https://download.csdn.net/download/YLG_lin/86 ...

  4. 基于51单片机+DHT11温湿度+LCD1602显示

    DHT温湿度1602显示 DHT11温湿度相关介绍 DHT11产品概述 1.测量范围 2.接口说明 3.电源引脚 4.串行接口 (单线双向) 5.相关时序及代码 6. DHT11引脚说明 程序代码 m ...

  5. 【Proteus仿真】51单片机+DS1302+lcd1602显示

    [Proteus仿真]51单片机+DS1302+lcd1602显示 Proteus仿真 工程架构 项目工程 文件结构 主程序代码 #include <reg52.h> #include & ...

  6. 51单片机+ds1302+lcd1602简易电子时钟(带闹钟功能)

    51单片机+ds1302+lcd1602简易电子时钟(带闹钟功能) AT89C52.LCD1602.DS1302.speaker. Proteus仿真 实例代码 #include<reg52.H ...

  7. 51单片机七段数码管显示时钟无按键控制—①—74HC595版

    参考链接: 51单片机七段数码管显示时钟加按键控制-③-74HC595版 51单片机七段数码管显示时钟加按键控制-②-74HC595版 文章目录 一.实验内容: 二.实验分析: 三.仿真图: 四.源代 ...

  8. 基于51单片机ds1302时钟、ds18b20、lcd12864的恒温器

    目录 项目:基于51单片机ds1302时钟.ds18b20的恒温器 功能说明: 运行流程: 效果展示: 供电方式: 用途: 提高: 附: ​                              ...

  9. 51单片机DS1302数字时钟

    51单片机DS1302数字时钟 #include <reg52.h> #define uchar unsigned char #define uint unsigned intsbit R ...

  10. 95、基于51单片机智能闹钟万年历 农历阳历温度电子时钟闹钟定时语音播报系统

    毕设帮助.开题指导.技术解答(有偿)见文末. 目录 摘要 一.硬件方案 二.设计功能 三.实物图 四.原理图 五.pcb图 六.Protues仿真 七.程序 八.资料包括 摘要 本文介绍了基于STC8 ...

最新文章

  1. explain 之 table || explain 之 type
  2. 图文详解 Kubernetes,刺激…
  3. Windows下用cmd命令安装及卸载服务[转]
  4. 为什么开不了4g网络_为什么4G网络越来越慢?究竟是你手机出了问题还是网络原因?...
  5. java调用接口失败重调_java 接口调用问题
  6. ASP如何限定中英文混合的文字输出字数?
  7. Eclipse Pydev 技巧汇编
  8. 设计素材 | 来一份秋高气爽——秋季促销海报
  9. leetcode python3 简单题125. Valid Palindrome
  10. sql server的增删改查语句
  11. android 小米相机权限,小米如何设置访问相机权限设置
  12. pytorch 模型输出特征 保存npy
  13. linux怎么查看hwaddr_linux下如何查看某个网卡当前使用的IP
  14. Neural Turing Machines-NTM系列
  15. Selenium 入门篇
  16. Office 2010 安装程序包的语言不受系统支持
  17. List1_Excise
  18. Python-OpenCV 的 remap函数
  19. 【产品】建立二八法则思维模式:精准定位
  20. CTFshow--常用姿势

热门文章

  1. c语言佛像怎么打,几种造像的方法、寺院殿堂佛像释名
  2. [Python] 读取 rar/zip 压缩文件
  3. 通讯rs232c语言编程,基于C51的RS232基本通信程序
  4. AUTOCAD 常用操作
  5. 成功解决TypeError: ‘float‘ object cannot be interpreted as an integer
  6. Python CheatSheet
  7. 您备案的网站未指向阿里云国内节点(不含香港)服务器,备案号可能被取消接入
  8. 常见的几种电脑蓝屏故障分析及处理办法
  9. MATLAB永磁同步电机电角度,永磁同步电动机矢量控制
  10. 四级英语听力软件测试,英语四级听力分值一题多少分