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
数据选择或读输入脚, 该引脚有两种工作模式
R/W
读/写输入端. 该管脚也有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 }