// IFMA - Embarcatech - jan-fev/2025
// Atividade Capítulos 05 a 08 - Clock e Temporizador
// Nome: Alberto Carlos de Oliveira Andrade
// Tarefa 2:
// 04 - Já para a comunicação I2C, iremos utilizar o DS1307, que é um Real Time Clock – RTC
// disponível no simulador Wokwi. O endereço I2C do DS1307 é 0x68. Um RTC é um hardware que
// garante a contagem de tempo na unidade de segundos. Muitos microcontroladores possuem RTC
// internos, mas alguns fazem uso de hardware externos. Para ler os valores, é necessário
// inicialmente configurar um valor de data e hora que deve, por exemplo, ser configurado
// manualmente pelo usuário.
// Nessa questão você deverá configurar o RTC para 24/09/2024 – 13:27:00 e em seguida,
// realizar a leitura do mesmo a cada 5 segundos, e imprimir na tela do console (Serial USB)
// o valor lido. Na tabela a seguir são apresentados os principais endereços do RTC DS1307.
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/i2c.h"
#define I2C_PORT i2c0 // Porta I2C que será usada
#define DS1307_ADDR 0x68 // Endereço do RTC DS1307
// Função para converter valor decimal para BCD
uint8_t dec_to_bcd(uint8_t val) {
return ((val / 10 * 16) + (val % 10)); // Converte de decimal para BCD (Binary Coded Decimal)
}
// Função para converter valor BCD para decimal
uint8_t bcd_to_dec(uint8_t val) {
return ((val / 16 * 10) + (val % 16)); // Converte de BCD para decimal
}
// Função para configurar o tempo do RTC (data e hora)
void set_time(uint8_t day, uint8_t month, uint8_t year, uint8_t hours, uint8_t minutes, uint8_t seconds) {
uint8_t data[8] = {0x00, dec_to_bcd(seconds), dec_to_bcd(minutes), dec_to_bcd(hours),
dec_to_bcd(2), dec_to_bcd(day), dec_to_bcd(month), dec_to_bcd(year)};
// Envia os dados de configuração para o RTC
if (i2c_write_blocking(I2C_PORT, DS1307_ADDR, data, 8, false) < 0)
printf("Erro ao configurar RTC DS1307\n"); // Se ocorrer erro na configuração, exibe mensagem
}
// Função para ler a data e hora do RTC
void read_time() {
uint8_t reg = 0x00, time_data[7];
// Solicita a leitura dos dados de tempo a partir do endereço 0x00 do RTC
if (i2c_write_blocking(I2C_PORT, DS1307_ADDR, ®, 1, true) < 0 ||
i2c_read_blocking(I2C_PORT, DS1307_ADDR, time_data, 7, false) < 0) {
printf("Erro ao ler RTC DS1307\n"); // Se falhar na leitura, exibe mensagem de erro
return;
}
// Converte os dados BCD para valores decimais
uint8_t seconds = bcd_to_dec(time_data[0]);
uint8_t minutes = bcd_to_dec(time_data[1]);
uint8_t hours = bcd_to_dec(time_data[2]);
uint8_t day = bcd_to_dec(time_data[4]);
uint8_t month = bcd_to_dec(time_data[5]);
uint8_t year = bcd_to_dec(time_data[6]);
// Exibe a data e hora no console no formato DD/MM/AAAA | HH:MM:SS
printf("Data: %02d/%02d/20%02d | Hora: %02d:%02d:%02d\n", day, month, year, hours, minutes, seconds);
}
int main() {
stdio_init_all(); // Inicializa a comunicação serial
i2c_init(I2C_PORT, 100 * 1000); // Inicializa a interface I2C com 100kHz de taxa de transmissão
gpio_set_function(4, GPIO_FUNC_I2C); // Configura o pino 4 como I2C (SDA)
gpio_set_function(5, GPIO_FUNC_I2C); // Configura o pino 5 como I2C (SCL)
gpio_pull_up(4); // Ativa o pull-up no pino SDA
gpio_pull_up(5); // Ativa o pull-up no pino SCL
printf("### Leitura RTC DS1307 ###\n");
// Configura o RTC para 24/09/2024 - 13:27:00
set_time(24, 9, 24, 13, 27, 0);
// Loop infinito para ler o tempo a cada 5 segundos e imprimir no console
while (true) {
read_time(); // Lê a hora atual do RTC
sleep_ms(5000); // Aguarda 5 segundos antes de realizar a próxima leitura
}
return 0; // Embora nunca seja alcançado, retorna 0 (finalização do programa)
}