#include “hal_data.h”
#incluye “Adafruit_SSD1306.h”
#include “fuentes/FreeSans9pt7b.h”
#incluir
#incluir
#incluye “qe_touch_config.h”
FSP_CPP_HEADER
anular R_BSP_WarmStart(evento bsp_warm_start_event_t);
FSP_CPP_FOOTER
#define DEBOUNCE_DELAY 20 // Retardo de rebote del botón 20 ms
Pantalla Adafruit_SSD1306 (128, 64); //crear objeto de pantalla OLED
rtc_time_t my_time= //estructura de tiempo con valores iniciales
{
.tm_sec = 0,
.tm_min = 0,
.tm_hora = 0,
.tm_mday = 1,
.tm_mon=1,
.tm_año = 100,
};
cadena[11]; // Cadena para enviar a OLED
uint8_t x0, x1, x2, y0, y1, y2; // coordenadas del punto
volatile uint32_ttic_1_128; // Contador de ticks de 1/128 segundos
estado del botón uint64_t; // estado del botón táctil
uint8_t estado anterior; // estado anterior del botón táctil
modos de enumeración // modo de funcionamiento del reloj
{
modo_normal,
MODE_SET_SEGUNDO,
MODE_SET_MINUTO,
MODE_SET_HORA,
MODE_SET_DAY,
MODE_SET_MES,
MODE_SET_AÑO
};
mode mode = MODE_NORMAL; // el modo actual es normal
fsp_err_t error; // resultado de la operación de la función API de FSP
void rtc_periodic_callback(rtc_callback_args_t *p_args) //Función de devolución de llamada RTC
{
if (p_args->event == RTC_EVENT_PERIODIC_IRQ)//Para interrupciones periódicas
tick_1_128 ++; // incrementa el contador de ticks
}
/**************************************************** * **************************************************** ************//**
* main() es generado por el editor de configuración RA y se usa para generar subprocesos si se usa RTOS.Esta función
* Llamado por main() si no se usa RTOS.
*************************************************** * * **************************************************** * ***************/
vacío hal_entry (vacío)
{
err = RM_TOUCH_Open(g_qe_touch_instance_config01.p_ctrl, g_qe_touch_instance_config01.p_cfg);//Inicializar la interfaz táctil
if (FSP_SUCCESS != err) // si el resultado no fue exitoso
{
while (true) {} // cuelga el programa aquí
}
R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_SECONDS);// Ejecute un retraso de 1 segundo para permitir que la energía OLED se estabilice
display.begin(SSD1306_SWITCHCAPVCC, 0x3C, false, true); //inicializa la pantalla OLED usando la dirección I2C 0x3C (para 128×64)
R_RTC_Open(&g_rtc0_ctrl, &g_rtc0_cfg); // Inicializar el módulo RTC
R_RTC_ClockSourceSet(&g_rtc0_ctrl); //Establece la fuente del reloj para RTC (también establece el formato de 24 horas)
R_RTC_CalendarTimeSet(&g_rtc0_ctrl, &my_time);//Asignar valor inicial a RTC
R_RTC_PeriodicIrqRateSet(&g_rtc0_ctrl, RTC_PERIODIC_IRQ_SELECT_1_DIV_BY_128_SECOND); //Establecer la tasa de interrupción periódica de RTC
display.begin(SSD1306_SWITCHCAPVCC, 0x3C, false, true); //inicializa la pantalla OLED usando la dirección I2C 0x3C (para 128×64)
display.setFont(&FreeSans9pt7b); //Establecer el nombre de la fuente
Display.setTextColor(WHITE); //Establecer el color del texto
/* Bucle principal */
mientras tanto (verdad)
{
if (tick_1_128 % 4 == 0) //cada 31,25 ms
{
err = RM_TOUCH_ScanStart(g_qe_touch_instance_config01.p_ctrl); //Iniciar exploración del botón táctil
if (FSP_SUCCESS != err) // si el resultado no fue exitoso
{
while (true) {} // cuelga el programa aquí
}
while (0 == g_qe_touch_flag) {} //Espere a que se complete el escaneo
g_qe_touch_flag = 0; // y reinicia la bandera
err = RM_TOUCH_DataGet(g_qe_touch_instance_config01.p_ctrl, &button_status, NULL, NULL); //Obtener el estado del botón táctil
si (FSP_SUCCESS == error)
{
if ((button_status == 1) && (previous_status == 0)) //si el estado actual del botón es bajo y el estado anterior era alto
Estado anterior = 1; //Restablecer el estado anterior a 0 para que la próxima vez no se implemente esta rama.
else if ((button_status == 0) && (previous_status == 1)) //si el estado actual del botón es alto y el estado anterior era bajo
Estado anterior = 0; // Luego establezca el estado anterior en 1 para que la próxima vez no se implemente esta rama.
else if ((button_status == 1) && (previous_status == 1)) //si ambos estados son altos (todavía se toca el botón)
{
if ((tick_1_128 % 32) == 0) //cada 250ms
{
cambiar (modo) // seleccionar el modo
{
case MODE_NORMAL: Break;//No hacer nada si el modo es normal
case MODE_SET_SECOND: //si el modo es set_second
my_time.tm_sec ++; // luego incrementa el segundo
if (my_time.tm_sec > 59) // si los segundos son mayores que 59
my_time.tm_sec = 0;// luego establezca los segundos en 0
descomponer;
case MODE_SET_MINUTE: //si el modo es set_minute
my_time.tm_min ++; // luego aumenta el minuto
if (my_time.tm_min > 59) //si el minuto es mayor que 59
my_time.tm_min = 0; // Luego establezca el minuto en 0
descomponer;
case MODE_SET_HOUR: //si el modo es set_hour
my_time.tm_hour++; // luego aumenta las horas
if (my_time.tm_hour > 23)//si la hora es mayor que 23
my_time.tm_hour = 0;//A continuación, establezca la hora en 0
descomponer;
case MODE_SET_DAY: // si el modo es set_day
my_time.tm_mday ++; // incrementa el día siguiente
if (my_time.tm_mday > 31) // si el día es mayor que 31
my_time.tm_mday = 1; // luego establezca el día en 1
descomponer;
case MODE_SET_MONTH: //si el modo es set_month
my_time.tm_mon ++; // luego incrementa el mes
if (my_time.tm_mon > 12) //si el mes es mayor que 12
my_time.tm_mon = 1; // Luego establezca el mes en 1
descomponer;
case MODE_SET_YEAR: //si el modo es set_year
my_time.tm_year ++; // luego incrementa el año
if (my_time.tm_year > 199)//si el año es mayor que 199 (2099)
my_time.tm_year = 100;//Luego establezca el año en 100 (2000).
descomponer;
}
}
}
}
}
if ((tick_1_128 % 32) == 0) //cada 250ms
{
if (mode == MODE_NORMAL) // si el modo es normal
R_RTC_CalendarTimeGet(&g_rtc0_ctrl, &my_time); // Luego lea la hora del módulo RTC
display.clearDisplay(); // limpia la pantalla
// dibuja la esfera del reloj analógico
mostrar.drawCircle(32, 32, 31, blanco);
para (int16_t i = 0; i < 360; i += 30)
display.drawLine((31*sin(i / 57.296)) + 32, (31*cos(i / 57.296)) + 32, (27*sin(i / 57.296)) + 32, (27*cos(i / 57.296) 57.296)) + 32, blanco);
// dibuja la flecha de los segundos
x0 = 32+((26*sin(my_time.tm_sec * 6 / 57.296)));
y0 = 32-((26*cos(my_time.tm_sec * 6 / 57.296)));
mostrar.drawLine(32, 32, x0, y0, blanco);
// dibujar la flecha de los minutos
x0 = 32+((2*cos(my_time.tm_min * 6 / 57.296)));
y0 = 32+((2*sin(my_time.tm_min * 6 / 57.296)));
x1 = 32-((2*cos(my_time.tm_min * 6 / 57.296)));
y1 = 32-((2*sin(my_time.tm_min * 6 / 57.296)));
x2 = 32+((25*sin(my_time.tm_min * 6 / 57.296)));
y2 = 32-((25*cos(my_time.tm_min * 6 / 57.296)));
mostrar.dibujarTriángulo(x0, y0, x1, y1, x2, y2, BLANCO);
// dibujar la flecha del tiempo
x0 = 32+((2*cos((mi_hora.tm_hora * 30 + mi_hora.tm_min / 2) / 57.296)));
y0 = 32+((2*sin((mi_hora.tm_hora * 30 + mi_hora.tm_min / 2) / 57.296)));
x1 = 32-((2*cos((mi_hora.tm_hora * 30 + mi_hora.tm_min / 2) / 57.296)));
y1 = 32-((2*sin((mi_hora.tm_hora * 30 + mi_hora.tm_min / 2) / 57.296)));
x2 = 32+((18*sin((mi_hora.tm_hora * 30 + mi_hora.tm_min / 2) / 57.296)));
y2 = 32-((18*cos((mi_hora.tm_hora * 30 + mi_hora.tm_min / 2) / 57.296)));
display.fillTriangle(x0, y0, x1, y1, x2, y2, WHITE);
// escribe el tiempo
Pantalla.setCursor(58, 13);
sprintf(str,”%02d:%02d:%02d”, mi_hora.tm_hora, mi_hora.tm_min, mi_hora.tm_seg);
mostrar.imprimir(cadena);
// escribir dia y mes
sprintf(str,”%02d.%02d”, mi_hora.tm_mday, mi_hora.tm_mon);
mostrar.setCursor(70, 36);
mostrar.imprimir(cadena);
// escribir el año
sprintf(str,”%04d”, my_time.tm_year + 1900);
mostrar.setCursor(70, 61);
mostrar.imprimir(cadena);
cambiar (modo) // dibuja un rectángulo alrededor del valor para cambiar en diferentes modos
{
caso MODE_NORMAL: romper;
Para MODE_SET_SECOND: display.drawRoundRect(107, 0, 22, 16, 2, WHITE);break;
Para MODE_SET_MINUTE: display.drawRoundRect(82, 0, 22, 16, 2, WHITE);break;
Para MODE_SET_HOUR: display.drawRoundRect(57, 0, 22, 16, 2, WHITE);break;
Para MODE_SET_DAY: display.drawRoundRect(69, 23, 22, 16, 2, WHITE);break;
Para MODE_SET_MONTH: display.drawRoundRect(94, 23, 22, 16, 2, WHITE);
Para MODE_SET_YEAR: display.drawRoundRect(69, 48, 42, 16, 2, WHITE);
}
display.display(); // vaciar el búfer a la pantalla
}
if (R_BSP_PinRead(BSP_IO_PORT_02_PIN_06) == BSP_IO_LEVEL_LOW) // si se presiona el botón
{
R_BSP_SoftwareDelay(DEBOUNCE_DELAY, BSP_DELAY_UNITS_MILLISECONDS); // retraso de rebote
if (R_BSP_PinRead(BSP_IO_PORT_02_PIN_06) == BSP_IO_LEVEL_LOW) //Si el botón aún está presionado
{
while (R_BSP_PinRead(BSP_IO_PORT_02_PIN_06) == BSP_IO_LEVEL_LOW);// Espere mientras se presiona el botón
R_BSP_SoftwareDelay(DEBOUNCE_DELAY, BSP_DELAY_UNITS_MILLISECONDS); // retraso de rebote
if (R_BSP_PinRead(BSP_IO_PORT_02_PIN_06) == BSP_IO_LEVEL_HIGH) //Si se suelta el botón
{
if (modo == MODE_SET_YEAR) // si el modo actual es set_year
{
mode = MODE_NORMAL; // luego establece el modo en normal
R_RTC_CalendarTimeSet(&g_rtc0_ctrl, &my_time); //y actualice el valor del módulo RTC
}
más // si no
modo = static_cast<モード>(modo + 1); // establece el siguiente modo
}
}
}
}
#si BSP_TZ_SECURE_BUILD
/* Ingrese el código no seguro */
R_BSP_NonSecureEnter();
#terminara si
}