STM32使用HAL库驱动4线的电阻屏

本文详细讲解了如何使用STemWin平台的ADC进行电压测量,涉及引脚设置、采样时间调整等关键细节,包括设置浮空引脚内部下拉、确保ADC采样稳定性的技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

其实道理很简单,就是用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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值