Графический дисплей и touchscreen.

Всем доброго дня!

Сегодня мы продолжим обсуждать работу с графическим дисплеем и на очереди у нас touchscreen.

Работа с touchscreen

В этой статье я не буду рассказывать про устройство дисплея и про то, как работает контроллер touchscreen’а. Сегодня рассмотрим библиотеку для работы с ним, а также конкретный пример, чтобы увидеть результат наших трудов. В общем, данная статья будет продолжением предыдущей: вот она.

Итак, для обмена данными с контроллером дисплея мы будем использовать интерфейс SPI, соответственно, необходимо его проинициализировать:

void TouchInit(void)
{
  GPIO_InitTypeDef GPIO_InitStruct;
  SPI_InitTypeDef  SPI_InitStructure;
 
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
 
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init (GPIOA, &GPIO_InitStruct);
 
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6;
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init (GPIOA, &GPIO_InitStruct);
 
  RCC_APB2PeriphClockCmd (RCC_APB2Periph_SPI1, ENABLE);
 
  SPI_Cmd (SPI1, DISABLE);
  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
  SPI_InitStructure.SPI_CRCPolynomial = 7;
  SPI_Init (SPI1, &SPI_InitStructure);
 
  SPI_CalculateCRC(SPI1, DISABLE);
  SPI_Cmd (SPI1, ENABLE);
  SPI_SSOutputCmd (SPI1, DISABLE);
  SPI_NSSInternalSoftwareConfig (SPI1, SPI_NSSInternalSoft_Set);
 
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStruct.GPIO_Pin = TOUCH_CS_PIN;
  GPIO_Init(TOUCH_CS_PORT, &GPIO_InitStruct);
  T_DCS();
 
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6;
  GPIO_Init (GPIOB, &GPIO_InitStruct);
 
  diffX = diffY = 0;
  dispSizeX = dispSizeY = 0;
}

Как видите за всю конфигурацию в библиотеке touchscreen’а отвечает функция TouchInit(). В принципе тут все понятно, настраиваем нужные выводы микроконтроллера, включаем тактирование, ну и, конечно, задаем параметры обмена данными по SPI.

Но на этом подготовка к работе с дисплеем не заканчивается. Вторым шагом является калибровка параметров touchscreen’а. За это отвечает функция TouchCalibrate(). Ее полный код я приводить не буду, ссылка на скачивание полной библиотеки и готового примера будет в конце статьи, все можно будет увидеть в исходниках 😉

Итак, все настроено и готово к работе!

Осталось обсудить основную функцию, с помощью которой мы и будем работать с LCD. И это функция:

bool TouchReadXY (uint16_t *px, uint16_t *py, bool isReadCorrected);

Эта функция позволит нам узнать координаты точки касания дисплея, с которыми мы уже в дальнейшем будем работать. Для получения этих данных необходимо передать в функцию адреса переменных, в которых будут сохранены координаты x и y.

С обсуждением на этом заканчиваем, давайте переходить к практическому примеру. Вот полный код функции main():

int main(void)
{
  initPeriph();
  initFSMC();
  initLCD();
  delay(10000);
  LCD_FillScr(0xFFFF);
  delay(100);
  LCD_SetOrient(Orientation_Portrait);
  delay(100);
 
  TouchInit();
  TouchSetScreenSize(240,320);
  TouchCalibrate();
  LCD_FillScr(0xFFFF);
 
  while (1) 
  {
    TouchReadXY(&X,&Y,true);
    LCD_PutPixel(X,Y,0x0000);
  }
}

Давайте разберемся, что тут происходит.

Для начала вызываем функции инициализации дисплея, которые мы обсуждали в предыдущей статье. Следом за ними функции конфигурации touchscreen’а. Кроме того, вызываем функцию TouchSetScreenSize() с параметрами, соответствующими размерам нашего дисплея. Эти данные нужны для работы драйвера touchscreen’а. А в бесконечном цикле реализуем что-то вроде рисовалки — считываем координаты касания и в этом месте рисуем точку. Таким образом, проводя пальцем по дисплею можно рисовать линии, фигуры итд.

Результат работы нашей программы:

На этом на сегодня заканчиваем, еще раз большое спасибо mishadesh за материалы и за работу над графической библиотекой!

В завершение как и обещал привожу проект для работы с touchscreen’ом, а также напоминаю контакты автора библиотеки =)

Проект — Touch_Project

Skype — mishadesh

Mail — mishadesh@gmail.com

Like this post? Suggest to friends!

Графический дисплей и touchscreen.: 6 комментариев
  1. Чтобы минимизировать количество ошибочных пикселей, попробуйте медианный фильтр. Суть проста: считываете n показаний тачскрина в массив, сортируете его(по возрастанию или убыванию без разницы) и берете средний элемент, если n — нечетное, или среднее арифметическое 2х средних элементов, если n — четное. Таким образом вы отсекаете цифровые шумы. Сам делал похожую рисовалку, так вот с использованием этого фильтра результат стал намного лучше.

  2. у меня не стояла цель делать рисовалку. Я делаю кнопочный интерфейс, а там прецизионная точность не нужна

    • нужна, будешь нажимать на одну кнопку, а нажмется соседняя… или вообще хз где..

  3. Как сделать чтобы каждый раз не калибровать, а использовать готовые коэффициенты.

    • Посмотри под отладчиком, какие коэффициенты получаются при калибровке и забей их константами.

  4. Я сейчас занимаюсь прикручиванием внешней памяти как раз чтобы хранить такую сервисную информацию. Константы в следующем проекте будут уже во flash памяти.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *