Top.Mail.Ru

Микроконтроллер и графический дисплей. Работа с Touch Screen.

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

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

Время традиционной вставки: поскольку компания STMicroelectronics прекратила поддержку библиотеки SPL, которая использовалась в этом курсе, я создал новый, посвященный работе уже с новыми инструментами, так что буду рад видеть вас там - STM32CubeMx. Кроме того, вот глобальная рубрика по STM32, а также небольшая подборка на смежную тему из нового курса:

Итак, для обмена данными с контроллером дисплея мы будем использовать интерфейс 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;
}

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

Но на этом подготовка к работе с дисплеем не заканчивается. Вторым шагом является калибровка параметров touch screen'а. За это отвечает функция 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);
	}
}

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

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

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

STM32 и Touch Screen.

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

  • Проект - Touch_Project
  • Skype - mishadesh
  • E-Mail - mishadesh@gmail.com

Подписаться
Уведомить о
guest

6 комментариев
Старые
Новые
Межтекстовые Отзывы
Посмотреть все комментарии
sob
sob
10 лет назад

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

mishadesh
mishadesh
10 лет назад

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

Влад
Влад
Ответ на комментарий  mishadesh
7 лет назад

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

GLEP
GLEP
10 лет назад

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

mishadesh
mishadesh
10 лет назад

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

6
0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x