Урок 72
Часть 1
Touch panel FT5336
Продолжаем работу с отладочной платой STM32F746G-DISCO и изучать её интересные элементы. Мы уже изрядно изучили её дисплей LCD, теперь настало время изучить панель Toush Screen, установленную на данном дисплее. Тем более без этого экран теряет свою интерактивность, и становится, как говорится, доступным «только для чтения». Нам это не подходит, так как мы хотим управлять процессами, поэтому обойти тему ввода информации через Touch Screen нам никак не получится.
Контроллер у данной панели представлен компанией FocalTech и маркируется FT5336. К сожелению, найти подробную техническую документацию к данному контроллеру (или драйверу) мне не удалось, только краткую, которую я, разумеется, прикреплю внизу страницы. В данной документации представлен протокол передачи данных, которая происходит посредством шины I2C, также даны все электрические и временные характеристики. Но здесь нет не то что идентификаторов, а даже адреса устройства, по которому мы к нему сможем обращаться. Мало того, данный контроллер является полноправным, то есть присутствует масса регистров, и описание данных регистров здесь не представлено.
Но, к счастью, мне в разборе этой темы помог исходный код из примеров Cube, а также техническая документация на подобные контроллеры TS, и мне удалось всё-таки научить данный Toushscreen откликаться и давать нам информацию о наших действиях и координатах. Данная панель является полноправным тачскрином, то есть поддерживается мультитач, отслеживаются действия одновременно пяти пальцев рук. Есть также регистры для хранения событий жестов, из которых почему-то читается постоянно ноль — нет жеста. Возможно, жесты не поддерживаются данным контроллером и регистры туда добавлены из соображений совместимости. Может это, конечно, и не так, но, во всяком случае, мне не удалось данные жесты идентифицировать. Если в последствии всё же как-то жесты откликнутся, то я обязательно этим с вами поделюсь и дам отдельный урок. А пока и без этого с данным устройством предстоит очень много работы, так что наберитесь терпения. Начнём.
Также скажу, что Toushscreen наш является емкостным, что придаёт нашему дисплею удобство в интерактивности.
Так как нам потребуются все функции нашего дисплея, то проект, соответственно, мы сотворим из проекта урока 70 по выводу текста на экран LTDC_TEXT и назовём его TOUCH_FT5336.
Запустим проект в Cube MX и включим в нём шину I2C
Ножку SCL переопределим на PH7, после этого ножки I2C будут у нас на ножках портов PH7 и PH8
Сделано это согласно схемы на нашу плату
Также включим ножку порта PI11 на вход. Это синяя кнопка на плате
Зайдём в I2C в разделе Configuration и настроим там сразу адрес Slave
Адрес также указан в схеме
Двоичное 01110000 равно шестнадцатеричному 70h и десятичному 112. Также всё равно потом в коде мы будем оперировать адресом явно.
Теперь генерируем проект для System WorkBench и открываем его там, перед этим на всякий случай удалив оттуда все проекты. После добавления проекта также удалим из секции Run/Debug Settings настроек все пункты. Откроем файл main.c и попытаемся собрать наш проект.
Также попробуем проект прошить через отладку и запустить его. Если нормально работает старый код на плате, то останавливаем отладку и запустим проект обычным штатным образом через Run.
Теперь начнём сочинять свою библиотеку по работе с тачскрином, соответственно добавив для этой цели новый модуль. Создадим пару файлов ft5336.h и ft5336.c со стандартным содержимым
ft5336.h:
#ifndef __FT5336_H
#define __FT5336_H
//------------------------------------------
#include "stm32f7xx_hal.h"
#include <string.h>
#include <stdlib.h>
//------------------------------------------
//------------------------------------------
#endif /* __FT5336_H */
ft5336.c:
#include "ft5336.h"
//----------------------------------------
В файл ft5336.c подключим библиотеку ltdc и напишем функцию обработки ошибок
#include "ft5336.h"
#include "ltdc.h"
//----------------------------------------
void Error(void)
{
TFT_FillScreen(LCD_COLOR_RED);
}
//----------------------------------------
То есть при вызове обраотчика ошибок экран будет светиться красным цветом (это вместо красного светодиода).
Далее добавим функцию инициализации нашего тачскрина
//----------------------------------------
void Touch_Ini(void)
{
uint8_t regValue = 0;
HAL_Delay(200);
}
//----------------------------------------
Создадим на данную функцию прототип, затем подключим нашу библиотеку в файле main.c
#include "MT48LC4M32B2.h"
#include "ft5336.h"
/* USER CODE END Includes */
Затем вызовем нашу функцию инициализации в main()
TFT_FillScreen(LCD_COLOR_BLACK);
Touch_Ini();
if(f_mount(&SDFatFs, (TCHAR const*)SD_Path, 0) != FR_OK)
Вернёмся в ft5336.c и добавим указатель на периферию I2C
#include "ltdc.h"
//----------------------------------------
extern I2C_HandleTypeDef hi2c3;
//----------------------------------------
Немного выше функции инициализации добавим функцию чтения байта из шины I2C
//----------------------------------------
uint8_t TS_IO_Read(uint8_t Addr, uint8_t Reg)
{
uint8_t read_value = 0;
HAL_I2C_Mem_Read(&hi2c3, Addr, (uint16_t)Reg, I2C_MEMADD_SIZE_8BIT, &read_value, 1, 0x1000);
return read_value;
}
//----------------------------------------
Функция эта простейшая и в объяснении не нуждается.
Теперь нам потребуются некоторые макросы для удобного обращения к регистрам, адресам, битам нашей микросхемы-драйвера тачскрина. Я уже заранее это всё подготовил, поэтому добавим их сразу все в заголовочный файл ft5336.h
#define TS_SWAP_NONE ((uint8_t) 0x01)
#define TS_SWAP_X ((uint8_t) 0x02)
#define TS_SWAP_Y ((uint8_t) 0x04)
#define TS_SWAP_XY ((uint8_t) 0x08)
//------------------------------------------
#define TS_I2C_ADDRESS ((uint16_t)0x70)
#define FT5336_ID_VALUE ((uint8_t)0x51)
#define FT5336_TD_STAT_REG ((uint8_t)0x02)
#define FT5336_GMODE_REG ((uint8_t)0xA4)
#define FT5336_CHIP_ID_REG ((uint8_t)0xA8)
#define FT5336_G_MODE_INTERRUPT_POLLING ((uint8_t)0x00)
#define FT5336_G_MODE_INTERRUPT_MASK ((uint8_t)0x03)
#define FT5336_TD_STAT_MASK ((uint8_t)0x0F)
#define FT5336_G_MODE_INTERRUPT_SHIFT ((uint8_t)0x00)
#define FT5336_GEST_ID_REG ((uint8_t)0x01)
//------------------------------------------
/* Possible values of FT5336_GEST_ID_REG */
#define FT5336_GEST_ID_NO_GESTURE ((uint8_t)0x00)
#define FT5336_GEST_ID_MOVE_UP ((uint8_t)0x10)
#define FT5336_GEST_ID_MOVE_RIGHT ((uint8_t)0x14)
#define FT5336_GEST_ID_MOVE_DOWN ((uint8_t)0x18)
#define FT5336_GEST_ID_MOVE_LEFT ((uint8_t)0x1C)
#define FT5336_GEST_ID_SINGLE_CLICK ((uint8_t)0x20)
#define FT5336_GEST_ID_DOUBLE_CLICK ((uint8_t)0x22)
#define FT5336_GEST_ID_ROTATE_CLOCKWISE ((uint8_t)0x28)
#define FT5336_GEST_ID_ROTATE_C_CLOCKWISE ((uint8_t)0x29)
#define FT5336_GEST_ID_ZOOM_IN ((uint8_t)0x40)
#define FT5336_GEST_ID_ZOOM_OUT ((uint8_t)0x49)
#define FT5336_I2C_NOT_INITIALIZED ((uint8_t)0x00)
#define FT5336_I2C_INITIALIZED ((uint8_t)0x01)
#define FT5336_MAX_DETECTABLE_TOUCH ((uint8_t)0x05)
//------------------------------------------
#define FT5336_TOUCH_POS_MSB_MASK ((uint8_t)0x0F)
#define FT5336_TOUCH_POS_MSB_SHIFT ((uint8_t)0x00)
#define FT5336_TOUCH_POS_LSB_MASK ((uint8_t)0xFF)
#define FT5336_TOUCH_POS_LSB_SHIFT ((uint8_t)0x00)
//------------------------------------------
#define FT5336_P1_XH_REG ((uint8_t)0x03)
#define FT5336_P1_XL_REG ((uint8_t)0x04)
#define FT5336_P1_YH_REG ((uint8_t)0x05)
#define FT5336_P1_YL_REG ((uint8_t)0x06)
#define FT5336_P2_XH_REG ((uint8_t)0x09)
#define FT5336_P2_XL_REG ((uint8_t)0x0A)
#define FT5336_P2_YH_REG ((uint8_t)0x0B)
#define FT5336_P2_YL_REG ((uint8_t)0x0C)
#define FT5336_P3_XH_REG ((uint8_t)0x0F)
#define FT5336_P3_XL_REG ((uint8_t)0x10)
#define FT5336_P3_YH_REG ((uint8_t)0x11)
#define FT5336_P3_YL_REG ((uint8_t)0x12)
#define FT5336_P4_XH_REG ((uint8_t)0x15)
#define FT5336_P4_XL_REG ((uint8_t)0x16)
#define FT5336_P4_YH_REG ((uint8_t)0x17)
#define FT5336_P4_YL_REG ((uint8_t)0x18)
#define FT5336_P5_XH_REG ((uint8_t)0x1B)
#define FT5336_P5_XL_REG ((uint8_t)0x1C)
#define FT5336_P5_YH_REG ((uint8_t)0x1D)
#define FT5336_P5_YL_REG ((uint8_t)0x1E)
#define FT5336_P6_XH_REG ((uint8_t)0x21)
#define FT5336_P6_XL_REG ((uint8_t)0x22)
#define FT5336_P6_YH_REG ((uint8_t)0x23)
#define FT5336_P6_YL_REG ((uint8_t)0x24)
#define FT5336_P7_XH_REG ((uint8_t)0x27)
#define FT5336_P7_XL_REG ((uint8_t)0x28)
#define FT5336_P7_YH_REG ((uint8_t)0x29)
#define FT5336_P7_YL_REG ((uint8_t)0x2A)
#define FT5336_P8_XH_REG ((uint8_t)0x2D)
#define FT5336_P8_XL_REG ((uint8_t)0x2E)
#define FT5336_P8_YH_REG ((uint8_t)0x2F)
#define FT5336_P8_YL_REG ((uint8_t)0x30)
#define FT5336_P9_XH_REG ((uint8_t)0x33)
#define FT5336_P9_XL_REG ((uint8_t)0x34)
#define FT5336_P9_YH_REG ((uint8_t)0x35)
#define FT5336_P9_YL_REG ((uint8_t)0x36)
#define FT5336_P10_XH_REG ((uint8_t)0x39)
#define FT5336_P10_XL_REG ((uint8_t)0x3A)
#define FT5336_P10_YH_REG ((uint8_t)0x3B)
#define FT5336_P10_YL_REG ((uint8_t)0x3C)
//------------------------------------------
#define FT5336_P1_WEIGHT_REG ((uint8_t)0x07)
#define FT5336_P1_MISC_REG ((uint8_t)0x08)
#define FT5336_P2_WEIGHT_REG ((uint8_t)0x0D)
#define FT5336_P2_MISC_REG ((uint8_t)0x0E)
#define FT5336_P3_WEIGHT_REG ((uint8_t)0x13)
#define FT5336_P3_MISC_REG ((uint8_t)0x14)
#define FT5336_P4_WEIGHT_REG ((uint8_t)0x19)
#define FT5336_P4_MISC_REG ((uint8_t)0x1A)
#define FT5336_P5_WEIGHT_REG ((uint8_t)0x1F)
#define FT5336_P5_MISC_REG ((uint8_t)0x20)
#define FT5336_P6_WEIGHT_REG ((uint8_t)0x25)
#define FT5336_P6_MISC_REG ((uint8_t)0x26)
#define FT5336_P7_WEIGHT_REG ((uint8_t)0x2B)
#define FT5336_P7_MISC_REG ((uint8_t)0x2C)
#define FT5336_P8_WEIGHT_REG ((uint8_t)0x31)
#define FT5336_P8_MISC_REG ((uint8_t)0x32)
#define FT5336_P9_WEIGHT_REG ((uint8_t)0x37)
#define FT5336_P9_MISC_REG ((uint8_t)0x38)
#define FT5336_P10_WEIGHT_REG ((uint8_t)0x3D)
#define FT5336_P10_MISC_REG ((uint8_t)0x3E)
//------------------------------------------
#define FT5336_TOUCH_EVT_FLAG_PRESS_DOWN ((uint8_t)0x00)
#define FT5336_TOUCH_EVT_FLAG_LIFT_UP ((uint8_t)0x01)
#define FT5336_TOUCH_EVT_FLAG_CONTACT ((uint8_t)0x02)
#define FT5336_TOUCH_EVT_FLAG_NO_EVENT ((uint8_t)0x03)
//------------------------------------------
#define FT5336_TOUCH_EVT_FLAG_SHIFT ((uint8_t)0x06)
#define FT5336_TOUCH_EVT_FLAG_MASK ((uint8_t)(3 << FT5336_TOUCH_EVT_FLAG_SHIFT))
#define FT5336_TOUCH_WEIGHT_MASK ((uint8_t)0xFF)
#define FT5336_TOUCH_WEIGHT_SHIFT ((uint8_t)0x00)
#define FT5336_TOUCH_AREA_MASK ((uint8_t)(0x04 << 4))
#define FT5336_TOUCH_AREA_SHIFT ((uint8_t)0x04)
//------------------------------------------
#define TS_MAX_NB_TOUCH ((uint32_t) FT5336_MAX_DETECTABLE_TOUCH)
Теперь опять вернёмся в ft5336.c и добавим функцию чтения идентификатора микросхемы сразу после функции чтения байта из шины I2C
//----------------------------------------
uint16_t Touch_ReadID(uint16_t DeviceAddr)
{
volatile uint8_t ucReadId = 0;
uint8_t nbReadAttempts = 0;
int8_t bFoundDevice = 0;
for(nbReadAttempts = 0; ((nbReadAttempts < 3) && !(bFoundDevice)); nbReadAttempts++)
{
ucReadId = TS_IO_Read(DeviceAddr, FT5336_CHIP_ID_REG);
if(ucReadId == FT5336_ID_VALUE)
{
bFoundDevice = 1;
}
}
return (ucReadId);
}
//----------------------------------------
Идентификатор читаем с трёх попыток, а то вдруг сразу не считается.
Теперь вызовем эту функцию в функции инициализации тачскрина
HAL_Delay(200);
if(Touch_ReadID(TS_I2C_ADDRESS) != FT5336_ID_VALUE) Error();
}
Перейдём в файл main.c и в функции main() после вызова функции инициализации тачскрина добавим задержку в 1 секунду для того, чтобы, если будет ошибка и экран засветится красным цветом, мы успели это увидеть
Touch_Ini();
HAL_Delay(1000);
Также в этой же главной функции, а также в функции копирования файла Bmp в память исправим код закрашивания экрана в красный цвет, чтобы он действительно закрашивался в него
TFT_FillScreen(LCD_COLOR_RED); //в случае неудачи окрасим экран в красный цвет
Соберём код, прошьём контроллер для того, чтобы проверить, что идентификатор благополучно считан.
Перейдём в заголовочный файл ft5336.h и добавим там структуру
#define TS_MAX_NB_TOUCH ((uint32_t) FT5336_MAX_DETECTABLE_TOUCH)
//------------------------------------------
typedef struct
{
uint8_t i2cInitialized;
uint8_t currActiveTouchNb;
uint8_t currActiveTouchIdx;
} ft5336_handle_TypeDef;
//------------------------------------------
void Touch_Ini(void);
Вернёмся в файл ft5336.c и добавим две глобальные переменные, одну из которых инициализируем сразу
extern I2C_HandleTypeDef hi2c3;
//----------------------------------------
static ft5336_handle_TypeDef ft5336_handle = {FT5336_I2C_NOT_INITIALIZED, 0, 0};
static uint8_t tsOrientation;
//----------------------------------------
После функции чтения из шины I2C добавим фукнцию записи в эту шину
//----------------------------------------
void TS_IO_Write(uint8_t Addr, uint8_t Reg, uint8_t Value)
{
HAL_StatusTypeDef status = HAL_OK;
HAL_I2C_Mem_Write(&hi2c3, Addr, (uint16_t)Reg, I2C_MEMADD_SIZE_8BIT, &Value, 1, 0x1000);
if(status != HAL_OK) Error();
}
//----------------------------------------
Теперь продолжим писать функцию инициализации.
Установим горизонтальную ориентацию
if(Touch_ReadID(TS_I2C_ADDRESS) != FT5336_ID_VALUE) Error();
tsOrientation = TS_SWAP_XY;
}
На этом мы пока на сегодня закончим.
В следующей части занятия мы закончим писать функцию инициализации тачскрина, а также начнём писать код процесса отслеживания различных действий TS.
Предыдущий урок Программирование МК STM32 Следующая часть
Техническая документация на драйвер TS FT5336
Отладочную плату можно приобрести здесь STM32F746G-DISCOVERY
Смотреть ВИДЕОУРОК в RuTube (нажмите на картинку)
Смотреть ВИДЕОУРОК в YouTube (нажмите на картинку)
Добавить комментарий