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.
Previous article:STM32 USB learning notes 1
Next article:STM32 TFT learning notes - brush image
- Popular Resources
- Popular amplifiers
- Learn ARM development(16)
- Learn ARM development(17)
- Learn ARM development(18)
- Embedded system debugging simulation tool
- A small question that has been bothering me recently has finally been solved~~
- Learn ARM development (1)
- Learn ARM development (2)
- Learn ARM development (4)
- Learn ARM development (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- CGD and Qorvo to jointly revolutionize motor control solutions
- CGD and Qorvo to jointly revolutionize motor control solutions
- Keysight Technologies FieldFox handheld analyzer with VDI spread spectrum module to achieve millimeter wave analysis function
- Infineon's PASCO2V15 XENSIV PAS CO2 5V Sensor Now Available at Mouser for Accurate CO2 Level Measurement
- Advanced gameplay, Harting takes your PCB board connection to a new level!
- Advanced gameplay, Harting takes your PCB board connection to a new level!
- A new chapter in Great Wall Motors R&D: solid-state battery technology leads the future
- Naxin Micro provides full-scenario GaN driver IC solutions
- Interpreting Huawei’s new solid-state battery patent, will it challenge CATL in 2030?
- Are pure electric/plug-in hybrid vehicles going crazy? A Chinese company has launched the world's first -40℃ dischargeable hybrid battery that is not afraid of cold
- Op amp basics: DC biasing of active circuits
- Gizwits ESP8266 controls the lifting of rolling shutter doors
- Help analyze this small wind power generation circuit
- Lessons learned from transplanting LwIP on C6414
- Lichee RV 86 PANEL Review (7) - Deploy a personal blog on Lichee
- [NXP Rapid IoT Review] Bluetooth Control RGB
- [National Technology N32G457 Review] Comparison between development board N32G457 and AB32VG1
- I2C pull-up levels
- It’s the middle of the year, how are your 2021 plans/goals going?
- [TI recommended course] #Optimizing system-level design through industrial Ethernet#