LED_shit/main/display.c

170 lines
4.7 KiB
C

#include "driver/i2c.h"
#include "esp_log.h"
#include "display.h"
#define DISP_ADDR 0x70
#define I2C_PORT I2C_NUM_0
const char *TAG = "DISPLAY";
// ------------------------------
// DISPLAY INIT
// ------------------------------
void display_init(void)
{
uint8_t cmd1 = 0x21; // oscillator ON
i2c_master_write_to_device(I2C_PORT, DISP_ADDR, &cmd1, 1, 20 / portTICK_PERIOD_MS);
uint8_t cmd2 = 0x81; // display ON, blink OFF
i2c_master_write_to_device(I2C_PORT, DISP_ADDR, &cmd2, 1, 20 / portTICK_PERIOD_MS);
uint8_t cmd3 = 0xEF; // brightness
i2c_master_write_to_device(I2C_PORT, DISP_ADDR, &cmd3, 1, 20 / portTICK_PERIOD_MS);
display_clear();
}
// ------------------------------
// CLEAR DISPLAY
// ------------------------------
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);
}
// --------------------------------------------------------
// RAW WRITE — 14 segmentos (cada dígito = 16 bits)
// --------------------------------------------------------
void display_raw(int pos, uint16_t mask)
{
if (pos < 0 || pos > 3) return;
uint8_t buf[3];
buf[0] = pos * 2;
buf[1] = mask & 0xFF;
buf[2] = (mask >> 8) & 0xFF;
i2c_master_write_to_device(I2C_PORT, DISP_ADDR, buf, 3, 20 / portTICK_PERIOD_MS);
}
// --------------------------------------------------------
// Tabela alfanumérica 14 segmentos
// (corrigido: H com os 2 segmentos horizontais g1/g2)
// --------------------------------------------------------
static uint16_t charset(char c)
{
switch (c)
{
case '0': return 0b0000000000111111;
case '1': return 0b0000000000000110;
case '2': return 0b0000000001011011;
case '3': return 0b0000000001001111;
case '4': return 0b0000000001100110;
case '5': return 0b0000000001101101;
case '6': return 0b0000000001111101;
case '7': return 0b0000000000000111;
case '8': return 0b0000000001111111;
case '9': return 0b0000000001101111;
// Letras principais
case 'A': case 'a': return 0b0000000001110111;
case 'B': case 'b': return 0b0001000011111100;
case 'C': case 'c': return 0b0000000000111001;
case 'D': case 'd': return 0b0001000011011110;
case 'E': case 'e': return 0b0000000001111001;
case 'F': case 'f': return 0b0000000001110001;
// CORRIGIDO → H com g1 + g2
case 'H': case 'h': return
(1<<5) | // f
(1<<4) | // e
(1<<1) | // b
(1<<2) | // c
(1<<6) | // g1
(1<<7); // g2
case 'I': case 'i': return 0b0001000000000000 | 0b0000000000000110;
case 'L': case 'l': return 0b0000000000111000;
case 'O': case 'o': return 0b0001000010011100;
case 'P': case 'p': return 0b0000000001110011;
case 'S': case 's': return 0b0000000001101101;
case 'U': case 'u': return 0b0000000000011100;
case '-': return 0b0000000001000000;
case ' ': return 0;
default:
return 0;
}
}
// --------------------------------------------------------
// display_char()
// --------------------------------------------------------
void display_char(int pos, char c)
{
uint16_t mask = charset(c);
display_raw(pos, mask);
}
// --------------------------------------------------------
// display_text() (4 caracteres)
// --------------------------------------------------------
void display_text(const char *txt)
{
for (int i = 0; i < 4; i++)
{
char c = txt[i];
if (c == 0) c = ' ';
display_char(i, c);
}
}
// --------------------------------------------------------
// display_number()
// Mantida para compatibilidade com 7-segment
// --------------------------------------------------------
void display_digit(int pos, uint8_t val)
{
static const uint8_t seg7[10] = {
0b00111111,
0b00000110,
0b01011011,
0b01001111,
0b01100110,
0b01101101,
0b01111101,
0b00000111,
0b01111111,
0b01101111
};
if (val > 9) val = 0;
display_raw(pos, seg7[val]);
}
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);
}
void display_set_time(int horas, int minutos)
{
if (horas < 0) horas = 0;
if (horas > 99) horas = 99;
if (minutos < 0) minutos = 0;
if (minutos > 99) minutos = 99;
int num = horas * 100 + minutos;
display_number(num);
}