STM32 TFT Learning Notes - Touch Screen

Publisher:画意人生Latest update time:2019-03-11 Source: eefocusKeywords:STM32 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

Host environment: Windows 7 SP1


Development environment: MDK5.14


Target board: ST NUCLEO-F303RE


TFT model: 2.4 inches, with touch, SD card, 240*320 resolution, 260,000 colors


Driver IC:ILI9325


ST library version: STM32Cube_FW_F3_V1.1.0


SD卡:Kingston 16GB Micro SDHC Class 10


Touch IC: XPT2046


A lot of information about XPT2016 can be downloaded from the Internet. XPT2046 uses the SPI communication interface. The interface description is as follows:



There is an extra BUSY pin and a PENIRQ pin. The BUSY signal indicates the working status of XPT2046, but it is found that it does not work during use, so it is useless. PENIRQ is an interrupt indicator pin. When the touch screen is touched, its signal will become low. For NUCLEO-F303RE, the SPI1 interface is used as the SD card interface in the BSP, so the SPI3 interface is used here to communicate with XPT2046. The interface declaration is as follows



/* Definition for SPI_XPT2046 clock resources */

#define SPI_XPT2046 SPI3

#define SPI_XPT2046_CLK_ENABLE() __SPI3_CLK_ENABLE()

#define SPI_XPT2046_CLK_DISABLE() __SPI3_CLK_DISABLE()

#define SPI_XPT2046_nCS_GPIO_CLK_ENABLE() __GPIOA_CLK_ENABLE()

#define SPI_XPT2046_SCK_GPIO_CLK_ENABLE() __GPIOC_CLK_ENABLE()

#define SPI_XPT2046_MISO_GPIO_CLK_ENABLE() __GPIOC_CLK_ENABLE()

#define SPI_XPT2046_MOSI_GPIO_CLK_ENABLE() __GPIOC_CLK_ENABLE()

 

#define SPI_XPT2046_FORCE_RESET() __SPI3_FORCE_RESET()

#define SPI_XPT2046_RELEASE_RESET() __SPI3_RELEASE_RESET()

 

/* Definition for SPIx Pins */

#define SPI_XPT2046_SCK_PIN                 GPIO_PIN_10

#define SPI_XPT2046_SCK_GPIO_PORT           GPIOC

#define SPI_XPT2046_SCK_AF                  GPIO_AF6_SPI3

#define SPI_XPT2046_MISO_PIN                GPIO_PIN_11

#define SPI_XPT2046_MISO_GPIO_PORT          GPIOC

#define SPI_XPT2046_MISO_AF                 GPIO_AF6_SPI3

#define SPI_XPT2046_MOSI_PIN                GPIO_PIN_12

#define SPI_XPT2046_MOSI_GPIO_PORT          GPIOC

#define SPI_XPT2046_MOSI_AF                 GPIO_AF6_SPI3

 

#define SPI_XPT2046_nCS_PIN GPIO_PIN_15

#define SPI_XPT2046_nCS_GPIO_PORT GPIOA

 

#define SPI_XPT2046_nCS_Set_Low() (GPIOA->BRR = GPIO_PIN_15)

#define SPI_XPT2046_nCS_Set_High() (GPIOA->BSRRL = GPIO_PIN_15)

 

#define SPI_XPT2046_TIMEOUT 1000


The XPT2046 communication timing is as follows

The communication master clock is 2MHz. Edit our spi3 initialization and read and write code accordingly.



SPI_HandleTypeDef spi_xpt_Handle;

/**

  * @brief SPI MSP Initialization 

  *        This function configures the hardware resources used in this example: 

  *           - Peripheral's clock enable

  *           - Peripheral's GPIO Configuration  

  * @param hspi: SPI handle pointer

  * @retval None

  */

void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi)

{

GPIO_InitTypeDef  GPIO_InitStruct;


if(SPI_XPT2046 != hspi->Instance)

{

return ;

}

   

/*##-1- Enable peripherals and GPIO Clocks #################################*/

/* Enable GPIO TX/RX clock */

SPI_XPT2046_SCK_GPIO_CLK_ENABLE();

SPI_XPT2046_MISO_GPIO_CLK_ENABLE();

SPI_XPT2046_MOSI_GPIO_CLK_ENABLE();

SPI_XPT2046_nCS_GPIO_CLK_ENABLE();

/* Enable SPI clock */

SPI_XPT2046_CLK_ENABLE(); 

 

/*##-2- Configure peripheral GPIO ##########################################*/  

/* SPI SCK GPIO pin configuration  */

GPIO_InitStruct.Pin       = SPI_XPT2046_SCK_PIN;

GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

GPIO_InitStruct.Pull      = GPIO_PULLDOWN;

GPIO_InitStruct.Speed     = GPIO_SPEED_HIGH;

GPIO_InitStruct.Alternate = SPI_XPT2046_SCK_AF;

HAL_GPIO_Init(SPI_XPT2046_SCK_GPIO_PORT, &GPIO_InitStruct);

 

/* SPI MISO GPIO pin configuration  */

GPIO_InitStruct.Pin = SPI_XPT2046_MISO_PIN;

GPIO_InitStruct.Alternate = SPI_XPT2046_MISO_AF;

HAL_GPIO_Init(SPI_XPT2046_MISO_GPIO_PORT, &GPIO_InitStruct);

 

/* SPI MOSI GPIO pin configuration  */

GPIO_InitStruct.Pin = SPI_XPT2046_MOSI_PIN;

GPIO_InitStruct.Alternate = SPI_XPT2046_MOSI_AF;

HAL_GPIO_Init(SPI_XPT2046_MOSI_GPIO_PORT, &GPIO_InitStruct);

 

/* SPI nCS GPIO pin configuration  */

GPIO_InitStruct.Pin = SPI_XPT2046_nCS_PIN;

GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

GPIO_InitStruct.Pull = GPIO_PULLUP;

HAL_GPIO_Init(SPI_XPT2046_nCS_GPIO_PORT, &GPIO_InitStruct);

 

}

 

/**

  * @brief SPI MSP De-Initialization 

  *        This function frees the hardware resources used in this example:

  *          - Disable the Peripheral's clock

  *          - Revert GPIO configuration to its default state

  * @param hspi: SPI handle pointer

  * @retval None

  */

void HAL_SPI_MspDeInit(SPI_HandleTypeDef *hspi)

{

if(SPI_XPT2046 != hspi->Instance)

{

return ;

}


/*##-1- Reset peripherals ##################################################*/

SPI_XPT2046_FORCE_RESET();

SPI_XPT2046_RELEASE_RESET();

 

/*##-2- Disable peripherals and GPIO Clocks ################################*/

/* Configure SPI SCK as alternate function  */

HAL_GPIO_DeInit(SPI_XPT2046_SCK_GPIO_PORT, SPI_XPT2046_SCK_PIN);

/* Configure SPI MISO as alternate function  */

HAL_GPIO_DeInit(SPI_XPT2046_MISO_GPIO_PORT, SPI_XPT2046_MISO_PIN);

/* Configure SPI MOSI as alternate function  */

HAL_GPIO_DeInit(SPI_XPT2046_MOSI_GPIO_PORT, SPI_XPT2046_MOSI_PIN);

/* Configure SPI nCS as alternate function  */

HAL_GPIO_DeInit(SPI_XPT2046_nCS_GPIO_PORT, SPI_XPT2046_nCS_PIN);

}

/**********************************************************************

Function: SPI3_Init()

Function: SPI3 initialization

Parameters: None

Return value: None

Previous version: None

Current version: 1.0

Author:anobodykey

Last modified:2015-07-31

Note: The clock used by SPI3 is APB1. When the clock is initialized, the clock is

32MHz, communication with xpt2046 is set to 2MHz, CLK idle state is low

Level, data latched on the rising edge of the clock, 8-bit data, MSB, master mode

**********************************************************************/

void SPI3_Init(void)

{

/* Set the SPI parameters */

spi_xpt_Handle.Instance               = SPI_XPT2046;

 

spi_xpt_Handle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;

spi_xpt_Handle.Init.Direction         = SPI_DIRECTION_2LINES;

spi_xpt_Handle.Init.CLKPhase          = SPI_PHASE_1EDGE;

spi_xpt_Handle.Init.CLKPolarity       = SPI_POLARITY_LOW;

spi_xpt_Handle.Init.CRCCalculation    = SPI_CRCCALCULATION_DISABLED;

spi_xpt_Handle.Init.CRCPolynomial     = 7;

spi_xpt_Handle.Init.DataSize          = SPI_DATASIZE_8BIT;

spi_xpt_Handle.Init.FirstBit          = SPI_FIRSTBIT_MSB;

spi_xpt_Handle.Init.NSS               = SPI_NSS_SOFT;

spi_xpt_Handle.Init.TIMode            = SPI_TIMODE_DISABLED;

spi_xpt_Handle.Init.NSSPMode          = SPI_NSS_PULSE_DISABLED;

spi_xpt_Handle.Init.CRCLength         = SPI_CRC_LENGTH_8BIT;

spi_xpt_Handle.Init.Mode   = SPI_MODE_MASTER;


HAL_SPI_Init(&spi_xpt_Handle);//Initialize spi

return ;

}

 

/**********************************************************************

Function: SPI3_Write()

Function: SPI3 sends one byte of data

parameter:

uint8_t value----------------------------Byte data to be sent

Return value: 0: success - 1: failure

Previous version: None

Current version: 1.0

Author:anobodykey

Last modified:2015-07-31

Note: SPI3 communication timeout is 1S

**********************************************************************/

int8_t SPI3_Write(uint8_t value)

{

HAL_StatusTypeDef status = HAL_OK;

 

status = HAL_SPI_Transmit(&spi_xpt_Handle, &value, 1, SPI_XPT2046_TIMEOUT);

 

/* Check the communication status */

if(status != HAL_OK)

{

return (int8_t)-1;

}


return 0;

}

/**********************************************************************

Function: SPI3_Read()

Function: SPI3 receives a 16-bit data

parameter:

uint8_t *value------------------------------The address of receiving data

Return value: 0: success - 1: failure

Previous version: None

Current version: 1.0

Author:anobodykey

Last modified:2015-07-31

Note: SPI3 communication timeout is 1S

**********************************************************************/

int8_t SPI3_Read(uint8_t *readvalue)

{

HAL_StatusTypeDef status = HAL_OK;

uint8_t writevalue = 0x00;

 

status = HAL_SPI_TransmitReceive(&spi_xpt_Handle, &writevalue, readvalue, 1, SPI_XPT2046_TIMEOUT);

 

/* Check the communication status */

if(status != HAL_OK)

{

return (int8_t)-1;

}

 

return 0;

}


After the SPI communication is completed, there are two pin interfaces BUSY and PENIRQ, the declarations are as follows


#define TOUCHPANEL_PEN_GPIO_CLK_ENABLE() __GPIOC_CLK_ENABLE()

#define TOUCHPANEL_BUSY_GPIO_CLK_ENABLE() __GPIOC_CLK_ENABLE()

#define TOUCHPANEL_PEN_PIN GPIO_PIN_2

#define TOUCHPANEL_PEN_GPIO_PORT GPIOC

#define TOUCHPANEL_BUSY_PIN GPIO_PIN_3

#define TOUCHPANEL_BUSY_GPIO_PORT GPIOC

 

#define TOUCHPANEL_BUSY_Read() (GPIOC->IDR & GPIO_PIN_3)

//#define TOUCHPANEL_PEN_Read() (GPIOC->IDR & GPIO_PIN_2)

 

#define TOUCHPANEL_BUSY (GPIO_PIN_3)

#define TOUCHPANEL_IDLE (0x00)


The interface is initialized as follows


/**********************************************************************

Function: HAL_TouchPanel_MspInit()

Function: Touch screen port resource initialization

Parameters: None

Return value: None

Previous version: None

Current version: 1.0

Author:anobodykey

Last modified:2015-07-31

Note: The ports here are PEN port and BUSY port. Other ports are SPI communication ports.

**********************************************************************/

void HAL_TouchPanel_MspInit(void)

{

GPIO_InitTypeDef  GPIO_InitStruct;

   

/*##-1- Enable peripherals and GPIO Clocks #################################*/

/* Enable GPIO  clock */

TOUCHPANEL_PEN_GPIO_CLK_ENABLE();

TOUCHPANEL_BUSY_GPIO_CLK_ENABLE();

 

/*##-2- Configure peripheral GPIO #######################################*/  

/* PEN GPIO pin configuration  */

GPIO_InitStruct.Pin       = TOUCHPANEL_BUSY_PIN;

GPIO_InitStruct.Mode      = GPIO_MODE_INPUT;

GPIO_InitStruct.Pull      = GPIO_PULLUP;

GPIO_InitStruct.Speed     = GPIO_SPEED_HIGH;

GPIO_InitStruct.Pin   = TOUCHPANEL_BUSY_PIN;

HAL_GPIO_Init(TOUCHPANEL_BUSY_GPIO_PORT, &GPIO_InitStruct);

 

GPIO_InitStruct.Pin   = TOUCHPANEL_PEN_PIN;

GPIO_InitStruct.Mode   = GPIO_MODE_IT_FALLING;

HAL_GPIO_Init(TOUCHPANEL_PEN_GPIO_PORT, &GPIO_InitStruct);


/*Enable an set EXTI line 2 Interrupt to the lowest priority*/

HAL_NVIC_SetPriority(EXTI2_TSC_IRQn,2,0);

HAL_NVIC_EnableIRQ(EXTI2_TSC_IRQn);

return ;

}

/**********************************************************************

Function: TouchPanel_Init()

Function: Touch screen initialization

Parameters: None

Return value: None

Previous version: None

Current version: 1.0

Author:anobodykey

Last modified:2015-07-31

illustrate: 

**********************************************************************/

void TouchPanel_Init(void)

{

HAL_TouchPanel_MspInit(); //Initialize io port resources

SPI_XPT2046_nCS_Set_High(); //Chip select high

}


Here, PENIQR is configured as an interrupt pin, and the falling edge is valid. There is only one command for XPT2046


MSB is always 1, MODE=012bit conversion mode, SER/DFR=0: differential mode conversion. The document mentions that differential mode is preferred when measuring X and Y coordinates. PD1, PD0=0, A2, A1, A0 are explained as follows



001 is the measurement of X coordinate, 101 is the measurement of Y coordinate


Construct a sampling point structure to store the measured values, as follows



typedef struct

{

uint16_t sample_x;

uint16_t sample_y;

}Touch_Point;


Read the measured values ​​as follows


/**********************************************************************

Function: TouchPanel_GetPoint()

Function: Get touch point

Parameters: None

Return value: None

Previous version: None

Current version: 1.0

Author:anobodykey

Last modified:2015-07-31

illustrate: 

**********************************************************************/

int8_t TouchPanel_GetPoint(Touch_Point *touch_point)

{

uint8_t sample_value_h=0,sample_value_l=0;


SPI_XPT2046_nCS_Set_Low();

 

if(SPI3_Write(0x90) != 0)//Measure Y-

{

return (int8_t)-1;

}

 

if(0 != SPI3_Read(&sample_value_h))

{

printf("read err1\r\n");

}

if(0 != SPI3_Read(&sample_value_l))

{

printf("read err1\r\n");

}

touch_point->sample_x = ((sample_value_h&0x7F)<


if(0 != SPI3_Write(0xD0)) //Measure X-

{

printf("write err2\r\n");

}

sample_value_h = 0;

sample_value_l = 0;

if(0 != SPI3_Read(&sample_value_h))

{

printf("read err2\r\n");

}

if(0 != SPI3_Read(&sample_value_l))

{

printf("read err2\r\n");

}

touch_point->sample_y = ((sample_value_h&0x7F)<


SPI_XPT2046_nCS_Set_High();

 

return 0;


}

uint8_t flag = 0;

void HAL_GPIO_EXTI_Callback (uint16_t GPIO_Pin)

{

switch(GPIO_Pin)

{

case TOUCHPANEL_PEN_PIN:

flag = 1;

break;

default:

break;

}

}

 

/**********************************************************************

Function: EXTI2_TSC_IRQHandler()

Function: EXTI2_TSC interrupt response function

Parameters: None

Return value: None

Previous version: None

Current version: 1.0

Author:anobodykey

Last modified:2015-08-10

Description: Only handle EXTI2 interrupt

**********************************************************************/

void EXTI2_TSC_IRQHandler(void)

{

HAL_GPIO_EXTI_IRQHandler (TOUCHPANEL_PEN_PIN);

}


When reading the measured value, it should be noted that the measured result is 12 bits. In the timing diagram, it can be seen that there are 24 clocks in total. The first 8 clocks are for sending control commands, the 9th clock is invalid, the next 12 clocks are valid data, and the last 3 clocks are idle clocks. Therefore, the high and low bits of the data need to be correctly combined. The timing description is as follows

The code in the main loop is as follows



while(1)

{

if(flag)

{

//PEN is low level to indicate a touch point

printf("get the touch!\r\n");

TouchPanel_GetPoint(&touch_point);

printf("sample y:%04X\r\n",touch_point.sample_y);

printf("sample x:%04X\r\n",touch_point.sample_x);

flag = 0;

}

}


The test results are as follows:


Now we have only obtained the sampled values, which have not been converted into X and Y coordinates. At the same time, the first step for the resistive screen is calibration. There are many resources on the Internet about the calibration process. After doing these, we can use STemWin to create a graphical interface. Using STemWin can make it very convenient for us to create a rich interface.

Keywords:STM32 Reference address:STM32 TFT Learning Notes - Touch Screen

Previous article:STM32 USB learning notes 1
Next article:STM32 TFT learning notes - brush image

Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号