ADC按键原理图
简单来说就是通过按下不同的按键来改变电压值,然后ADC引脚进行采集对应的电压,然后就可以做出判断,实现按键功能。
跳线帽的连接
如电路图所示需要将P4 P5的第五引脚连接起来,板子上有标注AKEY那个脚。
cubemx软件配置
我是用赛点资源包的驱动参考程序改的,打开cubemx软件,将PA5引脚设置为ADC
ADC2的13通道,设置为单通道即可,其它参数不需要进行更改。
接着更新到keil。
Keil程序编写
第一步:adc获取
需要写adc读取函数,我这边也没进行滤波,能用就行
uint16_t get_adc()
{
uint16_t adc=0; //存值
HAL_ADC_Start(&hadc2); //使能ADC
adc=HAL_ADC_GetValue(&hadc2); //读ADC值
return adc;
}
第二步:读值
将读到的值显示到lcd屏幕上,程序里面需要写4位,不然显示到屏幕上面的值会因为没清屏而显示错误正确的值。
u16 adc_value;
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
adc_value=get_adc();
sprintf(display,"ADC:%4d",adc_value); //这里需要写%4d
LCD_DisplayStringLine(Line2,(u8*)display);
}
/* USER CODE END 3 */
}
第三步:key_read()
通过第二步我们可以读取到各个按键对应的adc值,然后通过这些测量值作为范围,来判断是按下了哪个键。
下面是我自己测了之后写的函数。
u8 key_read()
{
if(get_adc()<400)
{
return 1;
}
else if(get_adc()<1000)
{
return 2;
}
else if(get_adc()<1600)
{
return 3;
}
else if(get_adc()<2000)
{
return 4;
}
else if(get_adc()<2600)
{
return 5;
}
else if(get_adc()<3000)
{
return 6;
}
else if(get_adc()<3800)
{
return 7;
}
else if(get_adc()<4000)
{
return 8;
}
else
return 0;
}
u16 adc_value;
u8 key_value;
将哪个按键按下显示到屏幕:
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
adc_value=get_adc();
key_value=key_read();
sprintf(display,"ADC:%4d",adc_value);
LCD_DisplayStringLine(Line2,(u8*)display);
sprintf(display,"key:%d",key_value);
LCD_DisplayStringLine(Line4,(u8*)display);
}
/* USER CODE END 3 */
}
整个main.c的代码:
#include "main.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stdio.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
ADC_HandleTypeDef hadc2;
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_ADC2_Init(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
uint16_t get_adc()
{
uint16_t adc=0;
HAL_ADC_Start(&hadc2);
adc=HAL_ADC_GetValue(&hadc2);
return adc;
}
u8 key_read()
{
if(get_adc()<400)
{
return 1;
}
else if(get_adc()<1000)
{
return 2;
}
else if(get_adc()<1600)
{
return 3;
}
else if(get_adc()<2000)
{
return 4;
}
else if(get_adc()<2600)
{
return 5;
}
else if(get_adc()<3000)
{
return 6;
}
else if(get_adc()<3800)
{
return 7;
}
else if(get_adc()<4000)
{
return 8;
}
else
return 0;
}
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_ADC2_Init();
/* USER CODE BEGIN 2 */
LCD_Init();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
LCD_Clear(Blue);
LCD_SetBackColor(Blue);
LCD_SetTextColor(White);
char display[20];
u16 adc_value;
u8 key_value;
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
adc_value=get_adc();
key_value=key_read();
sprintf(display,"ADC:%4d",adc_value);
LCD_DisplayStringLine(Line2,(u8*)display);
sprintf(display,"key:%d",key_value);
LCD_DisplayStringLine(Line4,(u8*)display);
}
/* USER CODE END 3 */
}