2025-11-23 18:15:56 +00:00
|
|
|
|
#include "driver/i2c.h"
|
|
|
|
|
|
#include "esp_log.h"
|
|
|
|
|
|
#include "display.h"
|
|
|
|
|
|
|
|
|
|
|
|
#define DISP_ADDR 0x70
|
|
|
|
|
|
#define I2C_PORT I2C_NUM_0
|
|
|
|
|
|
|
2025-11-30 12:29:16 +00:00
|
|
|
|
// Exemplo de tabela 16 bits para 0–9 (tens de afinar os bits para o teu módulo)
|
|
|
|
|
|
static const uint16_t segtbl16[10] = {
|
|
|
|
|
|
0b0000000000111111, // 0
|
|
|
|
|
|
0b0000000000000110, // 1
|
|
|
|
|
|
0b0000000001011011, // 2
|
|
|
|
|
|
0b0000000001001111, // 3
|
|
|
|
|
|
0b0000000001100110, // 4
|
|
|
|
|
|
0b0000000001101101, // 5
|
|
|
|
|
|
0b0000000001111101, // 6
|
|
|
|
|
|
0b0000000000000111, // 7
|
|
|
|
|
|
0b0000000001111111, // 8
|
|
|
|
|
|
0b0000000001101111 // 9
|
2025-11-23 18:15:56 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
2025-11-30 12:29:16 +00:00
|
|
|
|
static const uint16_t alpha_map[] = {
|
|
|
|
|
|
['A'] = 0b0000000001110111,
|
|
|
|
|
|
['b'] = 0b0000000001111100,
|
|
|
|
|
|
['C'] = 0b0000000000111001,
|
|
|
|
|
|
['d'] = 0b0000000001011110,
|
|
|
|
|
|
['E'] = 0b0000000001111001,
|
|
|
|
|
|
['F'] = 0b0000000001110001,
|
|
|
|
|
|
['H'] = 0b0000000001110110,
|
|
|
|
|
|
['L'] = 0b0000000000111000,
|
|
|
|
|
|
['P'] = 0b0000000001110011,
|
|
|
|
|
|
['r'] = 0b0000000001010000,
|
|
|
|
|
|
['U'] = 0b0000000000111110,
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-11-23 18:15:56 +00:00
|
|
|
|
void display_init(void)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Oscillator ON
|
|
|
|
|
|
uint8_t cmd1 = 0x21;
|
|
|
|
|
|
i2c_master_write_to_device(I2C_PORT, DISP_ADDR, &cmd1, 1, 20 / portTICK_PERIOD_MS);
|
|
|
|
|
|
|
|
|
|
|
|
// Display ON, no blink
|
|
|
|
|
|
uint8_t cmd2 = 0x81;
|
|
|
|
|
|
i2c_master_write_to_device(I2C_PORT, DISP_ADDR, &cmd2, 1, 20 / portTICK_PERIOD_MS);
|
|
|
|
|
|
|
|
|
|
|
|
// Brilho máximo
|
|
|
|
|
|
uint8_t cmd3 = 0xEF;
|
|
|
|
|
|
i2c_master_write_to_device(I2C_PORT, DISP_ADDR, &cmd3, 1, 20 / portTICK_PERIOD_MS);
|
|
|
|
|
|
|
|
|
|
|
|
display_clear();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void display_clear(void)
|
|
|
|
|
|
{
|
|
|
|
|
|
uint8_t buf[17] = {0};
|
|
|
|
|
|
buf[0] = 0x00;
|
|
|
|
|
|
i2c_master_write_to_device(I2C_PORT, DISP_ADDR, buf, sizeof(buf), 20 / portTICK_PERIOD_MS);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void display_digit(int pos, uint8_t val)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (pos < 0 || pos > 3) return;
|
|
|
|
|
|
if (val > 9) val = 0;
|
|
|
|
|
|
|
2025-11-30 12:29:16 +00:00
|
|
|
|
uint16_t pattern = segtbl16[val];
|
2025-11-23 18:15:56 +00:00
|
|
|
|
|
2025-11-30 12:29:16 +00:00
|
|
|
|
uint8_t buf[3];
|
|
|
|
|
|
buf[0] = pos * 2; // endereço base do dígito
|
|
|
|
|
|
buf[1] = pattern & 0xFF; // byte baixo (bits 0–7)
|
|
|
|
|
|
buf[2] = (pattern >> 8) & 0xFF; // byte alto (bits 8–15)
|
|
|
|
|
|
|
|
|
|
|
|
i2c_master_write_to_device(I2C_PORT, DISP_ADDR, buf, 3,
|
|
|
|
|
|
20 / portTICK_PERIOD_MS);
|
2025-11-23 18:15:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-30 12:29:16 +00:00
|
|
|
|
|
2025-11-23 18:15:56 +00:00
|
|
|
|
void display_number(int num)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (num < 0) num = 0;
|
|
|
|
|
|
if (num > 9999) num = 9999;
|
|
|
|
|
|
|
|
|
|
|
|
display_digit(3, num % 10);
|
|
|
|
|
|
display_digit(2, (num / 10) % 10);
|
|
|
|
|
|
display_digit(1, (num / 100) % 10);
|
|
|
|
|
|
display_digit(0, (num / 1000) % 10);
|
|
|
|
|
|
}
|
2025-11-30 12:29:16 +00:00
|
|
|
|
|
|
|
|
|
|
void display_set_time(int h, int m)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (h < 0) h = 0;
|
|
|
|
|
|
if (h > 23) h = h % 24;
|
|
|
|
|
|
|
|
|
|
|
|
if (m < 0) m = 0;
|
|
|
|
|
|
if (m > 59) m = m % 60;
|
|
|
|
|
|
|
|
|
|
|
|
int value = h * 100 + m; // HHMM
|
|
|
|
|
|
|
|
|
|
|
|
display_number(value);
|
|
|
|
|
|
}
|