其实道理很简单,就是用adc去读电压,但是细节很多。废话不说,直接上代码,这个是给STemWin的驱动,但是原理都在。如果单独用,需要滤波。
第一个细节: 设为浮空的引脚需要内部下拉,否则没有办法判断按或者不按。
第二个细节:ADC的sampling时间不能太小,否则读出数据不稳定,没法用。
#include "GUI.h"
#define XSIZE_PHYS 240 // To be adapted to x-screen size
#define YSIZE_PHYS 320 // To be adapted to y-screen size
#define GUI_TOUCH_AD_TOP 3600
#define GUI_TOUCH_AD_BOTTOM 410
#define GUI_TOUCH_AD_LEFT 410
#define GUI_TOUCH_AD_RIGHT 3660
void GUI_TOUCH_X_Init(void)
{
GUI_TOUCH_SetOrientation(GUI_SWAP_XY);
GUI_TOUCH_Calibrate(GUI_COORD_X, 0, XSIZE_PHYS, GUI_TOUCH_AD_LEFT, GUI_TOUCH_AD_RIGHT);
GUI_TOUCH_Calibrate(GUI_COORD_Y, 0, YSIZE_PHYS, GUI_TOUCH_AD_TOP, GUI_TOUCH_AD_BOTTOM);
}
void GUI_TOUCH_X_ActivateX(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
// X- = 0
GPIO_InitStruct.Pin = X_Left_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(X_Left_GPIO_Port, &GPIO_InitStruct);
HAL_GPIO_WritePin(X_Left_GPIO_Port, X_Left_Pin, GPIO_PIN_RESET);
// X+ = 1
GPIO_InitStruct.Pin = X_RIGHT_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(X_RIGHT_GPIO_Port, &GPIO_InitStruct);
HAL_GPIO_WritePin(X_RIGHT_GPIO_Port, X_RIGHT_Pin, GPIO_PIN_SET);
// Enable Y- = NO PULLUP OR DOWN
GPIO_InitStruct.Pin = Y_UP_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
HAL_GPIO_Init(Y_UP_GPIO_Port, &GPIO_InitStruct);
// Enable Y+ ADC, Channel 3
GPIO_InitStruct.Pin = Y_DOWN_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(Y_DOWN_GPIO_Port, &GPIO_InitStruct);
}
void GUI_TOUCH_X_ActivateY(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
// Y- = 0
GPIO_InitStruct.Pin = Y_UP_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(Y_UP_GPIO_Port, &GPIO_InitStruct);
HAL_GPIO_WritePin(Y_UP_GPIO_Port, Y_UP_Pin, GPIO_PIN_RESET);
// Y+ = 1
GPIO_InitStruct.Pin = Y_DOWN_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(Y_DOWN_GPIO_Port, &GPIO_InitStruct);
HAL_GPIO_WritePin(Y_DOWN_GPIO_Port, Y_DOWN_Pin, GPIO_PIN_SET);
// X- NO PULL UP or DOWN
GPIO_InitStruct.Pin = X_Left_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
HAL_GPIO_Init(X_Left_GPIO_Port, &GPIO_InitStruct);
// Enable X+ ADC, Channel 2
GPIO_InitStruct.Pin = X_RIGHT_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(X_RIGHT_GPIO_Port, &GPIO_InitStruct);
}
int GUI_TOUCH_X_MeasureX(void)
{
int result;
ADC_ChannelConfTypeDef sConfig = {0};
/*
* Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/
sConfig.Channel = ADC_CHANNEL_2;
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
if (HAL_ADC_Start(&hadc1) != HAL_OK)
{
Error_Handler();
}
if (HAL_ADC_PollForConversion(&hadc1, 10) != HAL_OK)
{
Error_Handler();
}
result = HAL_ADC_GetValue(&hadc1);
if (HAL_ADC_Stop(&hadc1) != HAL_OK)
{
Error_Handler();
}
return result;
}
int GUI_TOUCH_X_MeasureY(void) {
int result;
ADC_ChannelConfTypeDef sConfig = {0};
/*
* Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/
sConfig.Channel = ADC_CHANNEL_3;
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
if (HAL_ADC_Start(&hadc1) != HAL_OK)
{
Error_Handler();
}
if (HAL_ADC_PollForConversion(&hadc1, 10) != HAL_OK)
{
Error_Handler();
}
result = HAL_ADC_GetValue(&hadc1);
if (HAL_ADC_Stop(&hadc1) != HAL_OK)
{
Error_Handler();
}
return result;
}