#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/i2c.h"
#define COM_I2C i2c0
#define GPIO_SDA 4 // GPIO 4
#define GPIO_SCL 5 // GPIO 5
#define ADDRESS_DS1307 0x68 // Endereço I2C do DS1307
// Converte decimal para BCD
uint8_t conv_dec_BCD(uint8_t dec) {
return ((dec / 10) << 4) | (dec % 10);
}
// Converte BCD para decimal
uint8_t BCD_conv_dec(uint8_t bcd) {
return ((bcd >> 4) * 10) + (bcd & 0x0F);
}
// Configura a data e hora no DS1307
void set_rtc(uint8_t second, uint8_t minute, uint8_t hour, uint8_t day, uint8_t month, uint16_t year) {
uint8_t array_set[8] = {
0x00, // Endereço inicial do registrador
conv_dec_BCD(second),
conv_dec_BCD(minute),
conv_dec_BCD(hour),
0x03, // Dia da semana (1-7), não usado neste exemplo
conv_dec_BCD(day),
conv_dec_BCD(month),
conv_dec_BCD(year - 2000) // O DS1307 armazena apenas os dois últimos dígitos do ano
};
i2c_write_blocking(COM_I2C, ADDRESS_DS1307, array_set, 8, false);
}
// Lê a data e hora do DS1307
void read_rtc(uint8_t *second, uint8_t *minute, uint8_t *hour, uint8_t *day, uint8_t *month, uint16_t *year) {
uint8_t array_set[7];
uint8_t reg = 0x00;
// Define o endereço de leitura
i2c_write_blocking(COM_I2C, ADDRESS_DS1307, ®, 1, true);
// Lê 7 registros (segundos, minutos, horas, etc.)
i2c_read_blocking(COM_I2C, ADDRESS_DS1307, array_set, 7, false);
// Ignora o bit de oscilador desabilitado
*second = BCD_conv_dec(array_set[0] & 0x7F);
*minute = BCD_conv_dec(array_set[1]);
*hour = BCD_conv_dec(array_set[2] & 0x3F); // Modo 24 horas
*day = BCD_conv_dec(array_set[4]);
*month = BCD_conv_dec(array_set[5]);
*year = BCD_conv_dec(array_set[6]) + 2000;
}
void setup_i2c(){
// Inicializa a biblioteca stdio para usar printf
stdio_init_all();
// Inicializa o I2C
i2c_init(COM_I2C, 100 * 1000); // 100 kHz
gpio_set_function(GPIO_SDA, GPIO_FUNC_I2C);
gpio_set_function(GPIO_SCL, GPIO_FUNC_I2C);
gpio_pull_up(GPIO_SDA);
gpio_pull_up(GPIO_SCL);
// Configura a data e hora inicial: 24/09/2024 13:27:00
set_rtc(0, 27, 13, 24, 9, 2024);
}
int main() {
// Inicializa a biblioteca e a comunicação i2c
setup_i2c();
// Lê e mostra a hora a cada 5 segundos
while (true) {
uint8_t second, minute, hour, day, month;
uint16_t year;
read_rtc(&second, &minute, &hour, &day, &month, &year);
printf("Data e hora: %02d/%02d/%04d - %02d:%02d:%02d\n",
day, month, year, hour, minute, second);
sleep_ms(5000); // Delay de 5 segundos
}
}