Практически в любой микроконтроллерной системе есть необходимость выводить информацию пользователю, именно для этих целей и будем применять наш дисплей.
Выглядит он вот так:
Хотя может ещё быть вариант с пинами в два ряда сбоку…
Управляется такой дисплей очень просто. Есть два режима: по 8 проводной шине данны и по 4ёх проводной. Будем пользоваться первой системой т.к. она проще.
Другая не намного сложнее (данные нужно слать тетрадами), но отвлечёт от всей «магии»))
Распиновка дисплея такая:
Обратите внимание, что дисплей питается от 5В в то время как контроллеры stm32 от 3,3В.
Упростим себе задачу и не будем считывать флаг занятости с устройства. Заменим эту функцию задержкой в коде. Следовательно пин 5 (RW) суем на землю.
ГРАБЛИ 1!! Пин 3 — регулировка контрастности дисплея.
Ложим её на землю видим закрашенные квадраты (таким образом можно проверить целостность дисплея). Для нормального вывода туда нужно напряжения 0,7-0,9В.
Делается это либо переменным резистором либо делителем напряжения.
Теперь разберёмся с тем как управлять. Каждая буква имеет свой код. Для латинского алфавита этот код совпадает с кодом символа (char), для русского можно создать массив с нужными кодами. Смотрите даташит.
Присоединили 8 пинов данных к ногам контроллера. Рекомендую это делать к соответствующим ногам чтобы сразу писать в регистр без сдвигов данных.
т.е.
DB7 — PC7
DB6 — PC6
и так далее…
Это всё существенно упрощает и даёт нам разбираться.
При старте дисплей нужно инициализировать послав несколько наборов данных, перед этим настроив ноги контроллера как выводы.
void lcd_init_gpio() { RCC_AHB1PeriphClockCmd(LCD_RCC_GPIO,ENABLE); GPIO_InitTypeDef init; init.GPIO_Mode = GPIO_Mode_OUT; init.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_10 | GPIO_Pin_12; init.GPIO_OType = GPIO_OType_PP; GPIO_Init(LCD_PORT,&init); }
Теперь посылаем данные.
void lcd_init() { lcd_init_gpio(); int del = 99999; GPIO_ResetBits(LCD_PORT, LCD_RS_Pin); // rs = 0 delay(del); lcd_write_data(0b00110000); //init1 delay(del); lcd_write_data(0b00110000); //init2 delay(del); lcd_write_data(0b00110000); //init3 delay(del); lcd_write_data(0b00111000); // function set 8bit 2line 5x8 dots delay(del); lcd_write_data(0b00001111); // display on + cursor underline + blinking delay(del); lcd_write_data(0b00000001); //clear delay(del); lcd_write_data(0b00000110); //entry mode set delay(del); lcd_write_data(0b00000010); // return to home delay(del); GPIO_SetBits(LCD_PORT,LCD_RS_Pin); //rs = 1 }
Обратите внимание, что пин RS нужно установить в ноль, чтобы контроллер дисплея воспринял управляющие команды. Иначе он решит что это данные.
Теперь о функции записи данных. она посылает данные на указанные в ноги.
Я соблюдал номера ног и номера разрядов данных, поэтому меня интересует только порт на который подключен дисплей.
void lcd_write_data(u16 data) { GPIO_SetBits(LCD_PORT,data | LCD_E_Pin); delay(0xFFFF); GPIO_ResetBits(LCD_PORT,LCD_E_Pin | data); }
Мы «выставляем» данные на ноги порта соединённого с lcd и устанавливаем пин E в 1.
Ждём пока данные «зарегистрируются» и устанавливаем E в ноль. Остальные пины тоже сбрасываем.
Вот и всё. Уже сейчас можно выводить порции данных на дисплей.
Но мы ещё опишем функцию для перемещения курсора:
void lcd_set_cursor(int line,int pos) { pos |= 0b10000000; if (line == 1) { pos += 0x40; } lcd_write_cmd(pos); }
line — номер строки (0 или 1)
pos — позиция. тоже от 0 до 16.
Так как коды символов совпадают, можно также написать функцию для вывода строк:
void lcd_write_str(char*str) { do { lcd_write_data(*str); }while(*++str); }
Задержку я сделал просто циклом:
void delay(unsigned int s){ while(--s > 0) { __NOP(); } }
Для работы также нужно определить константы порта и пинов RS,E
У меня вот так:
#define LCD_PORT GPIOC #define LCD_RCC_GPIO RCC_AHB1Periph_GPIOC #define LCD_E_Pin GPIO_Pin_12 #define LCD_RS_Pin GPIO_Pin_10
Вот собственно архив с либой.
зы не претендую на самый крутой код и прочее. Даю гарантию работоспособности в Eclipse + st-util + stm32f4discovery + wh1602b
Доказательства: