STM32. Урок 5. Підключення LCD дисплея WH1602
У сьогоднішньому уроці буде розглянута робота з символьним LCD дисплеєм фірми Winstar на контролері HD44780. Слід одразу зазначити, що аналогів даного дисплея безліч, і прошивка буде працювати з усіма ними. Також була перевірена робота цього коду з графічними та символьними OLED дисплеями.
Розпочнемо, як звичайно, з постановки завдання. Необхідно підключити дисплей по 4-х бітній шині до налагоджувальної плати STM32F4 і вивести на нього будь-який текст.
Отже, почнемо з підключення. Існує два типи підключення подібних дисплеїв: по 4-х і 8-ми бітним шинам, при цьому суттєвої різниці між ними немає, тому зупинимося на першій, оскільки вона вимагає меншої кількості проводників.
Схема підключення показана на малюнку нижче.
Слід зазначити один дуже важливий момент: 1 вивід — " +5В " і 2 — "GND", на багатьох дисплеях поміняні місцями, тому перш ніж підключити дисплей, прочитайте даташит. Неправильне підключення може призвести до виходу дисплея з ладу.
Зібрати налагоджувальну плату і дисплей в один пристрій можна різними способами. Можна просто розпаяти проводками, можна розвести друковану плату-перехідник, а можна зібрати перехідник на макетній платі, як показано на фото.
Тепер перейдемо до прошивки. Виконаємо її у вигляді окремої бібліотеки, щоб у подальшому спростити підключення дисплея в інших проектах — додаєте файл у проект і використовуєте. Бібліотеку назвемо lcd.h. У бібліотеці міститься наступний код:
//---Переопределяем порты для подключения дисплея, для удобства---// #define LCM_OUT GPIOB->ODR #define LCM_PIN_RS GPIO_Pin_0 // PB0 #define LCM_PIN_EN GPIO_Pin_1 // PB1 #define LCM_PIN_D7 GPIO_Pin_7 // PB7 #define LCM_PIN_D6 GPIO_Pin_6 // PB6 #define LCM_PIN_D5 GPIO_Pin_5 // PB5 #define LCM_PIN_D4 GPIO_Pin_4 // PB4 #define LCM_PIN_MASK ((LCM_PIN_RS | LCM_PIN_EN | LCM_PIN_D7 | LCM_PIN_D6 | LCM_PIN_D5 | LCM_PIN_D4)) GPIO_InitTypeDef GPIO_InitStructure; //---Функция задержки---// void delay(int a) { int i = 0; int f = 0; while(f < a) { while(i<60) {i++;} f++; } } //---Нужная функция для работы с дисплеем, по сути "дергаем ножкой" EN---// void PulseLCD() { LCM_OUT &= ~LCM_PIN_EN; delay(220); LCM_OUT |= LCM_PIN_EN; delay(220); LCM_OUT &= (~LCM_PIN_EN); delay(220); } //---Отсылка байта в дисплей---// void SendByte(char ByteToSend, int IsData) { LCM_OUT &= (~LCM_PIN_MASK); LCM_OUT |= (ByteToSend & 0xF0); if (IsData == 1) LCM_OUT |= LCM_PIN_RS; else LCM_OUT &= ~LCM_PIN_RS; PulseLCD(); LCM_OUT &= (~LCM_PIN_MASK); LCM_OUT |= ((ByteToSend & 0x0F) << 4); if (IsData == 1) LCM_OUT |= LCM_PIN_RS; else LCM_OUT &= ~LCM_PIN_RS; PulseLCD(); } //---Установка позиции курсора---// void Cursor(char Row, char Col) { char address; if (Row == 0) address = 0; else address = 0x40; address |= Col; SendByte(0x80 | address, 0); } //---Очистка дисплея---// void ClearLCDScreen() { SendByte(0x01, 0); SendByte(0x02, 0); } //---Инициализация дисплея---// void InitializeLCD(void) { RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0 | GPIO_Pin_1| GPIO_Pin_4 | GPIO_Pin_5| GPIO_Pin_6| GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOB, &GPIO_InitStructure); LCM_OUT &= ~(LCM_PIN_MASK); delay(32000); delay(32000); delay(32000); LCM_OUT &= ~LCM_PIN_RS; LCM_OUT &= ~LCM_PIN_EN; LCM_OUT = 0x20; PulseLCD(); SendByte(0x28, 0); SendByte(0x0E, 0); SendByte(0x06, 0); } //---Печать строки---// void PrintStr(char *Text) { char *c; c = Text; while ((c != 0) && (*c != 0)) { SendByte(*c, 1); c++; } }
Пройдемося по основним функціям бібліотеки:
InitializeLCD( ) — ініціалізація дисплея, необхідно виконувати при старті програми.
InitializeLCD(); //Ініціалізація дисплея
ClearLCDScreen( )- очистка пам’яті дисплея.
ClearLCDScreen(); //Очистка пам’яті дисплея
Cursor(№ строки, № столбця) — установка позиції курсора, відлік починається з нульового рядка і нульового стовпця.
Cursor(0,2); //Установка курсора, 0-ий рядок, 2-ий стовпець
PrintStr(текст) — написання рядка на дисплеї.
PrintStr("CXEM.NET");
SendByte(байт, режим) — якщо коротко, то ця функція відправляє байт у дисплей. Якщо параметр «режим» дорівнює «1», то на дисплеї з’явиться символ, а якщо «0» - то байт буде прийнятий дисплеєм у режимі налаштування. Наприклад, очистка дисплея, установка курсора або вибір типу курсора.
SendByte(0b00001100, 0); //Курсор вимкнений
З бібліотекою закінчили. Тепер пора запускати дисплей. Для цього в основному файлі main.c потрібно написати наступний код:
#include "stm32f4xx.h" #include "stm32f4xx_gpio.h" #include "stm32f4xx_rcc.h" #include "lcd.h" int main(void) { InitializeLCD(); //Ініціалізація дисплея ClearLCDScreen(); //Очистка дисплея від сміття Cursor(0,2); //Установка курсора PrintStr("Specially for"); //Написання тексту Cursor(1,4); PrintStr("CXEM.NET"); while(1) { } }
Думаю по коментарях все зрозуміло. Тепер залишається скомпілювати код і прошити плату. Робимо перезавантаження і насолоджуємося написаним.
В заключенні хотілося б показати, як змінювати вид курсора. Існує три режими: без курсора, курсор у вигляді нижнього підкреслення і миготливий курсор.
Для вимкнення курсора виконуємо:
SendByte(0b00001100, 0); //Курсор вимкнений
Для нижнього підкреслення:
SendByte(0b00001110, 0); //Курсор не мигає
Для миготливого:
SendByte(0b00001111, 0); //Курсор миготить
Прикріплені файли:
- Lesson_5.rar (139 Кб)