Library for virtual onscreen keyboard for STM32F746 Disco board

Dependencies:   BSP_DISCO_F746NG mbed

Files at this revision

API Documentation at this revision

Comitter:
Faberge
Date:
Sat Sep 17 11:36:24 2016 +0000
Commit message:
First demo example of virtual onscreen keyboard for F746 Disco

Changed in this revision

BSP_DISCO_F746NG.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
other/readme.txt Show annotated file Show diff for this revision Revisions of this file
user/keyboard.c Show annotated file Show diff for this revision Revisions of this file
user/keyboard.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BSP_DISCO_F746NG.lib	Sat Sep 17 11:36:24 2016 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/teams/ST/code/BSP_DISCO_F746NG/#458ab1edf6b2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sat Sep 17 11:36:24 2016 +0000
@@ -0,0 +1,75 @@
+/*
+ *******************************************************************************
+ * Пример работы экранной клавиатуры на демо-плате STM32F746NG Discovery с
+ * использованием стандартного набора библиотек BSP и пользовательской
+ * библиотеки "keyboard.h"
+ *******************************************************************************
+ */
+
+/* Добавляем библиотеку для работы с LCD */
+#include "stm32746g_discovery_lcd.h"
+
+/* Добавляем библиотеку экранной клавиатуры */
+#include "keyboard.h"
+
+/* Вспомогательные переменые */
+uint8_t i;
+uint8_t key;
+uint8_t len;
+
+/* Пользовательский буфер */
+char buffer[45];
+
+/* Основная программа */
+int main(void)
+{
+    /* Инициализация дисплея */
+    BSP_LCD_Init();
+    BSP_LCD_LayerDefaultInit(0, LCD_FB_START_ADDRESS);
+    BSP_LCD_LayerDefaultInit(1, LCD_FB_START_ADDRESS + (BSP_LCD_GetXSize() * BSP_LCD_GetYSize() * 4));
+
+    /* Включаем дисплей */
+    BSP_LCD_DisplayOn();
+
+    /* Настраиваем первый и второй слои дисплея */
+    BSP_LCD_SelectLayer(0);
+    BSP_LCD_Clear(LCD_COLOR_WHITE);
+    BSP_LCD_SelectLayer(1);
+    BSP_LCD_Clear(LCD_COLOR_BLACK);
+    BSP_LCD_SetTransparency(0, 0);
+    BSP_LCD_SetTransparency(1, 100);
+
+    /* Настраиваем цвет фона экрана и цвет текста, а также шрифт  */
+    BSP_LCD_SetTextColor(LCD_COLOR_LIGHTGREEN);
+    BSP_LCD_SetBackColor(LCD_COLOR_BLACK);
+    BSP_LCD_SetFont(&Font16);
+
+    /* Инициализация тач-экрана*/
+    BSP_TS_Init(BSP_LCD_GetXSize(), BSP_LCD_GetYSize());
+    
+    /* Инициализация клавиатуры */
+    Keyboard_init(0, 80);
+    
+    /* Основной цикл */
+    while(1) 
+    {
+        /* Вызываем обработчик экранной клавиатуры */
+        key = Keyboard_handler(buffer);
+        
+        /* Если последней нажатой клавишей был "Enter", значит, пользовательский
+         * ввод завершен и его можно как-то обработать
+         */
+        if (key == KEY_ENTER_VALUE)
+        {
+            /* Пользовательская реализация обработки ввода должна быть тут */
+            
+            /* Затираем строчку со старым буфером и отображаем новый */
+            BSP_LCD_ClearStringLine(1);
+            BSP_LCD_DisplayStringAtLine(1, (uint8_t *) buffer);
+            buffer[0] = '\0';
+        }
+        
+        /* Задержка на 10 мс */
+        HAL_Delay(10);
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Sat Sep 17 11:36:24 2016 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/6c34061e7c34
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/other/readme.txt	Sat Sep 17 11:36:24 2016 +0000
@@ -0,0 +1,10 @@
+Библиотека: "keyboard.h"
+Версия:     0.1
+Автор:      faberge
+Дата:       17.09.2016
+
+Важно: если пример не работает/работает неправильно/не компилируется:
+1) Проверьте версию компилятора mbed, текущая версия может некорректно работать
+с поставляемыми библиотеками BSP для демо-платы Discovery. В таком случае, 
+рекомендуется использовать версию 121. 
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/user/keyboard.c	Sat Sep 17 11:36:24 2016 +0000
@@ -0,0 +1,480 @@
+/*
+ *******************************************************************************
+ * Библиотека Keyboard виртуальной клавиатуры для дисплея с тач-экраном на демо-
+ * плате STM32F746NG Discovery
+ *
+ * Файл "keyboard.c"
+ *******************************************************************************
+ */  
+
+/* Добавляем заголовочный файл */
+#include "keyboard.h"
+
+/* Структуры клаватуры и тач-экрана */
+Keyboard_TypeDef keyboard;
+TS_StateTypeDef tScreen;
+
+/* Функции для работы с экранной клавиатурой */
+
+/* Инициализация и вывод клавиатуры на дисплей */
+uint8_t Keyboard_init(uint16_t  x_value, uint16_t   y_value)
+{
+    uint8_t i;
+    
+    /* Координаты верхнего левого угла клавиатуры на экране, служат точкой
+     * отсчета для определения расположения всех остальных элементов
+     */
+    keyboard.posX = x_value;
+    keyboard.posY = y_value;
+    
+    /* По умолчанию на клавиатуре английская раскладка в верхнем регистре */
+    keyboard.mode = MODE_UPPER_CASE;
+    
+    /* Блок инициализации для стандартных клавиш */
+    
+    /* Инициализируем массив координат клавиш на клавиатуре для верхнего ряда */
+    for (i = 0; i < 10; i++)
+    {
+        keyboard.key[i].id = i;
+        keyboard.key[i].posX = keyboard.posX + 3 + (KEY_DISTANCE + KEY_SMALL_LENGTH) * i;
+        keyboard.key[i].posY = keyboard.posY + 3;
+        keyboard.key[i].dimX = KEY_SMALL_LENGTH;
+        keyboard.key[i].dimY = KEY_SMALL_HEIGHT;
+        keyboard.key[i].status = KEY_RELEASED; 
+    }
+    
+    /* Значения ASCII-кодов каждой клавишы из верхнего ряда для различных 
+     * раскладок клавиатуры 
+     */
+    keyboard.key[0].value[0] = 'Q';
+    keyboard.key[0].value[1] = 'q';
+    keyboard.key[0].value[2] = '1';
+    
+    keyboard.key[1].value[0] = 'W';
+    keyboard.key[1].value[1] = 'w';
+    keyboard.key[1].value[2] = '2';
+    
+    keyboard.key[2].value[0] = 'E';
+    keyboard.key[2].value[1] = 'e';
+    keyboard.key[2].value[2] = '3';
+    
+    keyboard.key[3].value[0] = 'R';
+    keyboard.key[3].value[1] = 'r';
+    keyboard.key[3].value[2] = '4';
+    
+    keyboard.key[4].value[0] = 'T';
+    keyboard.key[4].value[1] = 't';
+    keyboard.key[4].value[2] = '5';
+    
+    keyboard.key[5].value[0] = 'Y';
+    keyboard.key[5].value[1] = 'y';
+    keyboard.key[5].value[2] = '6';
+    
+    keyboard.key[6].value[0] = 'U';
+    keyboard.key[6].value[1] = 'u';
+    keyboard.key[6].value[2] = '7';
+    
+    keyboard.key[7].value[0] = 'I';
+    keyboard.key[7].value[1] = 'i';
+    keyboard.key[7].value[2] = '8';
+    
+    keyboard.key[8].value[0] = 'O';
+    keyboard.key[8].value[1] = 'o';
+    keyboard.key[8].value[2] = '9';
+    
+    keyboard.key[9].value[0] = 'P';
+    keyboard.key[9].value[1] = 'p';
+    keyboard.key[9].value[2] = '0';
+    
+    /* Инициализируем массив координат клавиш на клавиатуре для среднего ряда */  
+    for (i = 10; i < 19; i++)
+    {
+        keyboard.key[i].id = i;
+        keyboard.key[i].posX = keyboard.posX + 27 + (KEY_DISTANCE + KEY_SMALL_LENGTH) * (i - 10);
+        keyboard.key[i].posY = keyboard.posY + 3 + KEY_SMALL_HEIGHT + KEY_DISTANCE;
+        keyboard.key[i].dimX = KEY_SMALL_LENGTH;
+        keyboard.key[i].dimY = KEY_SMALL_HEIGHT;
+        keyboard.key[i].status = KEY_RELEASED; 
+    }
+    
+    /* Значения ASCII-кодов каждой клавишы из среднего ряда для различных
+     * раскладок клавиатуры
+     */
+    keyboard.key[10].value[0] = 'A';
+    keyboard.key[10].value[1] = 'a';
+    keyboard.key[10].value[2] = '1';
+    
+    keyboard.key[11].value[0] = 'S';
+    keyboard.key[11].value[1] = 's';
+    keyboard.key[11].value[2] = '2';
+    
+    keyboard.key[12].value[0] = 'D';
+    keyboard.key[12].value[1] = 'd';
+    keyboard.key[12].value[2] = '3';
+    
+    keyboard.key[13].value[0] = 'F';
+    keyboard.key[13].value[1] = 'f';
+    keyboard.key[13].value[2] = '4';
+    
+    keyboard.key[14].value[0] = 'G';
+    keyboard.key[14].value[1] = 'g';
+    keyboard.key[14].value[2] = '5';
+    
+    keyboard.key[15].value[0] = 'H';
+    keyboard.key[15].value[1] = 'h';
+    keyboard.key[15].value[2] = '6';
+    
+    keyboard.key[16].value[0] = 'J';
+    keyboard.key[16].value[1] = 'j';
+    keyboard.key[16].value[2] = '7';
+    
+    keyboard.key[17].value[0] = 'K';
+    keyboard.key[17].value[1] = 'k';
+    keyboard.key[17].value[2] = '8';
+    
+    keyboard.key[18].value[0] = 'L';
+    keyboard.key[18].value[1] = 'l';
+    keyboard.key[18].value[2] = '9';
+    
+    /* Инициализируем массив координат клавиш на клавиатуре для нижнего ряда */    
+    for (i = 19; i < 26; i++)
+    {
+        keyboard.key[i].id = i;
+        keyboard.key[i].posX = keyboard.posX + 51 + (KEY_DISTANCE + KEY_SMALL_LENGTH) * (i - 19);
+        keyboard.key[i].posY = keyboard.posY + 3 + (KEY_SMALL_HEIGHT + KEY_DISTANCE) * 2;
+        keyboard.key[i].dimX = KEY_SMALL_LENGTH;
+        keyboard.key[i].dimY = KEY_SMALL_HEIGHT;
+        keyboard.key[i].status = KEY_RELEASED;
+    }
+    
+    /* Значения ASCII-кодов каждой клавишы из нижнего ряда для различных
+     * раскладок лавиатуры
+     */
+    keyboard.key[19].value[0] = 'Z';
+    keyboard.key[19].value[1] = 'z';
+    keyboard.key[19].value[2] = '1';
+    
+    keyboard.key[20].value[0] = 'X';
+    keyboard.key[20].value[1] = 'x';
+    keyboard.key[20].value[2] = '2';
+    
+    keyboard.key[21].value[0] = 'C';
+    keyboard.key[21].value[1] = 'c';
+    keyboard.key[21].value[2] = '3';
+    
+    keyboard.key[22].value[0] = 'V';
+    keyboard.key[22].value[1] = 'v';
+    keyboard.key[22].value[2] = '4';
+    
+    keyboard.key[23].value[0] = 'B';
+    keyboard.key[23].value[1] = 'b';
+    keyboard.key[23].value[2] = '5';
+    
+    keyboard.key[24].value[0] = 'N';
+    keyboard.key[24].value[1] = 'n';
+    keyboard.key[24].value[2] = '6';
+    
+    keyboard.key[25].value[0] = 'M';
+    keyboard.key[25].value[1] = 'm';
+    keyboard.key[25].value[2] = '7';
+    
+    /* Блок инициализации для специальных клавиш */
+    
+    /* Клавиша "Enter" */
+    keyboard.key[26].id = 26;
+    keyboard.key[26].posX = 51 + (KEY_DISTANCE + KEY_SMALL_LENGTH) * 7;
+    keyboard.key[26].posY = keyboard.posY + 3 + (KEY_SMALL_HEIGHT + KEY_DISTANCE) * 2;
+    keyboard.key[26].dimX = KEY_ENTER_LENGTH;
+    keyboard.key[26].dimY = KEY_SMALL_HEIGHT;
+    keyboard.key[26].status = KEY_RELEASED;
+    keyboard.key[26].value[0] = KEY_ENTER_VALUE;
+    keyboard.key[26].value[1] = KEY_ENTER_VALUE;
+    keyboard.key[26].value[2] = KEY_ENTER_VALUE;
+    
+    /* Клавиша "Shift" */
+    keyboard.key[27].id = 27;
+    keyboard.key[27].posX = 3;
+    keyboard.key[27].posY = keyboard.posY + 3 + (KEY_SMALL_HEIGHT + KEY_DISTANCE) * 3;
+    keyboard.key[27].dimX = KEY_SHIFT_LENGTH;
+    keyboard.key[27].dimY = KEY_SMALL_HEIGHT;
+    keyboard.key[27].status = KEY_RELEASED;
+    keyboard.key[27].value[0] = KEY_SHIFT_VALUE;
+    keyboard.key[27].value[1] = KEY_SHIFT_VALUE;
+    keyboard.key[27].value[2] = KEY_SHIFT_VALUE;
+    
+    /* Клавиша "Space" */
+    keyboard.key[28].id = 28;
+    keyboard.key[28].posX = 27 + (KEY_SMALL_LENGTH + KEY_DISTANCE) * 3;
+    keyboard.key[28].posY = keyboard.posY + 3 + (KEY_SMALL_HEIGHT + KEY_DISTANCE) * 3;
+    keyboard.key[28].dimX = KEY_SPACE_LENGTH;
+    keyboard.key[28].dimY = KEY_SMALL_HEIGHT;
+    keyboard.key[28].status = KEY_RELEASED;
+    keyboard.key[28].value[0] = KEY_SPACE_VALUE;
+    keyboard.key[28].value[1] = KEY_SPACE_VALUE;
+    keyboard.key[28].value[2] = KEY_SPACE_VALUE;
+    
+    /* Клавиша "Backspace" */
+    keyboard.key[29].id = 29;
+    keyboard.key[29].posX = keyboard.posX + 27 + (KEY_DISTANCE + KEY_SMALL_LENGTH) * 8;
+    keyboard.key[29].posY = keyboard.posY + 3 + (KEY_SMALL_HEIGHT + KEY_DISTANCE) * 3;
+    keyboard.key[29].dimX = KEY_BACKSPACE_LENGTH;
+    keyboard.key[29].dimY = KEY_SMALL_HEIGHT;
+    keyboard.key[29].status = KEY_RELEASED;
+    keyboard.key[29].value[0] = KEY_BACKSPACE_VALUE;
+    keyboard.key[29].value[1] = KEY_BACKSPACE_VALUE;
+    keyboard.key[29].value[2] = KEY_BACKSPACE_VALUE;
+    
+    /* Отрисовываем клавиатуру на экране*/
+    Keyboard_display_all();
+    
+    return 0;
+}
+
+/* Отрисовка клавиатуры на экране */
+uint8_t Keyboard_display_all(void)
+{
+    uint8_t i;
+    
+    /* Получаем значение цвета фона экрана*/
+    uint32_t back_color = BSP_LCD_GetBackColor();
+    
+    /* Закрашиваем весь экран цветом фона*/
+    BSP_LCD_Clear(back_color);
+
+    /* Отрисовываем каждую клавишу на клавиатуре */
+    for (i = 0; i < KEY_NUMBER; i++)
+    {
+        Key_display_normal(i);
+    }
+    
+    return 0;
+}
+
+/* Отрисовка отдельной клавишы клавиатуры на экране */
+uint8_t Key_display_normal(uint8_t id)
+{
+    /* Получаем значение цвета фона экрана и цвета шрифта */
+    uint32_t back_color = BSP_LCD_GetBackColor();
+    uint32_t text_color = BSP_LCD_GetTextColor();
+    
+    /* Меняем цвета и закрашиваем место для клавишы на экране цветом фона */
+    BSP_LCD_SetTextColor(back_color);
+    BSP_LCD_SetBackColor(text_color);               
+    BSP_LCD_FillRect(keyboard.key[id].posX, keyboard.key[id].posY, keyboard.key[id].dimX, keyboard.key[id].dimY);
+    
+    /* Возвращаем прежние значения цвета фона экрана и цвета шрифта*/
+    BSP_LCD_SetTextColor(text_color);
+    BSP_LCD_SetBackColor(back_color);
+    
+    /* Рисуем рамку рамку вокруг клавишы и замыкающий пиксель в нижнем правом углу */
+    BSP_LCD_DrawRect(keyboard.key[id].posX, keyboard.key[id].posY, keyboard.key[id].dimX, keyboard.key[id].dimY);
+    BSP_LCD_DrawPixel(keyboard.key[id].posX + keyboard.key[id].dimX, keyboard.key[id].posY + keyboard.key[id].dimY, text_color);
+    
+    /* Выводим значение клавишы в текущей раскладке клавиатуры */
+    BSP_LCD_DisplayChar(keyboard.key[id].posX + 8, keyboard.key[id].posY + 8, keyboard.key[id].value[keyboard.mode]);
+    
+    /* Для специальных клавиш выводим больше одного символа */
+    Key_display_specials(id);
+    
+    return 0;
+}
+
+/* Отрисовка отдельной клавишы клавиатуры на экране (в инвертированном цвете) */
+uint8_t Key_display_inverted(uint8_t id)
+{
+    uint32_t back_color = BSP_LCD_GetBackColor();
+    uint32_t text_color = BSP_LCD_GetTextColor();
+    
+    /* Закрашиваем место для клавишы на экране цветом шрифта */
+    BSP_LCD_FillRect(keyboard.key[id].posX, keyboard.key[id].posY, keyboard.key[id].dimX, keyboard.key[id].dimY);
+    
+    /* Меняем цвета и выводим значение клавишы в текущей раскладке клавиатуры */
+    BSP_LCD_SetTextColor(back_color);
+    BSP_LCD_SetBackColor(text_color);
+    BSP_LCD_DisplayChar(keyboard.key[id].posX + 8, keyboard.key[id].posY + 8, keyboard.key[id].value[keyboard.mode]);
+    
+    /* Для спецмальных клавиш выводим больше одного символа */
+    Key_display_specials(id);
+    
+    /* Возвращаем прежние значения цвета фона экрана и цвета шрифта */
+    BSP_LCD_SetTextColor(text_color);
+    BSP_LCD_SetBackColor(back_color);
+    
+    return 0;
+}
+
+/* Вывод значения специальных клавиш клавиатуры */ 
+uint8_t Key_display_specials(uint8_t id)
+{
+    /* Клавиша "Enter" */
+    if (keyboard.key[id].value[keyboard.mode] == KEY_ENTER_VALUE)
+    {
+        BSP_LCD_DisplayStringAt(keyboard.key[id].posX + 8, keyboard.key[id].posY + 8, (uint8_t *) "Enter", LEFT_MODE);
+    }
+    /* Клавиша "Shift" */
+    if (keyboard.key[id].value[keyboard.mode] == KEY_SHIFT_VALUE)
+    {
+        BSP_LCD_DisplayStringAt(keyboard.key[id].posX + 4, keyboard.key[id].posY + 8, (uint8_t *) "Shft", LEFT_MODE);
+    }
+    
+    /* Клаиша "Space" */
+    if (keyboard.key[id].value[keyboard.mode] == KEY_SPACE_VALUE)
+    {
+        BSP_LCD_DisplayStringAt(keyboard.key[id].posX + 32, keyboard.key[id].posY + 8, (uint8_t *) "Space", LEFT_MODE);
+    }
+    
+    /* Клавиша "Backspace" */
+    if (keyboard.key[id].value[keyboard.mode] == KEY_BACKSPACE_VALUE)
+    {
+        BSP_LCD_DisplayStringAt(keyboard.key[id].posX + 4, keyboard.key[id].posY + 8, (uint8_t *) "Bspc", LEFT_MODE);
+    }
+    
+    return 0;
+}
+
+/* Проверка ввода на экранной клавиатуре */
+uint8_t Keyboard_check(void)
+{
+    uint8_t i;
+    uint8_t j;
+    
+    /* Проверяем состояния драйвера тач-экрана */
+    BSP_TS_GetState(&tScreen);
+    
+    /* Если произошло касание */
+    if (tScreen.touchDetected)
+    {
+        for (i = 0; i < KEY_NUMBER; i++)
+        {
+            /* Если координаты касания лежат в границах какой-либо из ненажатых кнопок +/- 4 пикселя */
+            if (((tScreen.touchX[0] >= keyboard.key[i].posX - 4) && (tScreen.touchX[0] < keyboard.key[i].posX + keyboard.key[i].dimX + 4)) &&
+                    ((tScreen.touchY[0] >= keyboard.key[i].posY - 4) && (tScreen.touchY[0] < keyboard.key[i].posY + keyboard.key[i].dimY + 4)) && 
+                    (keyboard.key[i].status == KEY_RELEASED))
+            {
+                /* Отрисовываем нужную клавишу в инвертированном цвете*/
+                Key_display_inverted(i);
+                
+                /* Если до этого нажатие было зафиксировано на другой клавише,
+                 * отжимаем её и перерисовываем
+                 */
+                for (j = 0; j < KEY_NUMBER; j++)
+                {
+                    if (keyboard.key[j].status == KEY_PRESSED)
+                    {
+                        Key_display_normal(j);
+                        
+                        keyboard.key[j].status = KEY_RELEASED;
+                    }
+                }
+                
+                /* Меняем состояние клавишы, для которой было зафиксировано нажатие */
+                keyboard.key[i].status = KEY_PRESSED;
+                
+                /* Сбрасываем состояние драйвера тач-экрана */
+                BSP_TS_ResetTouchData(&tScreen);
+            }
+        }
+    }
+    /* Если касания нет, проверяем состояние каждой клавишы, возможно, касание 
+     * было до этого момента и следует обработать ввод
+     */
+    else
+    {
+        for (i = 0; i < KEY_NUMBER; i++)
+        {
+            /* Если клавиша в нажатом состоянии, отжимаем её и перерисовываем */
+            if (keyboard.key[i].status == KEY_PRESSED)
+            {
+                Key_display_normal(i);
+                
+                keyboard.key[i].status = KEY_RELEASED;
+                BSP_TS_ResetTouchData(&tScreen);
+                
+                /* Возвращаем пользовательский ввод */
+                return keyboard.key[i].value[keyboard.mode];
+            }
+        }
+    }
+    
+    return 0;
+}
+
+/* Обработчик ввода на экранной клавиатуре */
+uint8_t Keyboard_handler(char buffer[])
+{
+    uint8_t i;
+    uint8_t len;
+    uint8_t key;
+    
+    /* Проверяем, есть ли новое нажатие */
+    key = Keyboard_check();
+    
+    /* Если нажата стандартная клавиша или клавиша "Space" */
+    if ((key >= KEY_SPACE_VALUE) && (key != KEY_DELETE_VALUE))
+    {
+        /* Проверяем буффер клавиатуры и, если есть свободное место, добавляем
+         * символ с нажатой клавишы в буфер клавиатуры
+         */
+        i = strlen(keyboard.buffer);
+        if (i < KEY_BUFFER_LEN)
+        {
+            keyboard.buffer[i] = key;
+            keyboard.buffer[i + 1] = '\0';
+            
+            /* Отображаем буфер клавиатуры на верхней строчке дисплея */
+            BSP_LCD_ClearStringLine(0);
+            BSP_LCD_DisplayStringAtLine(0, (uint8_t *) keyboard.buffer);
+        }
+    }
+    /* Если нажата специальная клавиша */
+    else
+    {
+        /* Если нажата клавиша "Enter", то копируем данные из буфера клавиатуры
+         * в пользовательский буфер и затираем данные в буфере клавиатуры
+         */
+        if (key == KEY_ENTER_VALUE)
+        {
+            len = strlen(keyboard.buffer);
+            
+            for (i = 0; i <= len; i++)
+            {
+                buffer[i] = keyboard.buffer[i];
+            }
+            
+            keyboard.buffer[0] = '\0';
+            
+            /* Затираем верхнюю строчку на дисплее */
+            BSP_LCD_ClearStringLine(0);
+            BSP_LCD_DisplayStringAtLine(0, (uint8_t *) keyboard.buffer);
+        }
+        
+        /* Если нажата клавиша "Shift", меняем раскладку клавиатуры */
+        if (key == KEY_SHIFT_VALUE)
+        {
+            keyboard.mode = !keyboard.mode;
+            
+            for (i = 0; i < KEY_NUMBER; i++)
+            {
+                /* Выводим значение клавишы в новой раскладке */
+                BSP_LCD_DisplayChar(keyboard.key[i].posX + 8, keyboard.key[i].posY + 8, keyboard.key[i].value[keyboard.mode]);
+                Key_display_specials(i);
+            }
+        }
+        
+        /* Если нажата клавиша "Backspace", удаляем крайний символ из буфера 
+         * клавиатуры */ 
+        if (key == KEY_BACKSPACE_VALUE)
+        {
+            len = strlen(keyboard.buffer);
+            if (len != 0)
+            {
+                keyboard.buffer[len - 1] = '\0'; 
+                BSP_LCD_ClearStringLine(0);
+                BSP_LCD_DisplayStringAtLine(0, (uint8_t *) keyboard.buffer);
+            }
+        }
+    }
+    
+    /* Возвращаем значение последней нажатой клавишы */
+    return key;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/user/keyboard.h	Sat Sep 17 11:36:24 2016 +0000
@@ -0,0 +1,93 @@
+/*
+ *******************************************************************************
+ * Библиотека Keyboard виртуальной клавиатуры для дисплея с тач-экраном на демо-
+ * плате STM32F746NG Dicovery
+ * 
+ * Файл "keyboard.h"
+ *******************************************************************************
+ */
+
+/* Определяем для предотвращения множественного включения */
+#ifndef KEYBOARD_HPP
+#define KEYBOARD_HPP
+
+/* На случай использования в составе C++ проекта */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Добавляем библиотеку <string.h> для импорта функции strlen() */
+#include <string.h>
+
+/* Добавляем библиотеки для работы с LCD и контроллером тач-экрана */
+#include "stm32746g_discovery_lcd.h"
+#include "stm32746g_discovery_ts.h"
+
+/* Определения */
+/* Различные раскладки клавиатуры */
+#define MODE_NUMBER                     3
+#define MODE_UPPER_CASE                 0
+#define MODE_LOWER_CASE                 1
+#define MODE_SYMBOLS                    2
+
+/* Общее количество клавиш */
+#define KEY_NUMBER                      30
+#define KEY_BUFFER_LEN                  30
+
+/* Размеры клавиш в пикселях */
+#define KEY_SMALL_LENGTH                40
+#define KEY_SMALL_HEIGHT                40
+#define KEY_ENTER_LENGTH                88
+#define KEY_SHIFT_LENGTH                64
+#define KEY_BACKSPACE_LENGTH            64
+#define KEY_SPACE_LENGTH                136
+#define KEY_DISTANCE                    8
+
+/* ASCII-коды для специальных клавиш */
+#define KEY_ENTER_VALUE                 0x0D
+#define KEY_SHIFT_VALUE                 0x10
+#define KEY_SPACE_VALUE                 0x20
+#define KEY_BACKSPACE_VALUE             0x08
+#define KEY_DELETE_VALUE                0x7F
+
+/* Состояние клавишы */
+#define KEY_RELEASED                    0
+#define KEY_PRESSED                     1
+
+/* Структура для отдельной клавишы */
+typedef struct
+{
+    uint8_t         id;
+    uint8_t         status;
+    uint16_t        posX;
+    uint16_t        posY;
+    uint8_t         dimX;
+    uint8_t         dimY;
+    uint8_t         value[MODE_NUMBER];
+}   Key_TypeDef;
+
+/* Структура для всей клавиатуры */
+typedef struct
+{
+    uint16_t        posX;
+    uint16_t        posY;
+    Key_TypeDef key[KEY_NUMBER];
+    uint8_t         mode;    
+    char            buffer[KEY_BUFFER_LEN];
+}   Keyboard_TypeDef;
+
+/* Функции для работы с экранной клавиатурой */
+uint8_t Keyboard_init(uint16_t x_value, uint16_t y_value);
+uint8_t Keyboard_display_all(void);
+uint8_t Key_display_normal(uint8_t id);
+uint8_t Key_display_inverted(uint8_t id);
+uint8_t Key_display_specials(uint8_t id);
+uint8_t Keyboard_check(void);
+uint8_t Keyboard_handler(char buffer[]);
+
+#ifdef __cplusplus
+}
+#endif
+
+/* Конец файла "keyboard.h" */
+#endif