STC89C516驱动DS12C887时钟模块
2021/8/21 6:06:06
本文主要是介绍STC89C516驱动DS12C887时钟模块,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
DS12C887
- DS12C887时钟芯片能输出世纪、年、月、日、时、分、秒等时间信息
- 集成电池, 外部掉电时, 时间不会丢失.
- 有12小时和24小时两种模式. 在12小时制模式中, 用AM和PM区分上午和下午
- 时间的存储方式有两种: 一种用二进制数表示, 另一种是用BCD码表示
- 带有128 byte RAM, 其中11 byte用来存储时间信息, 4 byte用来存储DS12C887的控制信息, 称为控制寄存器; 113 byte 通用RAM, 供用户使用. * 可以对DS12C887进行编程, 实现多种方波输出
- 可对其内部的三路中断通过软件进行屏蔽
- 芯片内部有一个精密的温度补偿电路用来监视Vee的状态, 如果检测到主电源故障, 该器件可以自动切换到备用电源供电
- VBAeKUP引脚用于支持可充电电池或超级电容, 内部包括一个始终有效的涓流充电器.
- 可以通过一个多路复用的单字节接口访问, 该接口支持Intel和Motorola模式
引脚功能
GND、 VCC
VCC接+5V输入, 当VCC输入为+5V时, 用户可以访问DS12C887内RAM中的数据, 并可对其进行读写操作. 当VCC的输入小于+4.25V时, 禁止用户对内部RAM进行读写操作, 此时用户不能正确获取芯片内的时间信息. 当VCC的输入小于+3V时, DS12C887会自动将电源发换到内部自带的锂电池上.
MOT
模式选择脚. DA12C887有两种工作模式: Motorola模式和Intel模式, 当MOT接VCC时是Motorola模式, 当MOT接GND时是Intel模式. 一般使用Intel模式.
SQW
方波输出脚. 当供电电压VCC大于4.25V时, SQW脚可进行方波输出, 此时用户可以通过对控制寄存器编程来得到13种方波信号的输出
AD0-AD7
复用地址数据总线, 该总线采用时分复用技术, 在总线周期的前半部分出现在AD0-AD7上的是地址信息, 可用以选通DS12C887内的RAM, 总线周期的后半部分出现在AD0-AD7上的是数据信息.
AS
地址选通输入脚, 在进行读写操作时, AS的上升沿将AD0-AD7上出现的地址信息锁存到DS12C887上, 而下一个下降沿清除AD0-AD7上的地址信息, 不论是否有效, DS12C887都将执行该操作.
DS/RD
数据选择或读输入脚, 该引脚有两种工作模式
- MOT接VCC时, 为Motorola工作模式, 在这种工作模式中, 每个总线周期的后一部分的DS为高电平, 被称为数据选通, 在读操作中, DS的上升沿使DS12C887将内部数据送往总线AD0-AD7上, 以供外部读取, 在写操作中, DS的下降沿将使总线 AD0-AD7上的数据锁存在DS12C887中.
R/W
读/写输入端. 该管脚也有2种工作模式
- 当MOT接VCC时, 工作在Motorola模式, 此时该引脚的作用是区分进行的是读操作还是写操作, 当R/W为高电平时为读操作, R/W 为低电平时为写操作.
- 当MOT接GND时, 工作在Intle模式, 此时该引脚作为写允许输入
STC89C516连接DS12C877
连接
- 操作DS12C887时钟芯片共需要13条信号线, 分别是并行数据地址复用线ADO~AD7, CS, AS, R/W, DS 和 IRQ
- 将RESET引脚固定接高电平
- DS, AS, R/W,CS分别连接单片机的P1.0 - P1.4口, 当然连接其他口也可以, 只要可以正常操作即可
- IRQ是DS12C887的中断申请端, 该引脚不能随便连接, 必须与单片机的外部中断引脚相连, 这样当DS12C887芯片向单片机申请中断时, 单片机才不会遗漏的检测出所有的中断, 这里我们将其与单片机的P3.2相连.
左侧 MOT => GND AD0 => P0.0 ... AD7 => P0.7 GND => GND 右侧 VCC => VCC SQW IRQ => P3.2 RESET => VCC DS => P1.0 RW => P1.1 AS => P1.2 CS => P1.4
USB2TTL连线
TX => P3.0 RX => P3.1
代码
读取时间信息的测试代码
#include <reg52.h> #include <stdio.h> typedef unsigned int u16; typedef unsigned char u8; u8 num,time,moshi,moshi1,flag,kaiqi,c; char shi,fen,miao,shiji,nian,yue,ri,xingqi,ashi,afen,amiao,kaiz; void delay(u16 z) { u16 x,y; for(x=z;x>0;x--) for(y=110;y>0;y--); } sbit dsds_ds12c887 = P1^0; sbit dsrw_ds12c887 = P1^1; sbit dsas_ds12c887 = P1^2; sbit dscs_ds12c887 = P1^4; sbit dsirq_ds12c887 = P3^2; void write_ds_ds12c887(u8 add_ds12c887, u8 data_ds12c887) { delay(1); dscs_ds12c887 = 0; // ds12c887de 使能端 cs=0 delay(1); dsas_ds12c887=1; dsds_ds12c887=1; dsrw_ds12c887=1; delay(1); P0 = add_ds12c887; delay(1); dsas_ds12c887=0; dsrw_ds12c887=0; P0 = data_ds12c887; dsrw_ds12c887=1; dsas_ds12c887=1; delay(1); dscs_ds12c887 = 1; // ds12c887de 使能端 cs=1 delay(1); } u8 read_ds_ds12c887(u8 add_ds12c887) { u8 ds_date; dsas_ds12c887=1; dsds_ds12c887=1; dsrw_ds12c887=1; delay(1); dscs_ds12c887 = 0; // ds12c887de 使能端 cs=0 delay(1); P0 = add_ds12c887; delay(1); dsas_ds12c887=0; dsds_ds12c887=0; P0 = 0XFF; ds_date=P0; dsds_ds12c887=1; dsas_ds12c887=1; dscs_ds12c887 = 1; // ds12c887de 使能端 cs=1 return ds_date; } void init_ds12c887() { write_ds_ds12c887(0x0b,0x26); //如果開啓設置 控制器B, 數據爲BCD碼, 時間爲24小時制, 產生鬧鐘中斷 write_ds_ds12c887(0x0a,0x20); //打開時鐘震盪 amiao=read_ds_ds12c887(1); afen=read_ds_ds12c887(3); ashi=read_ds_ds12c887(5); //讀DS12C887 鬧鐘 時, 分, 秒 即當進入鬧鐘設置狀態下, 顯示當前設定鬧鐘的時間 } void set_alarm_ds12c887(u8 ashi, u8 afen, u8 amiao) { write_ds_ds12c887(1,amiao); write_ds_ds12c887(3,afen); write_ds_ds12c887(5,ashi); //在DS12C887鬧鐘寄存器中寫入 鬧鐘時間 函數 } void main() { P0=0x00; //P0口送清零, 關LED數碼管的必要數據準備. P1=0xff; //P1口送全1, 關8位發光二極管的必要數據準備. init_ds12c887();//ds12c887 初始化 EA=1; IT0=1; EX0=1; // 初始化UART TMOD = 0x20; SCON = 0x40; TH1 = 256 - 11.0592 * 1000 * 1000 / 12 / 32 / 9600 + 0.5; TCON |= 0x40; SCON |= 0x02; // 初始化UART结束 c=read_ds_ds12c887(0x0c); //write_ds_ds12c887(0x0b,0x26);//如果開啓設置 控制器B, 數據爲BCD碼, 時間爲24小時制, 產生鬧鐘中斷 num=0;time=0;moshi=0;moshi1=0;flag=0;kaiqi=0; /* 該部分是調試程序時候使用, 當出現時間日期亂碼時候, 可以嘗試重新寫入給定數據 判斷是否是內部保存數據長時間未用導致出現亂碼. write_ds_ds12c887(4,9); //小時寄存器 寫 9點 write_ds_ds12c887(2,27); //分鐘寄存器 寫 27分 write_ds_ds12c887(0,25); //秒鐘寄存器 寫 25秒 write_ds_ds12c887(6,7); //星期寄存器寫 7 星期天 write_ds_ds12c887(9,11); //年寄存器 寫 11年 write_ds_ds12c887(8,8); //月份寄存器 寫 8月 write_ds_ds12c887(7,7); //日期寄存器 寫 7號 */ while(1) { miao = read_ds_ds12c887(0x00); //讀 秒 fen = read_ds_ds12c887(0x02); //讀 分 shi = read_ds_ds12c887(0x04); //讀 時 ri = read_ds_ds12c887(0x07); //讀 日 yue = read_ds_ds12c887(0x08); //讀 月 nian = read_ds_ds12c887(0x09); //讀 年 xingqi= read_ds_ds12c887(0x06); //讀 星期 shiji = read_ds_ds12c887(0x10); //讀 實際 保存實際數據, 內部不自加, 只是當做存儲器用 kaiz = read_ds_ds12c887(0x0e); //讀 鬧鐘 標誌位 ashi = read_ds_ds12c887(0x05); //讀 鬧鐘 時 afen = read_ds_ds12c887(0x03); //讀 鬧鐘 分 amiao = read_ds_ds12c887(0x01); //讀 鬧鐘 秒 printf("%bu-%bu-%bu\r\n", nian, yue, ri); printf(" %bu:%bu:%bu\r\n", shi, fen, miao); //把讀出的時間, 日期數據, 寫到1602液晶顯示 /*write_twoline_ds12c887_1602(5,shi); //寫 時 write_twoline_ds12c887_1602(8,fen); //寫 分 write_twoline_ds12c887_1602(11,miao); //寫 秒 write_oneline_ds12c887_1602(10,ri); //寫 日 write_oneline_ds12c887_1602(7,yue); //寫 月 write_oneline_ds12c887_1602(4,nian); //寫 年 write_oneline_ds12c887_1602(14,xingqi);//寫 星期 write_oneline_ds12c887_1602(2,shiji); //寫 世紀 write_twoline_ds12c887_1602(2,kaiz); //寫 鬧鐘開啓位 */ } } void exter() interrupt 0 { flag=1; //開外部中斷 0 }
参考
- https://blog.csdn.net/dai_wen/article/details/81050120
- http://www.51hei.com/bbs/dpj-184639-1.html
- https://blog.csdn.net/huang873036652/article/details/91460594
- http://www.51hei.com/bbs/dpj-29544-1.html
- http://news.eeworld.com.cn/mcu/ic466119.html
- c51的printf格式 https://www.keil.com/support/man/docs/c51/c51_printf.htm
这篇关于STC89C516驱动DS12C887时钟模块的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23增量更新怎么做?-icode9专业技术文章分享
- 2024-11-23压缩包加密方案有哪些?-icode9专业技术文章分享
- 2024-11-23用shell怎么写一个开机时自动同步远程仓库的代码?-icode9专业技术文章分享
- 2024-11-23webman可以同步自己的仓库吗?-icode9专业技术文章分享
- 2024-11-23在 Webman 中怎么判断是否有某命令进程正在运行?-icode9专业技术文章分享
- 2024-11-23如何重置new Swiper?-icode9专业技术文章分享
- 2024-11-23oss直传有什么好处?-icode9专业技术文章分享
- 2024-11-23如何将oss直传封装成一个组件在其他页面调用时都可以使用?-icode9专业技术文章分享
- 2024-11-23怎么使用laravel 11在代码里获取路由列表?-icode9专业技术文章分享
- 2024-11-22怎么实现ansible playbook 备份代码中命名包含时间戳功能?-icode9专业技术文章分享