触摸屏控制器是一个常见的电子设备,广泛应用于智能手机、平板电脑、汽车导航系统等设备上。在本文中,我们将使用STM32微控制器制作一个简单的触摸屏控制器。
首先,我们需要准备以下材料:
- STM32开发板:我们使用的是STM32F407VGT6开发板。
- 触摸屏:我们使用的是电阻式触摸屏,具有4线SPI接口。
- 3.5寸TFT LCD模块:我们使用的是ILI9488控制器的LCD模块。
接下来,我们将分为三个步骤来实现这个触摸屏控制器:
第一步:硬件连接
首先,将STM32开发板和触摸屏、LCD模块连接起来。
- 将触摸屏模块的VCC引脚连接到STM32开发板的3.3V电源引脚。
- 将触摸屏模块的GND引脚连接到STM32开发板的GND引脚。
- 将触摸屏模块的SCK引脚连接到STM32开发板的SPI的SCK引脚。
- 将触摸屏模块的SDI引脚连接到STM32开发板的SPI的MOSI引脚。
- 将触摸屏模块的SDO引脚连接到STM32开发板的SPI的MISO引脚。
- 将触摸屏模块的CS引脚连接到STM32开发板的GPIO引脚。
- 将LCD模块的VCC引脚连接到STM32开发板的3.3V电源引脚。
- 将LCD模块的GND引脚连接到STM32开发板的GND引脚。
- 将LCD模块的SCK引脚连接到STM32开发板的SPI的SCK引脚。
- 将LCD模块的SDI引脚连接到STM32开发板的SPI的MOSI引脚。
- 将LCD模块的CS引脚连接到STM32开发板的GPIO引脚。
- 将LCD模块的DC引脚连接到STM32开发板的GPIO引脚。
- 将LCD模块的RST引脚连接到STM32开发板的GPIO引脚。
第二步:配置STM32的SPI和GPIO
接下来,我们需要配置STM32的SPI和GPIO。
首先,打开STM32CubeIDE,并创建一个新的工程。选择正确的STM32微控制器型号,并配置SPI和GPIO引脚。例如,我们将SPI配置为主模式,时钟速度为1 MHz,数据大小为8位。
在代码中,我们首先需要包含相应的库文件,并定义一些变量和函数。
#include "stm32f4xx_hal.h"
#include "ili9488.h"
#include "touch.h"
SPI_HandleTypeDef hspi2;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_SPI2_Init(void);
然后,我们需要实现这些函数。
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = 16;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLM = 8;
RCC_OscInitStruct.PLL.PLLN = 168;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 4;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
if (HAL_PWREx_EnableOverDrive() != HAL_OK)
{
Error_Handler();
}
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK |
RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
{
Error_Handler();
}
}
static void MX_GPIO_Init(void)
{
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOE, LCD_RST_Pin | LCD_DC_Pin, GPIO_PIN_RESET);
}
static void MX_SPI2_Init(void)
{
/* SPI2 parameter configuration*/
hspi2.Instance = SPI2;
hspi2.Init.Mode = SPI_MODE_MASTER;
hspi2.Init.Direction = SPI_DIRECTION_2LINES;
hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi2.Init.NSS = SPI_NSS_SOFT;
hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;
hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi2.Init.CRCPolynomial = 7;
if (HAL_SPI_Init(&hspi2) != HAL_OK)
{
Error_Handler();
}
}
最后,在main()
函数中初始化SPI和GPIO。
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_SPI2_Init();
ILI9488_Init();
Touch_Init();
while (1)
{
// 获取触摸屏坐标
int x, y;
if (Touch_GetCoordinates(&x, &y))
{
// 根据坐标绘制图形
ILI9488_DrawPixel(x, y, ILI9488_COLOR_RED);
}
HAL_Delay(100);
}
}
第三步:编写显示和触摸操作函数
在上一步中,我们已经初始化了串行外设接口(SPI)和通用输入输出(GPIO)。现在,我们需要编写一些函数来控制显示和触摸操作。
首先,我们需要编写ILI9488控制器的函数。我们将创建一个名为ili9488.h
的头文件,并在其中定义一些函数和常量。
#ifndef _ILI9488_H_
#define _ILI9488_H_
#include "stm32f4xx_hal.h"
#define ILI9488_WIDTH 320
#define ILI9488_HEIGHT 480
#define ILI9488_COLOR_BLACK 0x0000
#define ILI9488_COLOR_WHITE 0xFFFF
#define ILI9488_COLOR_RED 0xF800
#define ILI9488_COLOR_GREEN 0x07E0
#define ILI9488_COLOR_BLUE 0x001F
void ILI9488_Init(void);
void ILI9488_DrawPixel(int16_t x, int16_t y, uint16_t color);
void ILI9488_FillScreen(uint16_t color);
#endif /* _ILI9488_H_ */
然后,在ili9488.c
文件中实现这些函数。
#include "ili9488.h"
extern SPI_HandleTypeDef hspi2;
extern GPIO_TypeDef *LCD_DC_GPIO_Port;
extern uint16_t LCD_DC_Pin;
extern GPIO_TypeDef *LCD_RST_GPIO_Port;
extern uint16_t LCD_RST_Pin;
void ILI9488_Init(void)
{
HAL_GPIO_WritePin(LCD_RST_GPIO_Port, LCD_RST_Pin, GPIO_PIN_SET);
HAL_Delay(10);
HAL_GPIO_WritePin(LCD_RST_GPIO_Port, LCD_RST_Pin, GPIO_PIN_RESET);
HAL_Delay(