← На главную

Отображение произвольных символов на ЖКИ 1602

Небольшое дополнение к посту Микроконтроллеры STM32: работа с экранчиком 1602 по I2C. HD44780-совместимые ЖК-индикаторы позволяют определить до восьми собственных символов 5x8 точек. Вот как этим пользоваться.

Обратимся к таблице доступных инструкций:

Команды, поддерживаемые чипом HD44780

Нас интересует строка «Set CGRAM Address». CGRAM означает Character Generator Random Access Memory. CGRAM состоит из 64-х ячеек памяти по 5 бит, что позволяет хранить восемь символов 5x8. Этим символам будут соответствовать коды \x00..\x07.

Обладая этой информацией, нетрудно написать код. Вот его полная версия:

#define PIN_RS (1 << 0) #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-метр в самодельном трансивере. Само собой разумеется, можно определить и другие символы. Заметьте, что ничто не мешает переопределять символы на лету. То есть, собственных символов может быть и больше восьми, но одновременно отобразить можно только восемь разных символов.