Отображение произвольных символов на ЖКИ 1602
23 июня 2021
Небольшое дополнение к посту Микроконтроллеры STM32: работа с экранчиком 1602 по I2C. HD44780-совместимые ЖК-индикаторы позволяют определить до восьми собственных символов 5x8 точек. Вот как этим пользоваться.
Обратимся к таблице доступных инструкций:
Нас интересует строка «Set CGRAM Address». CGRAM означает Character Generator Random Access Memory. CGRAM состоит из 64-х ячеек памяти по 5 бит, что позволяет хранить восемь символов 5x8. Этим символам будут соответствовать коды \x00
..\x07
.
Обладая этой информацией, нетрудно написать код. Вот его полная версия:
#define PIN_EN (1 << 2)
#define BACKLIGHT (1 << 3)
#define LCD_DELAY_MS 5
uint8_t lcd_addr = (0x27 << 1);
HAL_StatusTypeDef LCD_SendInternal(uint8_t data, uint8_t flags) {
HAL_StatusTypeDef res;
for(;;) {
res = HAL_I2C_IsDeviceReady(&hi2c1, lcd_addr, 1,
HAL_MAX_DELAY);
if(res == HAL_OK)
break;
}
uint8_t up = data & 0xF0;
uint8_t lo = (data << 4) & 0xF0;
uint8_t data_arr[4];
data_arr[0] = up|flags|BACKLIGHT|PIN_EN;
data_arr[1] = up|flags|BACKLIGHT;
data_arr[2] = lo|flags|BACKLIGHT|PIN_EN;
data_arr[3] = lo|flags|BACKLIGHT;
res = HAL_I2C_Master_Transmit(&hi2c1, lcd_addr, data_arr,
sizeof(data_arr), HAL_MAX_DELAY);
HAL_Delay(LCD_DELAY_MS);
return res;
}
void LCD_SendCommand(uint8_t cmd) {
LCD_SendInternal(cmd, 0);
}
void LCD_SendData(uint8_t data) {
LCD_SendInternal(data, PIN_RS);
}
void LCD_Init() {
// 4-bit mode, 2 lines, 5x7 format
LCD_SendCommand(0b00110000);
// display & cursor home (keep this!)
LCD_SendCommand(0b00000010);
// display on, underline off, blink off
LCD_SendCommand(0b00001100);
// clear display (optional here)
LCD_SendCommand(0b00000001);
}
void LCD_SendString(char *str) {
while(*str) {
LCD_SendData((uint8_t)(*str));
str++;
}
}
void init() {
// check for an alternative LCD address
HAL_StatusTypeDef res;
res = HAL_I2C_IsDeviceReady(&hi2c1, (0x3F << 1), 1, HAL_MAX_DELAY);
if(res == HAL_OK) {
lcd_addr = (0x3F << 1);
}
LCD_Init();
// create 8 custom characters for the S-meter
for(uint8_t ch = 0; ch < 8; ch++) {
// set CGRAM Address
LCD_SendCommand(0b01000000 + (ch << 3));
for(uint8_t line = 0; line < 8; line++) {
if(ch >= (7-line)) {
LCD_SendData(0b11111);
} else {
LCD_SendData(0b00000);
}
}
}
LCD_SendCommand(0b11000000);
LCD_SendString(" ");
for(uint8_t ch = 0; ch < 8; ch++) {
LCD_SendData(ch);
}
while(1) { HAL_Delay(1000); }
}
Результат:
Код был успешно протестирован на пяти разных ЖК-индикаторах 1602 и 0802.
Приведенные символы могут быть использованы для отображения громкости или изображать S-метр в самодельном трансивере. Само собой разумеется, можно определить и другие символы. Заметьте, что ничто не мешает переопределять символы на лету. То есть, собственных символов может быть и больше восьми, но одновременно отобразить можно только восемь разных символов.
Метки: STM32, Электроника.
Вы можете прислать свой комментарий мне на почту, или воспользоваться комментариями в Telegram-группе.