середа, 23 жовтня 2019 р.

STM32: Бібліотека touchscreen XPT2046 по шині SPI


Передмова

В попередній статті "Бібліотека дисплею ILI9341 по інтерфейсу FSMC" розібрались як виводити зображення на екран дисплею. А в цій статті обговоримо, як зчитувати координати сенсорної панелі при натисканні на неї.
Цей дисплей оснащено резистивним touchscreen який обслуговує контролер XPT2046 або ADS7843. Цей контролер є 12 бітним дискретизатором аналогово-цифрового перетворювача, при натисканні на панель, зчитує напругу по координатам X, Y. Значення напруги перетворює за допомоги АЦП в дискретні значення, та виставляє сигнал готовності даних. По синхронному послідовному інтерфейсу (SPI) можемо запросити дискретні значення координат X та Y зі швидкістю 1.5 - 2.5 Mbits/sec.

CubeMX

За основу візьмемо проект з попередньої статті. Згідно схеми, сенсорну панель підключено до SPI2 мікроконтролеру, де T_SCK - PB13, T_MISO - PB14, T_MOSI - PB15, сигнал чип-селект T_CS - PB12, а сигнал готовності даних при натисканні T_IRQ (T_PEN) - PC5 (виділено червоним):
Схема підключення touchscreen
Завантажимо до CubeMX проект з попередньої статті. В мене це "STM32F407VE_Black_ILI9341.ioc", робимо потрібні налаштування та зберігаємо з іншим ім'ям, як окремий проект.

Налаштування для роботи з touchscreen

Налаштування SPI:

Налаштування SPI
  1. В розділі "Connectivity" обираємо SPI2;
  2. Mode -> Full-Duplex Master;
  3. Prescaller -> 32 (можна спробувати 16), щоб Baud Rate було 1.3125 Mbits/s (2.625 Mbits/s);
  4. Перевірте щоб SPI2 був на шпильках як зазначено на малюнку.

Налаштування GPIO для Chip Select:

Налаштування T_CS
  1. В розділі "System Core" обираємо GPIO;
  2. Тиснемо на PB12;
  3. Налаштовуємо як на малюнку GPIO output level -> High, GPIO mode -> Output Push Pull, GPIO Pull-up, Maximum output speed -> High, User Label -> T_CS;
  4. Перевіряємо щоб назва PB12 була T_CS.

Налаштування GPIO для T_IRQ:

Налаштування T_IRQ
  1. В розділі "System Core" обираємо GPIO;
  2. Тиснемо на PC5;
  3. Налаштовуємо як на малюнку. GPIO mode -> External Interrupt Mode with Rising/Falling edge trigger detection, GPIO Pull-up, User Label -> T_IRQ;
  4. Перевіряємо щоб назва PC5 була T_IRQ.

Налаштування переривання від шпильки T_IRQ:

Налаштування переривань

  1. В розділі "System Core" обираємо NVIC;
  2. Позначаємо "галочкою" (checkbox) "EXTI line [9:5] interrupts".
Налаштування FSMC залишаємо як є з попередньої статті. Або, як проект створили новий, то налаштовуємо, як в статті "STM32: Бібліотека дисплею ILI9341 по інтерфейсу FSMC".

Зберігаємо проект, та генеруємо код проекту. Відкриваємо чи експортуємо проект до свого засобу розробки.

Бібліотека touch screen

Взяв за основу бібліотеку у користувача github . Виправив одну помилку, а так залишив як є. Оригінал бібліотеки за ланкою. Ланка на мою бібліотеку touchscreen. Бібліотека складається з двох файлів XPT2046_touch.h та XPT2046_touch.c 

Налаштування бібліотеки:

#define XPT2046_SPI_PORT hspi2
extern SPI_HandleTypeDef ILI9341_TOUCH_SPI_PORT;

#define XPT2046_IRQ_Pin       T_IRQ_Pin
#define XPT2046_IRQ_GPIO_Port T_IRQ_GPIO_Port
#define XPT2046_CS_Pin        T_CS_Pin
#define XPT2046_CS_GPIO_Port  T_CS_GPIO_Port

// change depending on screen orientation
#define XPT2046_SCALE_X 240
#define XPT2046_SCALE_Y 320

// to calibrate uncomment UART_Printf line in ili9341_touch.c
#define XPT2046_MIN_RAW_X 3400
#define XPT2046_MAX_RAW_X 29000
#define XPT2046_MIN_RAW_Y 3300
#define XPT2046_MAX_RAW_Y 30000
  1. Назначаємо на якому SPI "сидить" touch панель;
  2. Назначаємо порт і номер шпильки де під'єднано сигнали chip select та сигнал переривання про готовність даних (T_CS, T_IRQ);
  3. Задаємо розподільну здатність екрану по X та Y;
  4. Калібровочні значення touch панелі.
Якщо ви створили проект за допомоги CubeMX, як зазначено вище, то налаштування бібліотеки залишаються як є і додаткових налаштувань не потребує.

Додайте файли бібліотеки до свого проекту. Відкрийте файл "main.c" та додайте рядок:
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "XPT2046_touch.h"
/* USER CODE END Includes */
Спробуйте зкомпілювати проект. Як немає помилок, спробуємо щось намалювати за допомоги touch screen.

Малюємо за допомоги touch screen

Щоб можна було малювати на дисплеї ILI9341 додайте до проекту файли бібліотеки дисплею ILI9341, як зазначено в попередній статті. Це тека inc та src.

Додайте до коду в файл "main.c" проекту рядок з вкладенням файлу бібліотеки дисплея:
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "ili9341.h"
#include "XPT2046_touch.h"
/* USER CODE END Includes */
Спробуйте зкомпілювати проект. Як немає помилок, йдемо далі.

Додайте до коду в файл "main.c" в користувацьку секцію 2 такий код:
/* USER CODE BEGIN 2 */
  lcdBacklightOn();
  lcdInit();
  lcdSetOrientation(LCD_ORIENTATION_PORTRAIT);
  lcdFillRGB(COLOR_BLACK);
  /* USER CODE END 2 */
Вмикаємо підсвітку екрану, ініціалізуємо дисплей, задаємо орієнтацію дисплею, очищаємо дисплей чорним кольором.

В користувацьку секцію 4 файлу "main.c"додайте callback функцію:
void HAL_GPIO_EXTI_Callback (uint16_t GPIO_Pin)
{
 if (GPIO_Pin == T_IRQ_Pin)
 {
  if(XPT2046_TouchPressed())
  {
   uint16_t x = 0, y = 0;
   if(XPT2046_TouchGetCoordinates(&x, &y))
   {
    lcdFillCircle((lcdGetWidth() - x), y, 2, COLOR_GREENYELLOW);
   }
  }

 }
}
До цієї функції мікроконтролер буде потрапляти кожного разу коли ви будете натискати (малювати) на touch панелі. Тут буде перевірятись чи натиснуто на панель, і якщо так, то будуть братись координати натискання, та по цим координатам намалюємо маленьке зафарбоване коло жовто-зеленого кольору.

Компілюйте, заливайте і малюйте.

Приклад роботи

Приклад роботи

2 коментарі:

  1. навищо залаштував T_IRQ якщр його не користуешь?

    ВідповістиВидалити
    Відповіді
    1. Как это не использует - а Callback ведь вызывается прерыванием

      Видалити