#include <stdio.h> // Biblioteca para operações de entrada e saída padrão (printf)
#include "pico/stdlib.h" // Biblioteca padrão do Pico SDK para GPIO, I2C, etc.
#include "hardware/i2c.h" // Biblioteca para comunicação I2C
#include "hardware/timer.h" // Biblioteca para uso de timers
// Definições I2C
#define I2C_PORT i2c0 // Define qual periférico I2C será utilizado (i2c0)
#define I2C_SDA 8 // Define o pino GPIO para a linha SDA do I2C (GPIO 8)
#define I2C_SCL 9 // Define o pino GPIO para a linha SCL do I2C (GPIO 9)
#define DS1307_ADDR 0x68 // Define o endereço I2C do módulo DS1307 (0x68)
// Definições dos Registradores do RTC
#define DS1307_SECONDS 0x00 // Endereço do registrador de segundos no DS1307
#define DS1307_MINUTES 0x01 // Endereço do registrador de minutos no DS1307
#define DS1307_HOURS 0x02 // Endereço do registrador de horas no DS1307
#define DS1307_DAY 0x03 // Endereço do registrador do dia da semana no DS1307
#define DS1307_DATE 0x04 // Endereço do registrador de data no DS1307
#define DS1307_MONTH 0x05 // Endereço do registrador de mês no DS1307
#define DS1307_YEAR 0x06 // Endereço do registrador de ano no DS1307
// Função para converter um valor decimal para BCD "Binary Coded Decimal" (Decimal Codificado em Binário)
uint8_t decToBcd(uint8_t val) {
return ((val / 10) << 4) | (val % 10); // Calcula e retorna o valor BCD
}
// Função para converter um valor BCD para decimal
uint8_t bcdToDec(uint8_t val) {
return ((val >> 4) * 10) + (val & 0x0F); // Calcula e retorna o valor decimal
}
// Função para escrever um byte em um registrador do RTC (DS1307)
void rtc_write(uint8_t reg, uint8_t value) {
uint8_t buffer[2] = {reg, value}; // Cria um buffer com o endereço e o valor a ser escrito
i2c_write_blocking(I2C_PORT, DS1307_ADDR, buffer, 2, false); // Escreve o buffer no I2C
}
// Função para ler um byte de um registrador do RTC (DS1307)
uint8_t rtc_read(uint8_t reg) {
uint8_t value; // Variável para armazenar o valor lido
i2c_write_blocking(I2C_PORT, DS1307_ADDR, ®, 1, true); // Envia o endereço do registrador para leitura
i2c_read_blocking(I2C_PORT, DS1307_ADDR, &value, 1, false); // Lê um byte do I2C
return value; // Retorna o valor lido
}
// Função para definir a data e hora inicial no RTC (DS1307)
void set_rtc_time() {
// Define a data e hora inicial: 24/09/2024 - 13:27:00
rtc_write(DS1307_SECONDS, decToBcd(0)); // Escreve os segundos (00) em BCD
rtc_write(DS1307_MINUTES, decToBcd(27)); // Escreve os minutos (27) em BCD
rtc_write(DS1307_HOURS, decToBcd(13)); // Escreve as horas (13) em BCD
rtc_write(DS1307_DAY, decToBcd(3)); // Escreve o dia da semana (não usado)
rtc_write(DS1307_DATE, decToBcd(24)); // Escreve o dia (24) em BCD
rtc_write(DS1307_MONTH, decToBcd(9)); // Escreve o mês (9) em BCD
rtc_write(DS1307_YEAR, decToBcd(24)); // Escreve o ano (24) em BCD (representa 2024)
}
// Função para ler a data e hora do RTC (DS1307) e imprimir no console
void read_rtc_time() {
// Lê os registradores do DS1307 e converte de BCD para decimal
uint8_t seconds = bcdToDec(rtc_read(DS1307_SECONDS)); // Lê e converte os segundos
uint8_t minutes = bcdToDec(rtc_read(DS1307_MINUTES)); // Lê e converte os minutos
uint8_t hours = bcdToDec(rtc_read(DS1307_HOURS)); // Lê e converte as horas
uint8_t date = bcdToDec(rtc_read(DS1307_DATE)); // Lê e converte o dia
uint8_t month = bcdToDec(rtc_read(DS1307_MONTH)); // Lê e converte o mês
uint8_t year = bcdToDec(rtc_read(DS1307_YEAR)); // Lê e converte o ano
// Imprime a data e hora formatada no console
printf("Hora: %02d:%02d:%02d - Data: %02d/%02d/20%02d\n", hours, minutes, seconds, date, month, year);
}
// Função de callback do timer, chamada a cada intervalo definido
bool repeating_timer_callback(struct repeating_timer *t) {
read_rtc_time(); // Chama a função para ler e imprimir a hora e data
return true; // Retorna true para continuar o timer
}
int main() {
stdio_init_all(); // Inicializa a comunicação padrão (stdio)
// Inicialização da comunicação I2C
i2c_init(I2C_PORT, 100 * 1000); // Inicializa a comunicação I2C a 100 kHz
gpio_set_function(I2C_SDA, GPIO_FUNC_I2C); // Define o pino SDA como função I2C
gpio_set_function(I2C_SCL, GPIO_FUNC_I2C); // Define o pino SCL como função I2C
gpio_pull_up(I2C_SDA); // Habilita resistor de pull-up no pino SDA
gpio_pull_up(I2C_SCL); // Habilita resistor de pull-up no pino SCL
set_rtc_time(); // Define a data e hora inicial no RTC
// Configura um temporizador repetitivo para ler o RTC a cada 5 segundos
struct repeating_timer timer;
add_repeating_timer_ms(5000, repeating_timer_callback, NULL, &timer);
while(true) { // Loop principal
sleep_ms(10); // Aguarda 10 ms para economizar processamento
}
return 0; // Retorna 0 (não alcançado em um loop infinito)
}