/**
 * @author Alexandre Sales Vasconcelos ([email protected])
 * @brief Simulation with 4 multiplexed 7-segment displays based on example in figure 15.4 of the book "Programação de Sistemas Embarcados - Desenvolvendo Software para Microcontroladores em Linguagem C" by Rodrigo de Almeida.
 * @version 0.1
 * @date 2022-07-21
 * 
 * @copyright Copyright (c) 2022
 * 
 */

#include <stdio.h>    

//freeRTOS includes 
   
#include "freertos/FreeRTOS.h" 
#include "freertos/task.h" 
      
//ESP32 includes 

#include "driver/gpio.h" 
        
//pin mapping        
#define LED_a     (1ULL<<0)    //GPIO0     
#define LED_b     (1ULL<<1)    //GPIO1   
#define LED_c     (1ULL<<2)    //GPI02
#define LED_d     (1ULL<<3)    //GPIO3
#define LED_e     (1ULL<<4)    //GPIO4
#define LED_f     (1ULL<<5)    //GPIO5
#define LED_g     (1ULL<<6)    //GPIO6
#define LED_dp    (1ULL<<7)    //GPIO7
#define DISPLAY_1 (1ULL<<10)
#define DISPLAY_2 (1ULL<<11)
#define DISPLAY_3 (1ULL<<12)
#define DISPLAY_4 (1ULL<<13)

//hex -> 7-seg
enum digit_to_7seg {
  DIGIT_0 = (LED_a | LED_b | LED_c | LED_d | LED_e | LED_f),
  DIGIT_1 = (LED_b | LED_c),
  DIGIT_2 = (LED_a | LED_b | LED_d | LED_g | LED_e | LED_d),
  DIGIT_3 = (LED_a | LED_b | LED_c | LED_d | LED_g),
  DIGIT_4 = (LED_b | LED_c | LED_f | LED_g),
  DIGIT_5 = (LED_a | LED_c | LED_d | LED_f | LED_g),
  DIGIT_6 = (LED_a | LED_c | LED_d | LED_e | LED_f | LED_g),
  DIGIT_7 = (LED_a | LED_b | LED_c),
  DIGIT_8 = (LED_a | LED_b | LED_c | LED_d | LED_e | LED_f | LED_g),
  DIGIT_9 = (LED_a | LED_b | LED_c | LED_d | LED_f | LED_g),
  DIGIT_A = (LED_a | LED_b | LED_c | LED_e | LED_f | LED_g),
  DIGIT_b = (LED_c | LED_d | LED_e | LED_f | LED_g),
  DIGIT_C = (LED_a | LED_d | LED_e | LED_f),
  DIGIT_d = (LED_b | LED_c | LED_d | LED_e | LED_g),
  DIGIT_E = (LED_a | LED_d | LED_e | LED_f | LED_g),
  DIGIT_F = (LED_a | LED_e | LED_f | LED_g)
} digits;

void initDisplay(void);
void writeDisplay(long display, char digit);

void app_main(void)
{
  // vetor que armazena o valor HEX correspondente a cada caractere no display de 7 segmentos
  static const char digits[] = {DIGIT_0, DIGIT_1, DIGIT_2, DIGIT_3, DIGIT_4, DIGIT_5, DIGIT_6, 
      DIGIT_7, DIGIT_8, DIGIT_9, DIGIT_A, DIGIT_b, DIGIT_C, DIGIT_d, DIGIT_E, DIGIT_F};

  unsigned int counter = 0;
  unsigned char display_message[] = {0,0,0,0};
  unsigned int  loop_time = 1;
  unsigned long last_time = esp_timer_get_time() / 1000ULL;

  initDisplay();

  for (;;)
  {
    
    if (((esp_timer_get_time() / 1000ULL) - last_time) >= loop_time) {
      if (counter < 9999) {
        counter++;
      } else {
        counter = 0;
      }
      unsigned int _count = counter;
      display_message[0] = _count%10;
      _count = _count/10;
      display_message[1] = _count%10;
      _count = _count/10;
      display_message[2] = _count%10;
      _count = _count/10;
      display_message[3] = _count%10;
      _count = _count/10;
      last_time = esp_timer_get_time() / 1000ULL;
    }
    
    writeDisplay(DISPLAY_1, digits[display_message[3]]);
    writeDisplay(DISPLAY_2, digits[display_message[2]]);
    writeDisplay(DISPLAY_3, digits[display_message[1]]);
    writeDisplay(DISPLAY_4, digits[display_message[0]]);

  }  
}

void initDisplay(void) {
  gpio_config_t io_conf;
  io_conf.intr_type = GPIO_PIN_INTR_DISABLE;
  io_conf.mode = GPIO_MODE_OUTPUT;
  io_conf.pin_bit_mask = (LED_a | LED_b | LED_c | LED_d | LED_e | LED_f | LED_g | LED_dp | DISPLAY_1 | DISPLAY_2 | DISPLAY_3 | DISPLAY_4);
  io_conf.pull_down_en = 0;
  io_conf.pull_up_en = 0;
  gpio_config(&io_conf);
}

void writeDisplay(long display, char digit) {
  REG_WRITE(GPIO_OUT_W1TS_REG, 0x00ff);   // limpa o display
  REG_WRITE(GPIO_OUT_W1TS_REG, display);  // habilita o display selecionado
  REG_WRITE(GPIO_OUT_W1TC_REG, digit);    // liga o conjunto de led do digito
    vTaskDelay(10 / portTICK_PERIOD_MS);  // aguarda
  REG_WRITE(GPIO_OUT_W1TC_REG, display);  // desabilita o display selecionado
}
Loading
franzininho-wifi