// IFMA - SISTEMAS EMBARCADOS
// HUGO FELIPE DOS SANTOS ROCHA
// UNIT04 - Cap. 05 a 08 - ATIVIDADE: TAREFA DE ENVIO - Clock e temporizador
/*TAREFA 2:
4. 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"
// Definições para I2C
#define I2C_PORT i2c0
#define SDA_PIN 4
#define SCL_PIN 5
#define DS1307_ADDR 0x68
// Função para converter valores BCD em decimal
uint8_t bcd_to_decimal(uint8_t val) {
return (val >> 4) * 10 + (val & 0x0F);
}
// Função para converter valores decimais em BCD
uint8_t decimal_to_bcd(uint8_t val) {
return ((val / 10) << 4) | (val % 10);
}
// Função para configurar data e hora no DS1307
void set_rtc_time(uint8_t sec, uint8_t min, uint8_t hour, uint8_t day, uint8_t date, uint8_t month, uint8_t year) {
uint8_t buffer[8];
buffer[0] = 0x00; // Endereço de memória inicial
buffer[1] = decimal_to_bcd(sec);
buffer[2] = decimal_to_bcd(min);
buffer[3] = decimal_to_bcd(hour);
buffer[4] = decimal_to_bcd(day);
buffer[5] = decimal_to_bcd(date);
buffer[6] = decimal_to_bcd(month);
buffer[7] = decimal_to_bcd(year);
i2c_write_blocking(I2C_PORT, DS1307_ADDR, buffer, 8, false);
}
// Função para ler data e hora do DS1307
void read_rtc_time() {
uint8_t buffer[7];
uint8_t reg = 0x00; // Endereço inicial
i2c_write_blocking(I2C_PORT, DS1307_ADDR, ®, 1, true);
i2c_read_blocking(I2C_PORT, DS1307_ADDR, buffer, 7, false);
// Converter valores BCD para decimal
uint8_t sec = bcd_to_decimal(buffer[0] & 0x7F);
uint8_t min = bcd_to_decimal(buffer[1]);
uint8_t hour = bcd_to_decimal(buffer[2]);
uint8_t day = bcd_to_decimal(buffer[3]);
uint8_t date = bcd_to_decimal(buffer[4]);
uint8_t month = bcd_to_decimal(buffer[5]);
uint8_t year = bcd_to_decimal(buffer[6]);
printf("Data: %02d/%02d/20%02d, Hora: %02d:%02d:%02d\n", date, month, year, hour, min, sec);
}
int main() {
// Inicializar I2C e UART (para o console serial)
stdio_init_all();
i2c_init(I2C_PORT, 100 * 1000);
gpio_set_function(SDA_PIN, GPIO_FUNC_I2C);
gpio_set_function(SCL_PIN, GPIO_FUNC_I2C);
gpio_pull_up(SDA_PIN);
gpio_pull_up(SCL_PIN);
printf("Iniciando RTC DS1307...\n");
// Configurar o RTC com a data e hora desejada
set_rtc_time(0, 27, 13, 2, 24, 9, 24); // 24/09/2024 – 13:27:00
printf("Data e hora configuradas com sucesso!\n");
// Marca inicial de tempo
absolute_time_t next_read_time = make_timeout_time_ms(5000);
while (true) {
read_rtc_time();
// Esperar até o próximo múltiplo de 5 segundos
sleep_until(next_read_time);
// Atualizar o próximo momento de leitura
next_read_time = delayed_by_ms(next_read_time, 5000);
}
return 0;
}