#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/i2c.h"
/* Definições importantes */
// Endereço I2C do DS1307
#define RTC_ADDRESS 0x68
// Pinos I2C
#define I2C_SDA_PIN 4 // Pino SDA
#define I2C_SCL_PIN 5 // Pino SCL
// Registradores do DS1307
#define REGISTER_SECONDS 0x00 // Segundos e bit Clock Halt (CH)
#define REGISTER_MINUTES 0x01 // Minutos
#define REGISTER_HOURS 0x02 // Horas
#define REGISTER_DAY 0x03 // Dia da semana (1-7)
#define REGISTER_DATE 0x04 // Dia do mês
#define REGISTER_MONTH 0x05 // Mês
#define REGISTER_YEAR 0x06 // Ano (2 dígitos)
/* Funções auxiliares */
// Converte um valor BCD para decimal
uint8_t bcd_to_dec(uint8_t value) {
return ((value >> 4) * 10) + (value & 0x0F);
}
// Converte um valor decimal para BCD
uint8_t dec_to_bcd(uint8_t value) {
return ((value / 10) << 4) | (value % 10);
}
// Inicializa o I2C
void initialize_i2c() {
// Configura o I2C com frequência de 100 kHz
i2c_init(i2c_default, 100000);
// Define os pinos SDA e SCL para função I2C
gpio_set_function(I2C_SDA_PIN, GPIO_FUNC_I2C);
gpio_set_function(I2C_SCL_PIN, GPIO_FUNC_I2C);
// Habilita resistores de pull-up nos pinos SDA e SCL
gpio_pull_up(I2C_SDA_PIN);
gpio_pull_up(I2C_SCL_PIN);
}
// Escreve um dado no DS1307
void rtc_write(uint8_t register_address, uint8_t *data, size_t length) {
// Cria um buffer que inclui o endereço do registrador e os dados
uint8_t buffer[length + 1];
buffer[0] = register_address; // Primeiro byte: endereço do registrador
for (size_t i = 0; i < length; i++) {
buffer[i + 1] = data[i]; // Dados a serem enviados
}
// Envia o buffer ao DS1307
i2c_write_blocking(i2c_default, RTC_ADDRESS, buffer, length + 1, false);
}
// Lê dados do DS1307
void rtc_read(uint8_t register_address, uint8_t *data, size_t length) {
// Envia o endereço do registrador ao DS1307
i2c_write_blocking(i2c_default, RTC_ADDRESS, ®ister_address, 1, true);
// Lê os dados do registrador
i2c_read_blocking(i2c_default, RTC_ADDRESS, data, length, false);
}
// Configura o horário no DS1307
void rtc_set_time(uint8_t hour, uint8_t minute, uint8_t second, uint8_t weekday, uint8_t day, uint8_t month, uint8_t year) {
uint8_t time_data[7];
time_data[0] = dec_to_bcd(second); // Segundos (em BCD)
time_data[1] = dec_to_bcd(minute); // Minutos (em BCD)
time_data[2] = dec_to_bcd(hour); // Horas (em BCD)
time_data[3] = dec_to_bcd(weekday); // Dia da semana (em BCD)
time_data[4] = dec_to_bcd(day); // Dia do mês (em BCD)
time_data[5] = dec_to_bcd(month); // Mês (em BCD)
time_data[6] = dec_to_bcd(year); // Ano (em BCD)
// Escreve os dados no DS1307
rtc_write(REGISTER_SECONDS, time_data, 7);
}
// Lê o horário do DS1307
void rtc_get_time(uint8_t *hour, uint8_t *minute, uint8_t *second, uint8_t *weekday, uint8_t *day, uint8_t *month, uint8_t *year) {
uint8_t time_data[7];
// Lê os 7 registradores de tempo do DS1307
rtc_read(REGISTER_SECONDS, time_data, 7);
// Converte os valores de BCD para decimal
*second = bcd_to_dec(time_data[0]);
*minute = bcd_to_dec(time_data[1]);
*hour = bcd_to_dec(time_data[2]);
*weekday = bcd_to_dec(time_data[3]);
*day = bcd_to_dec(time_data[4]);
*month = bcd_to_dec(time_data[5]);
*year = bcd_to_dec(time_data[6]);
}
int main() {
stdio_init_all();
// Inicializa a comunicação I2C
initialize_i2c();
// Mensagem inicial
printf("Consultando agenda...\n");
printf("Primeiramente, parabéns Sandra, mãe do Tiago, que fez 56 anos hoje 24/09/2024! \n");
printf("Inicializando DS1307...\n");
// Configura o horário inicial: 24/09/2024 às 13:27:00 (terça-feira)
rtc_set_time(13, 27, 0, 2, 24, 9, 24);
while (1) {
uint8_t hour, minute, second, weekday, day, month, year;
// Lê o horário atual
rtc_get_time(&hour, &minute, &second, &weekday, &day, &month, &year);
// Imprime o horário e a data no console
printf("Hora: %02d:%02d:%02d, Data: %02d/%02d/20%02d\n", hour, minute, second, day, month, year);
// Aguarda 5 segundos
sleep_ms(5000);
}
return 0;
}