/* Title: I2C_Master_Software_DS3231_1.ino Author: Florin Dragan florind@mas.utcluj.ro Date Created: 01-10-2017 Last Modified: 02-04-2020 Purpose: This is an example how to communicate with DS32310 RTC (Real Time Clock) chip, using I2C interface with Software implementation */ /*Implementare simpla I2C Master software*/ #define SDA_Pin 2 //PD2 #define SCL_Pin 3 //PD3 #define SDA_HIGH digitalWrite(SDA_Pin, 1) #define SDA_LOW digitalWrite(SDA_Pin, 0) #define SCL_HIGH digitalWrite(SCL_Pin, 1) #define SCL_LOW digitalWrite(SCL_Pin, 0) /************************************************** Functions immplementing Software I2C communication ***************************************************/ void I2CInit() { SDA_HIGH; SCL_HIGH; } void I2CStart() { SDA_LOW; SCL_LOW; } void I2CRestart() { SDA_HIGH; SCL_HIGH; SDA_LOW; SCL_LOW; } void I2CStop() { SCL_LOW; SDA_LOW; SCL_HIGH; SDA_HIGH; } void I2CAck() { SDA_LOW; SCL_HIGH; SCL_LOW; SDA_HIGH; } void I2CNak() { SDA_HIGH; SCL_HIGH; SCL_LOW; SDA_HIGH; } unsigned char I2CSend(unsigned char Data) { unsigned char i, ack_bit; for (i = 0; i < 8; i++) { if ((Data & 0x80) == 0) { SDA_LOW; } else { SDA_HIGH; } SCL_HIGH; SCL_LOW; Data<<=1; } //end for SDA_HIGH; SCL_HIGH; ack_bit = digitalRead(SDA_Pin); SCL_LOW; return ack_bit; } unsigned char I2CRead() { unsigned char i, Data=0; for (i = 0; i < 8; i++) { SCL_HIGH; if(digitalRead(SDA_Pin)) Data |=1; if(i<7) Data<<=1; SCL_LOW; } //end for return Data; } /* Buffer where we will read/write our data */ /* Loop to read 7 bytes from I2C slave. register 0x00 - 0x06 Seconds, Minutes, Hours, Day of week, Day, Month, Year */ unsigned char I2CData[] = {0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x20}; /* Simple DS3231 communication example */ int main(void) { /*Set Date/Time if necessary*/ // SetDateTime(); /* We will now read data from DS3231 */ /* Reading for a memory based device always starts with a dummy write */ /* Initialize I2C Port */ I2CInit(); /* Send a start condition */ I2CStart(); /* Send slave address with write (R/W bit=0) */ I2CSend(0xD0); /* Send (write) address for dummy read operation this register */ /* address (pointer) 0x00 is actually where we are going to read from */ I2CSend(0x00); /* Send a repeated start, after a dummy write to start reading */ I2CRestart(); /* send slave address with read bit=1 set, address 0xD0|1 */ I2CSend(0xD1); /* Loop to read 7 bytes from I2C slave. register 0x00 - 0x06 0x00 -> Seconds, Minutes, Hours, Day of week, Day, Month, Year <- 0x06 */ for (unsigned char i = 0; i < 7; i++) { /* Read one byte by another */ I2CData[i] = I2CRead(); /* Send ACK if its not the last byte to read */ /* if its the last byte then send a NAK */ if (i < 6) I2CAck(); else I2CNak(); } /* Reading 7 bytes finished, Send stop */ I2CStop(); /* end of program */ /* Display Date/Time ........ */ while(1); } //end main void SetDateTime() { /*Set Date/Time if necessary*/ /* Initialize I2C Port */ I2CInit(); /* Send Start condition */ I2CStart(); /* Send DS3231 slave address with write operation bit = 0 */ I2CSend(0xD0); /* Send start register address (pointer) 0x00, we are writing from this location on */ I2CSend(0x00); /* Loop to write 7 bytes to I2C slave. register 0x00 - 0x06 0x00 -> Seconds, Minutes, Hours, Day of week, Day, Month, Year <- 0x06 */ for (unsigned char i = 0; i < 7; i++) { /* send I2C data one by one */ I2CSend(I2CData[i]); } /* Send a stop condition - as transfer finishes */ I2CStop(); }