#ifndef RTC_H_ #define RTC_H_ #include #include #include #define DS1307_ADDRESS 0xD0 // Address of the RTC on the I2C bus #define SECONDS_REGISTER 0x00 #define MINUTES_REGISTER 0x01 #define HOURS_REGISTER 0x02 #define DAYOFWK_REGISTER 0x03 #define DAYS_REGISTER 0x04 #define MONTHS_REGISTER 0x05 #define YEARS_REGISTER 0x06 void i2c_init(void) { TWSR = 0x00; // Set prescaler to 1 TWBR = ((F_CPU / 100000UL) - 16) / 2; // Set I2C frequency to 100kHz } void i2c_start(void) { TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN); // Send start condition while (!(TWCR & (1 << TWINT))); // Wait for TWINT flag to be set } void i2c_stop(void) { TWCR = (1 << TWINT) | (1 << TWSTO) | (1 << TWEN); // Send stop condition while ((TWCR & (1 << TWSTO))); // Wait for TWSTO flag to be cleared } void i2c_write(uint8_t data) { TWDR = data; // Load data into data register TWCR = (1 << TWINT) | (1 << TWEN); // Start transmission while (!(TWCR & (1 << TWINT))); // Wait for TWINT flag to be set } uint8_t i2c_read_ack(void) { TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWEA); // Enable acknowledge bit while (!(TWCR & (1 << TWINT))); // Wait for TWINT flag to be set return TWDR; // Return data received } uint8_t i2c_read_nack(void) { TWCR = (1 << TWINT) | (1 << TWEN); // Disable acknowledge bit while (!(TWCR & (1 << TWINT))); // Wait for TWINT flag to be set return TWDR; // Return data received } void SetTimeDate() // simple, hard-coded way to set the date 8/13/21013 at 8:51 PM { I2C_WriteRegister(MONTHS_REGISTER, 0x08); I2C_WriteRegister(DAYS_REGISTER, 0x31); I2C_WriteRegister(YEARS_REGISTER, 0x13); I2C_WriteRegister(HOURS_REGISTER, 0x08+0x40); // add 0x40 for PM I2C_WriteRegister(MINUTES_REGISTER, 0x00); I2C_WriteRegister(SECONDS_REGISTER, 0x00); } void rtc_init(void) { i2c_start(); i2c_write(DS1307_ADDRESS); i2c_write(0x00); // Set control register to 0 i2c_write(0x00); // Enable oscillator and set square-wave output to 1Hz i2c_stop(); } void I2C_WriteRegister(uint8_t deviceRegister, uint8_t data) { i2c_start(); i2c_write(DS1307_ADDRESS); // send bus address i2c_write(deviceRegister); // first byte = device register address i2c_write(data); // second byte = data for device register i2c_stop(); } uint8_t rtc_read_register(uint8_t reg) { uint8_t value; i2c_start(); i2c_write(DS1307_ADDRESS); i2c_write(reg); // Set register pointer i2c_start(); // Send repeated start condition i2c_write(DS1307_ADDRESS | 0x01); // Set RTC address with read bit value = i2c_read_nack(); // Read value from register i2c_stop(); return value; } #endif /* RTC_H_ */