1. 采用外部RAM的方式读写
2. 采用INTEL总线时序要求的方式读写
用的AT89S52都进行了测试,都可用,在此分享下
DS12C887.c
#include <reg52.h>
#include <absacc.h>
#include "DS12C887.h"
#if READ_WRITE_WITH_EXTERNAL_RAM
/*
采用外部RAM的方式读写
AT89S52 read time successfully
DS12C887 接法为
GND - MOT - 1 24 - VCC - +5V
N.C.- 2 23 - SQW
N.C.- 3 22 - N.C.
P0.0 - AD0 - 4 21 - N.C.
P0.1 - AD1 - 5 20 - N.C.
P0.2 - AD2 - 6 19 - /IRQ
P0.3 - AD3 - 7 18 - /RESET - +5V
P0.4 - AD4 - 8 17 - DS - RD(P3.7)
P0.5 - AD5 - 9 16 - N.C.
P0.6 - AD6 - 10 15 - R/W - WR(P3.6)
P0.7 - AD7 - 11 14 - AS - ALE
GND - GND - 12 13 - /CS - GND
*/
unsigned char time[6] = {18,5,23,15,17,0};
void SetupDs12c887(void)
{
REGISTERA = 0x70;
REGISTERB = 0xa2;
TIME_YEAR = NUM2BCD(time[0]);
TIME_MONTH = NUM2BCD(time[1]);
TIME_DATE = NUM2BCD(time[2]);
TIME_HOUR = NUM2BCD(time[3]);
TIME_MINUTE = NUM2BCD(time[4]);
TIME_SECOND = NUM2BCD(time[5]);
//计时开始
REGISTERA = 0x20;
REGISTERB = 0x22;
}
void ReadDs12c887(void)
{
time[0] = BCD2NUM(TIME_YEAR);
time[1] = BCD2NUM(TIME_MONTH);
time[2] = BCD2NUM(TIME_DATE);
time[3] = BCD2NUM(TIME_HOUR);
time[4] = BCD2NUM(TIME_MINUTE);
time[5] = BCD2NUM(TIME_SECOND);
}
#else
/*
采用INTEL总线时序要求的方式读写
AT89S52 read time successfully
DS12C887 接法为
GND - MOT - 1 24 - VCC - +5V
N.C.- 2 23 - SQW
N.C.- 3 22 - N.C.
P0.0 - AD0 - 4 21 - N.C.
P0.1 - AD1 - 5 20 - N.C.
P0.2 - AD2 - 6 19 - /IRQ
P0.3 - AD3 - 7 18 - /RESET - P2.7
P0.4 - AD4 - 8 17 - DS - P2.6
P0.5 - AD5 - 9 16 - N.C.
P0.6 - AD6 - 10 15 - R/W - P2.5
P0.7 - AD7 - 11 14 - AS - P2.4
GND - GND - 12 13 - /CS - P2.3
*/
sbit RESET = P2^7;
sbit DS = P2^6;
sbit RW = P2^5;
sbit AS = P2^4;
sbit CS = P2^3;
unsigned char time[6] = {18,5,23,15,17,0};
/*****************************************************
函数功能:向DS12C887写数据
入口参数:dat,add
***************************************************/
void Write887(unsigned char add, unsigned char dat)
{
CS=0;
AS=1;
DS=1;
RW=1;
P0=add; //先写地址
AS=0;
RW=0;
P0=dat; //再写数据
RW=1;
AS=1;
CS=1;
}
/*****************************************************
函数功能:向DS12C887读数据
入口参数:add
***************************************************/
unsigned char Read887(unsigned char add)
{
unsigned char DS_date; //定义DS12C887日期时间变量
AS=1;
DS=1;
RW=1;
CS=0;
P0=add; //写地址
AS=0;
DS=0;
P0=0xff;
DS_date=P0; //读数据
DS=1;
AS=1;
CS=1;
return DS_date;
}
void SetupDs12c887(void)
{
Write887(REGISTERA,0x70);
Write887(REGISTERB,0xa2);
Write887(TIME_YEAR, NUM2BCD(time[0]));
Write887(TIME_MONTH, NUM2BCD(time[1]));
Write887(TIME_DATE, NUM2BCD(time[2]));
Write887(TIME_HOUR, NUM2BCD(time[3]));
Write887(TIME_MINUTE, NUM2BCD(time[4]));
Write887(TIME_SECOND, NUM2BCD(time[5]));
//计时开始
Write887(REGISTERA,0x20);
Write887(REGISTERB,0x22);
}
void ReadDs12c887(void)
{
time[0] = BCD2NUM(Read887(TIME_YEAR));
time[1] = BCD2NUM(Read887(TIME_MONTH));
time[2] = BCD2NUM(Read887(TIME_DATE));
time[3] = BCD2NUM(Read887(TIME_HOUR));
time[4] = BCD2NUM(Read887(TIME_MINUTE));
time[5] = BCD2NUM(Read887(TIME_SECOND));
}
#endif
//----------------------------------------
DS12C887.h
#ifndef __DS12C887_H__
#define __DS12C887_H__
//1: 使用外部RAM方式读写 0:采用INTEL总线方式按时序要求的方式读写
#define READ_WRITE_WITH_EXTERNAL_RAM 0
#if READ_WRITE_WITH_EXTERNAL_RAM
#define NUM2BCD(x) ((((x)/10)<<4)|(x%10))
#define BCD2NUM(x) (((x)>>4)*10 + ((x)&0x0f))
#define TIME_SECOND XBYTE[0xff00]
#define TIME_MINUTE XBYTE[0xff02]
#define TIME_HOUR XBYTE[0xff04]
#define TIME_DAY XBYTE[0xff06]
#define TIME_DATE XBYTE[0xff07]
#define TIME_MONTH XBYTE[0xff08]
#define TIME_YEAR XBYTE[0xff09]
//控制寄存器
#define REGISTERA XBYTE[0xff0A]
#define REGISTERB XBYTE[0xff0B]
#define REGISTERC XBYTE[0xff0C]
#define REGISTERD XBYTE[0xff0D]
void SetupDs12c887(void);
void ReadDs12c887(void);
extern unsigned char time[6];
#else
#define NUM2BCD(x) ((((x)/10)<<4)|(x%10))
#define BCD2NUM(x) (((x)>>4)*10 + ((x)&0x0f))
#define TIME_SECOND 0
#define TIME_MINUTE 2
#define TIME_HOUR 4
#define TIME_DAY 6
#define TIME_DATE 7
#define TIME_MONTH 8
#define TIME_YEAR 9
//控制寄存器
#define REGISTERA 10
#define REGISTERB 11
#define REGISTERC 12
#define REGISTERD 13
void SetupDs12c887(void);
void ReadDs12c887(void);
extern unsigned char time[6];
#endif
#endif
//-----------------------------------------------------------
main.c
#include <reg52.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include "DS12C887.h"
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef signed char s8;
typedef signed short s16;
typedef signed int s32;
void Uart_Init(void)
{
TMOD = 0x20;
//设置定时器,定时器1工作于8位自动重载模式, 用于产生波特率
//TH1 = ;
//TL1 = ;
//注意查找编程器在22.1184MHz下9600的初值计算
TH1 = 0xFD;
TL1 = 0xFD;
//晶振在MCU下面,暂时认为是11.0592MHz
PCON = 0x00;
SCON = 0x50;
//SM0 SM1 SM2 REN TB8 RB8 TI SI
//选择工作模式1使能接收,允许发送,允许接收
ES = 1;
EA = 1;
TR1 = 1;
}
void Printc(u8 x)
{
SBUF = x;
while(TI==0);
TI = 0;
}
void sendbuf(void *ucabuf, u32 len)
{
u32 i;
char *pbuf;
pbuf = ucabuf;
for (i = 0; i < len; i++)
{
Printc((unsigned char)pbuf[i]);
}
}
void Prints(u8 * pd)
{
while((*pd)!='\0') //发送字符串,直到遇到0才结束
{
Printc(*pd); //发送一个字符
pd++; //移动到下一个字符
}
}
void trace(const char *format, ...)
{
//if (debug)
//{
char sbuf[30] = {0};
u16 slen;
va_list ap;
va_start(ap, format);
slen = vsprintf(sbuf, format, ap);
va_end(ap);
//PortSend(1, (uchar *)sbuf, (uint)slen);
//DEBUG_SEND_STR(sbuf);
//UARTSend(0, (u8 *)sbuf, (u16)slen);
Prints((u8 *)sbuf);
//}
}
void printbuf(char *title, void *ucabuf, u32 len)
{
u32 i;
char *pbuf;
pbuf = ucabuf;
//if (debug)
//{
if (title != NULL)
{
trace("\r\n%s->", title);
}
else
{
trace("->");
}
for (i = 0; i < len; i++)
{
trace("[%d]%02x ", i, (unsigned char)pbuf[i]);
}
trace("\r\n");
//}
}
void delay_500ms(void)
{
u8 i,j,k;
for(i=15;i>0;i--)
for(j=202;j>0;j--)
for(k=81;k>0;k--);
}
void main(void)
{
u8 buf[10] = {0};
Uart_Init();
SetupDs12c887();
while(1)
{
ReadDs12c887();
sendbuf(time, 6);
delay_500ms();
}
}
|