【国信长天蓝桥杯】扩展板② ADC按键的使用

摘要

本篇文章主要介绍了蓝桥杯嵌入式比赛扩展板上面ADC按键的工作原理与使用方法。

跳线帽与原理图

要想使用ADC按键需要将扩展板连接到主板上,如下图所示,并且还要短路扩展板上AKEY跳线帽。
在这里插入图片描述
连接成功后,ADC按键与主控板上的PA5引脚相连,ADC按键共有8个子按键,原理图如下图所示:
ADC按键
从上图可以看出,当没有按键按下时,ADC_KEY的电压为3.3V,当按下不同的按键是,根据欧姆定理,ADC_KEY上会产生不同的电压,根据电压的值,可判断哪个按键被按下。比如按键S1被按下时,ADC_KEY上的电压约为0.2V,按键S4按下时,ADC_KEY上的电压约为1.5V。

ADC按键使用步骤

下面将基于硬件原厂提供的显示屏示例代码:HAL_06_LCD 介绍ADC的使用步骤:

① 添加 stm32g4xx_hal_adc.c,stm32g4xx_hal_adc_ex.c

双击Drivers/STM32G4xx_HAL_Driver,打开添加文件对话框,在向上一级 -> Drivers -> STM32G4xx_HAL_Driver -> Src中,找到stm32g4xx_hal_adc.c stm32g4xx_hal_adc_ex.c 并添加。添加后如下图所示:
在这里插入图片描述

② 修改 stm32g4xx_hal_conf.h 文件

在如下位置找到该文件,并打开:
在这里插入图片描述
取消注释 #define HAL_ADC_MODULE_ENABLED 这一行,取下注释后如下图所示:
在这里插入图片描述

main.c 添加 #include "stm32g4xx_hal_adc.h"

main.c 适当位置添加 #include "stm32g4xx_hal_adc.h",添加后如下图所示:
在这里插入图片描述

④ 复制如下 ADC 按键初始化及获取ADC按键值的代码
复制下面的代码,粘贴带main.c文件 main()函数上面空白处

ADC_HandleTypeDef hadc2;

uint16_t ADC_Key_Scan(void)
{
	uint16_t adc_value = 0;
	
	HAL_ADC_Start(&hadc2);
	adc_value = HAL_ADC_GetValue(&hadc2);
	
	if(adc_value < 10) return 1;
	if(adc_value < 800) return 2;
	if(adc_value < 1600) return 3;
	if(adc_value < 2000) return 4;
	if(adc_value < 2700) return 5;
	if(adc_value < 3300) return 6;
	if(adc_value < 3700) return 7;
	if(adc_value < 4000) return 8;
	
	return 0;
}


static void ADC_Key_Init(void)
{
	ADC_ChannelConfTypeDef sConfig = {0};
	RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
	GPIO_InitTypeDef GPIO_InitStruct = {0};
	
	PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC12;
	PeriphClkInit.Adc12ClockSelection = RCC_ADC12CLKSOURCE_SYSCLK;
	HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
	
	__HAL_RCC_ADC12_CLK_ENABLE();//打开ADC时钟
	__HAL_RCC_GPIOA_CLK_ENABLE();//打开GPIO A时钟
	
	hadc2.Instance = ADC2;
	hadc2.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
	hadc2.Init.Resolution = ADC_RESOLUTION_12B;
	hadc2.Init.DataAlign = ADC_DATAALIGN_RIGHT;
	hadc2.Init.GainCompensation = 0;
	hadc2.Init.ScanConvMode = ADC_SCAN_DISABLE;
	hadc2.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
	hadc2.Init.LowPowerAutoWait = DISABLE;
	hadc2.Init.ContinuousConvMode = DISABLE;
	hadc2.Init.NbrOfConversion = 1;
	hadc2.Init.DiscontinuousConvMode = DISABLE;
	hadc2.Init.ExternalTrigConv = ADC_SOFTWARE_START;
	hadc2.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
	hadc2.Init.DMAContinuousRequests = DISABLE;
	hadc2.Init.Overrun = ADC_OVR_DATA_PRESERVED;
	hadc2.Init.OversamplingMode = DISABLE;
	
	HAL_ADC_Init(&hadc2);
	
	sConfig.Channel = ADC_CHANNEL_13; //设置采样通道为13(PA5引脚)
	sConfig.Rank = ADC_REGULAR_RANK_1;
	sConfig.SamplingTime = ADC_SAMPLETIME_640CYCLES_5;
	sConfig.SingleDiff = ADC_SINGLE_ENDED;
	sConfig.OffsetNumber = ADC_OFFSET_NONE;
	sConfig.Offset = 0;
	
	HAL_ADC_ConfigChannel(&hadc2, &sConfig);
	
	GPIO_InitStruct.Pin = GPIO_PIN_5;
	GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); // 初始化PA5引脚为模拟模式
	HAL_ADC_Start(&hadc2);
}

**⑤ 在main() 中调用 ADC_Key_Init(); **

如下图所示,在main() 函数中LCD_Init();下面调用 ADC_Key_Init();

在这里插入图片描述
⑥ 获取按键值

main()while()中插入如下代码:

int key_value =  ADC_Key_Scan();
		
if(key_value == 1) //按键S1被按下
{

}
if(key_value == 2) //按键S2被按下
{

}
if(key_value == 3) //按键S3被按下
{

}

main()函数while(1)中代码如下:
在这里插入图片描述

总结

ADC 按键使用步骤总结入下:

①正确连接扩展板及对应跳线帽
②添加ADC相关文件,启用ADC功能
③复制ADC按键相关的代码到main.c
④在main()函数中初始化ADC按键,读取按键值

如果此文章对你有帮助,欢迎点赞 关注 收藏 转发.

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
感谢您的反馈!您提到的国信长天的开发可能使用的是不同的芯片,因此需要使用不同的代码来实现相同的功能。以下是基于STC芯片的51单片机实现测量声音频率并输出的代码,供您参考: ``` #include <reg51.h> #include <intrins.h> // 定义数码管段码 unsigned char code segCode[] = { 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71 }; // 定义计数器初值 unsigned int counter = 65535; // 延时函数 void Delay10us() { _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); } // 读取AD值 unsigned char GetADCResult() { unsigned char result; ADC_CONTR = 0x88; // 开始ADC转换 while (!(ADC_CONTR & 0x10)); // 等待ADC转换完成 result = ADC_RES; // 读取ADC值 return result; } // 主函数 void main() { unsigned char adValue, lastAdValue = 0; unsigned int frequency = 0; TMOD = 0x01; // 设置定时器模式 TH0 = 0xfc; // 设置定时器初值 TL0 = 0xfc; ET0 = 1; // 开启定时器中断 EA = 1; // 开启总中断 P0 = 0xff; // 数码管初始值 while (1) { adValue = GetADCResult(); // 获取AD值 if (adValue < 0xff && lastAdValue == 0xff) { // 检测到声音信号 TR0 = 1; // 开启定时器 } if (adValue == 0xff && lastAdValue < 0xff) { // 检测到声音信号结束 TR0 = 0; // 关闭定时器 frequency = 11059200 / counter; // 计算频率 counter = 65535; // 复位计数器 } lastAdValue = adValue; // 保存上一个AD值 // 将频率显示在数码管上 P0 = segCode[frequency / 1000]; Delay10us(); P0 = segCode[frequency % 1000 / 100] | 0x80; Delay10us(); P0 = segCode[frequency % 100 / 10]; Delay10us(); P0 = segCode[frequency % 10]; Delay10us(); } } // 定时器中断函数 void Timer0Interrupt() interrupt 1 { counter--; } ``` 这份代码使用了STC芯片的ADC模块和定时器,通过检测声音信号的上升沿和下降沿来计算声音的频率,并将频率显示在数码管上。需要注意的是,由于STC芯片的ADC模块和定时器与51单片机的实现略有不同,因此这份代码可能无法直接在其他芯片上使用。如果您仍然遇到问题,请提供更多的信息和反馈,我会尽力帮助您。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值