历史上的今天
返回首页

历史上的今天

今天是:2025年03月11日(星期二)

正在发生

2019年03月11日 | STM32 TFT学习笔记——触摸屏

2019-03-11 来源:eefocus

主机环境:Windows 7 SP1


开发环境:MDK5.14


目标板:ST NUCLEO-F303RE


TFT型号:2.4英寸,带触摸,SD卡,240*320分辨率,26万色


驱动IC:ILI9325


ST库版本:STM32Cube_FW_F3_V1.1.0


SD卡:Kingston 16GB Micro SDHC Class 10


触摸IC:XPT2046


关于XPT2016的说明可以从网上下载很多资料,XPT2046使用SPI通信接口,接口说明如下:



多出了一个BUSY脚和一个PENIRQ脚,BUSY信号指示XPT2046工作状态,但是在使用过程中发现其不起作用,所以就没用了,PENIRQ为中断指示脚,当触摸屏有接触时其信号会变成低电平。对于NUCLEO-F303RE来说SPI1接口在BSP里面用作了SD卡接口,因此这里使用SPI3接口来跟XPT2046进行通信,接口声明如下



/* 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


XPT2046通信时序如下

通信主时钟为2MHz据此编辑我们的spi3初始化以及读写代码



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);

}

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

函数:SPI3_Init()

函数作用:SPI3初始化

参数:无

返回值:无

上一版本:无

当前版本:1.0

作者:anobodykey

最后修改时间:2015-07-31

说明: SPI3使用的时钟为APB1,在时钟初始化时该时钟为

32MHz,跟xpt2046通信设置成2MHz速率,CLK空闲状态为低

电平,数据在时钟上升沿锁存,8bit数据位,MSB,主模式

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

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);//初始化spi

return ;

}

 

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

函数:SPI3_Write()

函数作用:SPI3发送一个字节数据

参数:

uint8_t value----------------------------待发送的字节数据

返回值:0:成功-1:失败

上一版本:无

当前版本:1.0

作者:anobodykey

最后修改时间:2015-07-31

说明: SPI3通信超时时间为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;

}

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

函数:SPI3_Read()

函数作用:SPI3接收一个16bit数据

参数:

uint8_t *value------------------------------接收数据的地址

返回值:0:成功-1:失败

上一版本:无

当前版本:1.0

作者:anobodykey

最后修改时间:2015-07-31

说明: SPI3通信超时时间为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;

}


SPI通信完成之后还有两个引脚接口BUSY和PENIRQ,声明如下


#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)


接口初始化如下


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

函数:HAL_TouchPanel_MspInit()

函数作用:触摸屏端口资源初始化

参数:无

返回值:无

上一版本:无

当前版本:1.0

作者:anobodykey

最后修改时间:2015-07-31

说明: 这里端口是PEN口和BUSY口其他口都是spi通讯口

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

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 ;

}

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

函数:TouchPanel_Init()

函数作用:触摸屏初始化

参数:无

返回值:无

上一版本:无

当前版本:1.0

作者:anobodykey

最后修改时间:2015-07-31

说明: 

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

void TouchPanel_Init(void)

{

HAL_TouchPanel_MspInit();//初始化io口资源

SPI_XPT2046_nCS_Set_High();//片选拉高

}


这里配置PENIQR为中断引脚,下降沿有效,XPT2046的命令只有一条


MSB一直为1,MODE=012bit转换模式,SER/DFR=0:差分模式转换,文档中提到在测量X、Y坐标时首选差分模式,PD1,PD0=0,A2、A1、A0说明如下



001是测量X坐标,101是测量Y坐标


构造一个采样点结构体,存储测量值,如下



typedef struct

{

uint16_t sample_x;

uint16_t sample_y;

}Touch_Point;


读取测量值如下


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

函数:TouchPanel_GetPoint()

函数作用:获取触摸点

参数:无

返回值:无

上一版本:无

当前版本:1.0

作者:anobodykey

最后修改时间:2015-07-31

说明: 

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

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)//测量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))//测量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;

}

}

 

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

函数:EXTI2_TSC_IRQHandler()

函数作用:EXTI2_TSC中断响应函数

参数:无

返回值:无

上一版本:无

当前版本:1.0

作者:anobodykey

最后修改时间:2015-08-10

说明: 只处理EXTI2中断

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

void EXTI2_TSC_IRQHandler(void)

{

HAL_GPIO_EXTI_IRQHandler (TOUCHPANEL_PEN_PIN);

}


在读取测量值时需要注意测量的结果是12bit,在时序图中可以看到,一共24个时钟,前8个时钟是发送控制命令,第9个时钟无效,接着的12个时钟为有效数据,最后3个时钟为空闲时钟,因此数据的高位和地位需要正确的组合。时序说明如下

在主循环中代码如下



while(1)

{

if(flag)

{

//PEN为低电平表示有触摸点

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;

}

}


测试结果如下:


现在只是获取了采样值还没有转换成X、Y坐标,同时对于电阻屏来说第一步就是校正,关于校正流程网上有很多资源,做完这些下面就可以使用STemWin来制作图形界面了,使用STemWin可以很方便我们做出丰富的界面。

推荐阅读

史海拾趣

Dymec公司的发展小趣事

随着全球对环保问题的日益关注,Dymec公司也积极响应号召,开始推动绿色环保的转型。公司投入大量资金研发环保型电子连接器产品,采用环保材料和生产工艺,减少了对环境的污染。这一转型不仅提升了公司的社会责任感,也为公司赢得了更多客户的青睐。

德力西(DELIXI)公司的发展小趣事

进入新世纪后,德力西开始全国化布局和多元化发展。1998年,在上海注册成立了上海德力西集团有限公司,与西安高压电器研究所联合生产高压电器和成套设备。此外,德力西还积极参与国企改革,整体并购了杭州西子(集团)公司,并进入环保领域,建设垃圾处理及水处理项目。这些举措使德力西在电子行业的地位更加稳固。

EPT公司的发展小趣事

EPT深知产品质量是企业发展的基石。因此,公司不仅通过了ISO9001:2015和BSCI等国际质量管理体系认证,还获得了CE、UL、IEC62133、KC等多项证书。此外,EPT还为所有电池购买了产品责任险,为客户提供双重保障。这一举措不仅提升了客户对EPT产品的信任度,也为其在电子行业中树立了良好的品牌形象。

ATOP_Technologies公司的发展小趣事

随着技术的不断进步,ATOP Technologies意识到要想在激烈的市场竞争中保持领先地位,必须不断进行技术创新和产品升级。因此,公司加大了在研发方面的投入,积极引进高端人才,加强与高校和研究机构的合作。经过多年的努力,ATOP Technologies成功开发出了一系列具有自主知识产权的工业自动化产品,并在市场上取得了良好的口碑。

EDO Corp公司的发展小趣事

在制药工业中,Eclipse Magnetics的磁选机技术得到了广泛应用。通过与制药企业的合作,Eclipse Magnetics成功解决了制药过程中可能存在的金属污染问题。这种合作不仅提升了制药企业的产品质量,也进一步巩固了Eclipse Magnetics在电子行业的地位。

Frequency Electronics Inc公司的发展小趣事

为了进一步扩大市场份额,高频电子积极实施全球化战略。公司在全球范围内建立了销售网络和服务体系,与众多国际知名企业建立了长期合作关系。同时,高频电子还针对不同地区的市场需求,定制化开发符合当地标准的产品和服务。这些努力使得高频电子的产品和服务能够覆盖全球多个国家和地区,为公司带来了稳定的收入来源和持续增长的动力。

问答坊 | AI 解惑

第一次来这儿 很喜欢这里,会常来的

第一次来这儿 很喜欢这里,会常来的 支持这个网站…

查看全部问答>

用户电话环路的问题

因为工作想了解一下: 1.是想了解一下电话用户环路的各种信号:如振铃,供电,挂机检测,双音多频,话音的标准. 2,二是想了解一下电话端,交换接入端的电路与芯片.…

查看全部问答>

有趣的遛鱼道具

有趣的遛鱼道具, 相对于阿猫阿狗而言,鱼缸里的金鱼好像孤单了许多,每天都在那一亩三分水里游来游去,换作是你早就崩溃了。这款鱼缸刚好可以让你的鱼儿也出去遛遛,看一看壮丽的世界。 平时晚饭过后,你就可以带着金鱼上街散步,不仅为金鱼解了 ...…

查看全部问答>

关于汇编程序

设有100个有符号数,连续存放在以2000H为首地址的外部数据存储区中,试编程计算其正数负数和0的个数。 另外哪里可以找到汇编代码,我感觉主要是看的代码少,所以不会做。 多谢!…

查看全部问答>

求S3C2440 的A/D转换器的工作原理

请教一下再WINCE下的S3C2440 的A/D转换器的工作原理…

查看全部问答>

WINCE5.0,U盘上电之前插上,系统不识别,上电之后,再插上能够正常识别

环境:S3C2440+WINCE5.0 如题,上电之前,把U盘插在S3C2440板上,进入系统只有不能识别U盘,但是上电之后将没有识别的U盘拔下,重新插上,系统立即识别,我感觉应该是驱动的问题,可能在初始化的时候未做检测....不知道有谁碰到过同样的问题?…

查看全部问答>

wince IE 上网问题

   用WINCE IE上网(系统为500M)怎么样提高其速度,另外在上网时我要右键另存为怎么出现呢?…

查看全部问答>

EVC4操作剪贴板

EVC4操作剪贴板,HOW TO DO???…

查看全部问答>

IAREWARM5.11使用问题请教。区别与IAREWARM4。42

用 5.11 编译IAREWARM 4.42 STM32 库出错。如下:Error[Li005]: no definition for "__program_start" referenced from D:STM32STM32F10xFWLibFWLib 而且在 LINKE ...…

查看全部问答>