ESP32. Подключение индикатора TM1637 в Espressif-IDE
Сразу обозначим, что статья о работе с ESP32, в Espressif-IDF, не с Arduino.
В статье опишем общий принцип работы. Сразу замечание, текст будет казаться только отображения на индикаторе. Модуль может ещё работать с клавиатурой, но нам в работе это не понадобилось и эта тема освещена не будет.
Принцип работы
Обмен данными с модулем происходит по двум шинам CLK и DIO. Когда не происходит передача, на обеих шинах устанавливается высокий уровень сигнала.Маркером окончания передачи является переход от 0 к 1 на шине DIO, при 1 на шине CLK.
Между маркерами может быть передано от одного до нескольких байтов.
! Изменение состояния шины DIO должны происходить только при низком уровне на шине CLK !
Перед восходящим фронтом на шине CLK на шине DIO уже должен быть установлен уровень, соответствующий передаваемому биту.Если после этого не будет сформирован маркер окончания передачи, то считается, что со следующим импульсом CLK пошла передача следующего байта.
Во время передачи сигнала АСК неплохо переводить соответствующие выводы микроконтроллера на прием, но при наличии только одного индикатора, достаточно держать на выводах 0.
На рисунке выше изображено, как происходит передача байта на индикатор.
Программная реализация
1. Для того, чтобы индикатор начал работать сначала необходимо отправить команду инициализации.В даташите (файл приложим к статье) об этом сказано весьма непонятно. В результате экспериментов (не исключено, что это именно с нашим экземпляром индикатора, прибудут другие протестируем) выяснено, что для инициализации необходимо отправить команду инициализации.
(для тех кто не знает 0b - означает, что далее идет число в двоичном формате, передавать можно в любом, но так понятнее).
Структура команды конфигурации следующая (слева направо):
10 - признак, что идет команда конфигурации:
Bit_7 - всегда 1
Bit_6 - всегда 0
Bit_5 - всегда 0
Bit_4 - всегда 0
Bit_3 - 1- включить индикатор, 0 - выключить индикатор
Биты с 0 по 2- градация яркости. 000 минимальная яркость, 111 - максимальная яркость
Bit_2 - 1
Bit_1 - 1
Bit_0 - 1
Выглядеть это будет так (при передаче с фиксированным адресом знакоместа).
4. Адрес задается байтом, где первые (справа) байты задают место на индикаторе, справа налево, начиная с 0:
0b11000000 - первый справа
0b11000001 - второй
0b11000010 - третий
0b11000011 - четвертый
Обозначения сегментов
DP - точка или двоеточие.
Кодирование символов | |||||||
bit_7 | bit_6 | bit_5 | bit_4 | bit_3 | bit_2 | bit_1 | bit_0 |
DP | G | F | E | D | C | B | A |
Программная реализация с помощью Espressif-IDE
#include <driver/gpio.h>#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#define TM1637_CONFIG 0b10001100
#define TM1637_adres_1 0b11000001
#define TM1637_adres_2 0b11000010
#define TM1637_adres_3 0b11000011
//Маркер начала посылки
gpio_set_level(clk_gpio, 1);
gpio_set_level(dio_gpio, 0);
}//Маркер окончания посылки
gpio_set_level(clk_gpio, 1);
gpio_set_level(dio_gpio, 1);
}//Отправка команды
void tm1637_send_command(int clk_gpio, int dio_gpio, int command){tm1637_start(clk_gpio, dio_gpio);
//Формируем 8 импульсов и передаем значения бит
for(int i = 0; i < 8; i++){
gpio_set_level(clk_gpio, 0);
gpio_set_level(dio_gpio, command >> i & 1); //Выбираем нужный бит и устанавливаем
gpio_set_level(clk_gpio, 1);
}
//ACK
gpio_set_level(clk_gpio, 0);
gpio_set_level(dio_gpio, 0);
//Девятый импульс
gpio_set_level(clk_gpio, 1);
gpio_set_level(clk_gpio, 0);
tm1637_finish(clk_gpio, dio_gpio);
}//Первоначальная инициализация
void tm1637_init(int clk_gpio, int dio_gpio){esp_rom_gpio_pad_select_gpio(clk_gpio); // режим ввода-вывода
gpio_set_direction(clk_gpio, GPIO_MODE_OUTPUT); // активный выход
esp_rom_gpio_pad_select_gpio(dio_gpio); // режим ввода-вывода
gpio_set_direction(dio_gpio, GPIO_MODE_OUTPUT); // активный выход
tm1637_start(clk_gpio, dio_gpio);
tm1637_send_command(clk_gpio, dio_gpio, TM1637_INIT);
tm1637_send_command(clk_gpio, dio_gpio, TM1637_CONFIG);
tm1637_finish(clk_gpio, dio_gpio);
}//Получение адреса знакоместа
int tm1637_address_get(int num_digit){int res = 0b00000000;
switch (num_digit) {
case 0: res = 0b11000000; break;
case 1: res = 0b11000001; break;
case 2: res = 0b11000010; break;
case 3: res = 0b11000011; break;
case 4: res = 0b11000100; break;
case 5: res = 0b11000101; break;
}
return (res);
}int tm1637_get_code_symbol(char x){
int res = 0b00000000;
switch (x) {
case 0: res = 0b00111111; break;
case 1: res = 0b00000110; break;
case 2: res = 0b01011011; break;
case 3: res = 0b01001111; break;
case 4: res = 0b01100110; break;
case 5: res = 0b01101101; break;
case 6: res = 0b01111101; break;
case 7: res = 0b00000111; break;
case 8: res = 0b01111111; break;
case 9: res = 0b01101111; break;
case '0': res = 0b00111111; break;
case '1': res = 0b00000110; break;
case '2': res = 0b01011011; break;
case '3': res = 0b01001111; break;
case '4': res = 0b01100110; break;
case '5': res = 0b01101101; break;
case '6': res = 0b01111101; break;
case '7': res = 0b00000111; break;
case '8': res = 0b01111111; break;
case '9': res = 0b01101111; break;
case 'B': res = 0b01111111; break;
case 'H': res = 0b01110110; break;
case 'L': res = 0b00111000; break;
case '=': res = 0b01001000; break;
case 'E': res = 0b01111001; break;
case 'r': res = 0b01010000; break;
case 'N': res = 0b00000000; break; // Погасить разряд
}
return (res);
}void tm1637_send_command_short(int clk_gpio, int dio_gpio, int command){
//Формируем 8 импульсов и передаем значения бит
for(int i = 0; i < 8; i++){
gpio_set_level(clk_gpio, 0);
gpio_set_level(dio_gpio, command >> i & 1); //Выбираем нужный бит и устанавливаем
gpio_set_level(clk_gpio, 1);
}
//ACK
gpio_set_level(clk_gpio, 0);
gpio_set_level(dio_gpio, 0);
//Девятый импульс
gpio_set_level(clk_gpio, 1);
gpio_set_level(clk_gpio, 0);
}void tm1637_indicator_set_one(int clk_gpio, int dio_gpio, int num_digit, char symbol){
tm1637_start(clk_gpio, dio_gpio);
tm1637_send_command_short(clk_gpio, dio_gpio, tm1637_address_get(num_digit));
tm1637_send_command_short(clk_gpio, dio_gpio, tm1637_get_code_symbol(symbol));
tm1637_finish(clk_gpio, dio_gpio);
}void tm1637_indicator_set_all(int clk_gpio, int dio_gpio, char * ind_value){
for (int i = 0; i < 4; i++){
tm1637_indicator_set_one(clk_gpio, dio_gpio, i, ind_value[i]);
}
}//Определение ног микропроцессора для работы с дисплеем
#define TM1637_CLK GPIO_NUM_21
#define TM1637_DIO GPIO_NUM_23
//Инициализация
tm1637_init(TM1637_CLK, TM1637_DIO);
//Отправка символов
tm1637_indicator_set_all(TM1637_CLK, TM1637_DIO, "1234");
}
Комментарии 1