我给你来个程序试试
DS3231.h
- #ifndef __DS3231_H__
- #define __DS3231_H__
- #include <reg52.h>
- #include <intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- sbit scl = P1^1; /* I2C pin definitions */
- sbit sda = P1^0;
- sbit int0 = P3^2; //DS3231内部闹钟中断
- /**************************** defines *******************************/
- #define ADDRTC 0xd0 /* DS3231 slave address (write) */
- #define ACK 0
- #define NACK 1
- extern xdata uchar sec, min, hour, day, date, month, year,Dtemp;
- /*********************** Function Prototypes **************************/
- void start();
- void stop();
- void i2cwrite(uchar d);
- uchar i2cread(uchar b);
- void writebyte();
- void Init_DS3231();
- //void frq_out_tog();
- void init_alrm();
- void comm_init();
- void GetTime(void);
- void SetTime(uchar yea,uchar mon,uchar da,uchar hou,uchar min,uchar sec);
- void i2cwrite_add(uchar address,uchar dat);
- uchar i2cread_add(uchar address);
- void InitDS3231();
- void read_temp();
- #endif
复制代码
DS3231.c
- #include "DS3231.H"
- /************************* Global Variables ***************************/
- xdata uchar sec, min, hour, day, date, month, year;
- xdata uchar Dtemp;
- /**************************** functions ******************************/
- void delay()
- {
- ;;
- }
- void start() /* --------- Initiate start condition ---------- */
- {
- sda = 1; delay();
- scl = 1; delay();
- sda = 0; delay();
- scl = 0;
- }
- void stop() /* ---------- Initiate stop condition ----------- */
- {
- sda = 0; delay();
- scl = 1; delay();
- sda = 1; delay();
- scl = 0;
- }
- void i2cack()
- {
- uchar i=0;
- scl=1;delay();
- while(sda==1 && i<255) i++;
- scl=0;delay();
- }
- void i2cwrite(uchar d) /* ----------------------------- */
- {
- uchar i;
- scl = 0;
- for (i = 0;i < 8; i++)
- {
- sda = d & 0x80; /* Send the msbits first */
- scl = 0;delay();
- scl = 1;delay();
- d = d << 1; /* do shift here to increase scl high time */
- scl = 0;
- }
- sda = 1;delay(); /* Release the sda line */
- scl = 0;delay();
- }
- uchar i2cread(uchar b) /* ----------------------------------- */
- {
- uchar i, d;
- d = 0;
- sda = 1;delay(); /* Let go of sda line */
- scl = 0;delay();
- for (i = 0; i < 8; i++) /* read the msb first */
- {
- scl = 1;delay();
- d = d << 1;
- d = d | (uchar)sda;
- scl = 0;delay();
- }
- sda = b;delay(); /* low for ack, high for nack */
- scl = 1;delay();
- scl = 0;delay();
- sda = 1;delay(); /* Release the sda line */
- return d;
- }
- void i2cwrite_add(uchar address,uchar dat)//指定地址写一个字节数据
- {
- start();
- i2cwrite(ADDRTC);
- i2cack();
- i2cwrite(address);
- i2cack();
- i2cwrite(dat);
- i2cack();
- stop();
- }
- uchar i2cread_add(uchar address)
- //指定地址读一个字节数据
- {
- uchar dd;
- start();
- i2cwrite(ADDRTC);
- i2cack();
- i2cwrite(address);
- i2cack();
- start();
- i2cwrite(ADDRTC);
- i2cack();
- dd=i2cread(0);
- stop();
- return dd;
- }
- void InitDS3231() /* ----- set time & date; user data entry ------ */
- {
- scl=1;delay();
- sda=1;delay();
- start();
- i2cwrite(ADDRTC); /* write slave address, write 1339 */
- i2cwrite(0x00); /* write register address, 1st clock register */
- i2cwrite(0x00); //秒
- i2cwrite(0x01); //分
- i2cwrite(0x01); //时
- i2cwrite(0x03); //星期
- i2cwrite(0x12); //日
- i2cwrite(0x01); //月
- i2cwrite(0x11); //年
- //i2cwrite(0x10); /* enable sqw, 1hz output */
- stop();
- }
- void GetTime() /* --- get date/time from DS3231 --- */
- {
- //while(int0); /* loop until int pin goes low */
- //start();
- //i2cwrite(ADDRTC);
- //i2cwrite(0x0f);
- //i2cwrite(0); /* clear alarm flags */
- //stop();
- start();
- i2cwrite(ADDRTC);
- i2cwrite(0);
- start();
- i2cwrite(ADDRTC | 1);
- sec = i2cread(ACK);
- min = i2cread(ACK);
- hour= i2cread(ACK);
- day = i2cread(ACK);
- date= i2cread(ACK);
- month= i2cread(ACK);
- year= i2cread(NACK);
- stop();
- }
- void read_temp() /* -------- read temperature -------- */
- {
- int itemp;
- float ftemp;
- do
- {
- start();
- i2cwrite(ADDRTC);
- i2cwrite(0x0e); /* address of control register */
- start();
- i2cwrite(ADDRTC + 1); /* send the device address for read */
- itemp = i2cread(NACK); /* get the control register value */
- stop();
- } while(itemp & 0x20); /* wait until CNVT bit goes inactive */
- start();
- i2cwrite(ADDRTC);
- i2cwrite(0x11); /* address of temperature MSB */
- start();
- i2cwrite(ADDRTC + 1); /* send the device address for read */
- itemp = ( (int) i2cread(ACK) << 5 );
- itemp += ( i2cread(NACK) >> 3);
- stop();
- if(itemp & 0x1000) itemp += 0xe000; /* if sign bit set, make 16 bit 2's comp */
- ftemp = 0.03125 * (float) itemp; /* convert to degrees C */
- /* ftemp = ftemp * 9 / 5 + 32; /* skip this if you don't want degrees F */
- Dtemp = (uchar) ftemp;
- }
- /*void frq_out_tog() // --- toggle en32khz bit to enable/disable sqw ---
- {
- uchar val;
- start();
- i2cwrite(ADDRTC);
- i2cwrite(0x0f); // control/status reg address
- start();
- i2cwrite(ADDRTC + 1); //send the device address for read
- val = i2cread(NACK);
- stop();
- val ^= 0x08; //toggle en32khz bit
- start();
- i2cwrite(ADDRTC);
- i2cwrite(0x0f); //control/status reg address
- i2cwrite(val);
- stop();
- }*/
- void init_alrm() /* --- enable alarm 1 for once-per-second --- */
- {
- start();
- i2cwrite(ADDRTC);
- i2cwrite(7); /* 1st alarm 1 reg address */
- i2cwrite(0x80); /* mask alarm register */
- i2cwrite(0x80);
- i2cwrite(0x80);
- i2cwrite(0x80);
- stop();
- start();
- i2cwrite(ADDRTC);
- i2cwrite(0x0e); /* control/status reg address */
- i2cwrite(0x05); /* enable interrupts, alarm 1 output */
- }
- void comm_init() /* ------ reset DS3231 comm interface ------ */
- {
- do /* because the DS3231 I2C interface is active for both supplies */
- { /* after a micro reset, we must get the comm into a known state */
- sda = 1; /* make sure master has released SDA */
- scl = 1;
- if(sda) /* if sda is high, generate a start */
- {
- sda = 0; /* The DS3231 will recognize a valid start */
- sda = 1; /* condition anywhere in a I2C data transfer */
- }
- scl = 0;
- } while(sda == 0); /* if the DS3231 is holding sda low, try again */
- }
复制代码 |