DS3232是低成本温度补偿晶体振荡器(TCXO),内置精度极高的温度补偿实时时钟(RTC)以及236字节电池备份SRAM。此外,DS3232还具有电池输入,可在器件主电源掉电时保持精确计时。集成晶振提高了器件的长期精度,并减少了生产线的元件数量。DS3232具有商业级和工业级温度范围,并采用工业标准的20引脚、300mil SO封装。
RTC可以计数秒、分、时、星期、日期、月份和年份信息。对于少于31天的月份,月末日期自动调整,同时包括闰年修正功能。该时钟可以工作在24小时模式或带/AM/PM指示的12小时模式。提供两个可编程定时闹钟和可编程方波输出。地址和数据通过I2C双向总线串行传输。
精密的、经过温度补偿的电压基准和比较器电路用来监视VCC状态,以便检测电源失效,提供复位输出,并在必要时自动切换到备份电源。此外, 器件对/RST引脚进行监视,因此该引脚可作为按钮输入以产生μP复位。
在0°C至+40°C范围内,精度为±2ppm
在-40°C至+85°C范围内,精度为±3.5ppm
为不间断计时提供电池备份输入
工作温度范围
商业级:0°C至+70°C
工业级:-40°C至+85°C
236字节电池备份SRAM
低功耗
实时时钟计数秒、分、时、星期、日期、月份和年份信息,具有有效至2099年的闰年补偿
两个定时闹钟
可编程方波输出
高速(400kHz) I2C接口
3.3V工作电压
数字温度传感器输出:精度为±3°C
老化修正寄存器
/RST输入/输出
300mil、20引脚SO封装
本程序利用微控制器的两个通用端口作为I2C总线的主机,DS3231作为同一总线上的从机器件。该程序可以演示时间、日期的设置和读取,并能够读取、显示温度数据。利用本软件可以将时间、日期和温度信息显示到LCD监视器上,这里采用了一个标准的HD44780控制器。/***************************************************************************/
/* DEMO3231.C */
/***************************************************************************/
#include <stdio.h> /* Prototypes for I/O functions */
#include <DS5000.h> /* Register declarations for DS5000 */
/************************* bit definitions ****************************/
sbit scl = P0^0; /* I2C pin definitions */
sbit sda = P0^1;
sbit E = P1^0; /* DCM LCD module control signal definitions */
sbit RS = P1^1;
sbit RW = P1^2;
sbit CLK = P2^5; /* DS1267 control signal definitions */
sbit RSTb = P2^6;
sbit DQ = P2^7;
sbit int0 = P3^2;
/**************************** defines *******************************/
#define ADDRTC 0xd0 /* DS3231 slave address (write) */
#define ACK 0
#define NACK 1
/*********************** Function Prototypes **************************/
void start();
void stop();
uchar i2cwrite(uchar d);
uchar i2cread(char);
void wr_dsp_dat(uchar);
void wr_dsp_ins(uchar);
uchar rd_dsp_ins();
void hex2asc(uchar);
void dsp_adj(uchar pos);
void init_dsp();
void writebyte();
void initialize_DS3231();
void disp_regs();
void rd_temp();
void frq_out_tog();
void init_alrm();
void comm_init();
/************************* Global Variables ***************************/
xdata uchar sec, min, hr, dy, dt, mn, yr;
/**************************** functions ******************************/
void start() /* --------- Initiate start condition ---------- */
{
sda = 1; scl = 1;
sda = 0;
}
void stop() /* ---------- Initiate stop condition ----------- */
{
sda = 0; sda = 0;
scl = 1; scl = 1; sda = 1;
}
uchar i2cwrite(uchar d) /* ----------------------------- */
{
uchar i;
scl = 0;
for (i = 0;i < 8; i++)
{
if (d & 0x80)
sda = 1; /* Send the msbits first */
else
sda = 0;
scl = 0;
scl = 1;
d = d << 1; /* do shift here to increase scl high time */
scl = 0;
}
sda = 1; /* Release the sda line */
scl = 0;
scl = 1;
i = sda;
if (i) printf("Ack bit missing %02X\n",(unsigned int)d);
scl = 0;
return(i);
}
uchar i2cread(char b) /* ----------------------------------- */
{
uchar i, d;
d = 0;
sda = 1; /* Let go of sda line */
scl = 0;
for (i = 0; i < 8; i++) /* read the msb first */
{
scl = 1;
d = d << 1;
d = d | (unsigned char)sda;
scl = 0;
}
sda = b; /* low for ack, high for nack */
scl = 1;
scl = 0;
sda = 1; /* Release the sda line */
return d;
}
void wr_dsp_dat(uchar dat) /* -------- write one byte to the display --------- */
{
P0 = dat;
RS = 1; /* data register */
RW = 0; /* write */
E = 1;
E = 0; /* latch data in */
}
void wr_dsp_ins(uchar dat) /* ---- write one byte to the display instruction ----- */
{
P0 = dat;
RS = 0; /* instruction register */
RW = 0; /* write */
E = 1;
E = 0; /* latch data in */
}
uchar rd_dsp_ins() /* ---- read one byte from the instruction registers ----- */
{
uchar dat;
P0 = 0xff; /* set up for read */
RS = 0; /* instruction register */
RW = 1; /* read */
E = 1;
dat = P0;
E = 0;
return(dat);
}
void init_dsp() /* -------- initialize DMC-16207 LCD display ------- */
{
while((rd_dsp_ins() & 0x80)); /* wait for display */
wr_dsp_ins(0x38); /* Set 8-bit data, 2-line display, 5X7 font */
while((rd_dsp_ins() & 0x80));
wr_dsp_ins(0x0c); /* Display on, cursor off, blink off */
while((rd_dsp_ins() & 0x80));
wr_dsp_ins(0x06); /* Entry mode set: increment, no display shift */
while((rd_dsp_ins() & 0x80));
wr_dsp_ins(0x01); /* clear display */
while((rd_dsp_ins() & 0x80));
wr_dsp_ins(0x80); /* move to start of line 1 */
while((rd_dsp_ins() & 0x80));
wr_dsp_ins(0x50); /* Set CG RAM address */
while((rd_dsp_ins() & 0x80));
wr_dsp_dat(0x07); /* write 1st line of custom char to CG RAM */
while((rd_dsp_ins() & 0x80));
wr_dsp_dat(0x05); /* write 2nd line */
while((rd_dsp_ins() & 0x80));
wr_dsp_dat(0x07); /* write 3rd line */
while((rd_dsp_ins() & 0x80));
wr_dsp_dat(0x00); /* write 4th line */
while((rd_dsp_ins() & 0x80));
wr_dsp_dat(0x00); /* write 5th line */
while((rd_dsp_ins() & 0x80));
wr_dsp_dat(0x00); /* write 6th line */
while((rd_dsp_ins() & 0x80));
wr_dsp_dat(0x00); /* write 7th line */
while((rd_dsp_ins() & 0x80));
}
void hex2asc(uchar hex) /* -- convert the upper and lower nibbles to 2 ascii characters -- */
{
if( ( (hex & 0xf0) >> 4) < 0x0a)
wr_dsp_dat( ( (hex & 0xf0) >> 4) + 48 ); /* prints 0-9 */
else
wr_dsp_dat( ( (hex & 0xf0) >> 4) + 55 ); /* prints A-F */
while((rd_dsp_ins() & 0x80));
if( (hex & 0x0f) < 0x0a)
wr_dsp_dat( (hex & 0x0f) + 48 );
else
wr_dsp_dat( (hex & 0x0f) + 55 );
while((rd_dsp_ins() & 0x80));
}
void dsp_adj(uchar pos) /* ------ adjust contrast on LCD display ------- */
{
char inc;
RSTb = CLK = 0; /* initialize for 1st pass */
RSTb = 1; /* enable DS1267 */
DQ = 0; /* write stack select bit */
CLK = 1; /* toggle clk with data valid */
CLK = 0;
for (inc = 7; inc >= 0; inc--) /* write wiper 0 */
{
DQ = ((pos >> inc) & 0x01); /* shift x bits left */
CLK = 0;