В сегодняшнем уроке будет рассмотрена работа с символьным 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(«BESTSCHEMES.RU»);
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(«BESTSCHEMES.RU»);
while(1)
{
}
}
Думаю по комментариям все понятно. Теперь остается скомпилировать код и прошить плату. Делаем рестарт и наслаждаемся написанным.
В заключении хотелось бы показать, как менять вид курсора. Существует три режима: без курсора, курсор в виде нижнего подчеркивания и мигающий курсор.
Для выключения курсора выполняем:
SendByte(0b00001100, 0); //Курсор выключен
Для нижнего подчеркивания:
SendByte(0b00001110, 0); //Курсор не мигает
Для мигающего:
SendByte(0b00001111, 0); //Курсор мигает
Прикрепленные файлы:
- Lesson_5.rar (139 Кб)