蓝桥杯嵌入式国赛笔记(2):拓展板按键程序设计

目录

1、前言

2、电路原理

3、代码编写

3.1 读取Btn电压

3.2 检索按键

3.3 main文件编写

3.3.1 进行变量定义

3.3.2 AD_Key函数

3.3.3 LCD函数

3.3.4 main函数

3.3.5 完整代码 

4、测试 

5、总结


1、前言

本文进行拓展板按键程序设计,拓展板的按键是通过采集模拟量来判断具体按键的,所以通过配置AD资源,通过模拟量转数字量获取相应的AD值,即可判断具体按下的按键编号。

2、电路原理

蓝桥杯的扩展板与核心板的引脚图如下:

ADC_KEY与PA5引脚连接即可通过PA5引脚捕获ADC_KEY的电压值。

下图为ADC_KEY的电路示意图,当按下不同的按键,电阻的分压是不同的,所以可以根据读取到的电压值进行判断不同的按键被按下。

3、代码编写

3.1 读取Btn电压

进行获取按键的电压值,并进行中值滤波设计,采集一组AD数据,通过冒泡排序即可找到其中的中值,用其来作为本轮检测滤波后的AD值。

如上图所示,获取采集到的AD数组取中值为按键AD的滤波值。 

#define BTN_BUFF_LEN 50

uint16_t Read_Btn(void)
{
	uint16_t Btn_Buffer[BTN_BUFF_LEN] = {0};
	
	int i,j;
	for(i=0;i<BTN_BUFF_LEN;i++)
	{
		Btn_Buffer[i] = getADC2();
	}
	
	uint16_t temp;
	for(i=0;i<BTN_BUFF_LEN/2;i++)
	{
		for(j=0;j<BTN_BUFF_LEN-i-1;i++)
		{
			if(Btn_Buffer[j+1]<Btn_Buffer[j])
			{
				temp = Btn_Buffer[j+1];
				Btn_Buffer[j+1] = Btn_Buffer[j];
				Btn_Buffer[j] = temp;
			}
		}
	}
	if(BTN_BUFF_LEN%2==0)
		return ((Btn_Buffer[BTN_BUFF_LEN/2-1]+Btn_Buffer[BTN_BUFF_LEN/2])/2);
	else
		return Btn_Buffer[BTN_BUFF_LEN/2];
}

3.2 检索按键

通过读取Btn电压,根据按键电路计算经验值,通过if-else语句进行判断 ,返回对应的按键值。

uint8_t Scan_Btn(void)
{
	uint16_t BtnAd = Read_Btn();

	if(BtnAd < (0xFFF*1/14))
		return 1;
	else if((BtnAd > (0xFFF*1/14)) && (BtnAd < (0xFFF*3/14)))
		return 2;
	else if((BtnAd > (0xFFF*3/14)) && (BtnAd < (0xFFF*5/14)))
		return 3;
	else if((BtnAd > (0xFFF*5/14)) && (BtnAd < (0xFFF*7/14)))
		return 4;
	else if((BtnAd > (0xFFF*7/14)) && (BtnAd < (0xFFF*9/14)))
		return 5;
	else if((BtnAd > (0xFFF*9/14)) && (BtnAd < (0xFFF*11/14)))
		return 6;
	else if((BtnAd > (0xFFF*11/14)) && (BtnAd < (0xFFF*13/14)))
		return 7;
	else if((BtnAd > (0xFFF*13/14)) && (BtnAd < (0xF6E)))
		return 8;
	else
		return 0;
}

3.3 main文件编写

3.3.1 进行变量定义

减速变量控制Key_Proc和Led_Proc的执行速度

Lcd_Disp_String为显示LCD的字符串

Btn_Num 为AD_Key的按键值

//*减速变量
__IO uint32_t uwTick_Key_Set_Point = 0;//控制Key_Proc的执行速度
__IO uint32_t uwTick_Led_Set_Point = 0;//控制Led_Proc的执行速度
//*LCD显示专用变量
unsigned char Lcd_Disp_String[22];
//AD_Key变量
uint8_t Btn_Num = 0;

3.3.2 AD_Key函数

AD_Key函数去执行AD模块的Scan_Btn();

void AD_Key_Proc(void)
{
	Btn_Num = Scan_Btn();
}

3.3.3 LCD函数

void Lcd_Proc(void)
{
	if((uwTick - uwTick_Lcd_Set_Point)<100)return;//减速处理
	uwTick_Lcd_Set_Point = uwTick;

	sprintf((char*)Lcd_Disp_String,"AD_Key:%d",Btn_Num);
	LCD_DisplayStringLine(Line2,Lcd_Disp_String);

}

3.3.4 main函数

int main(void)
{
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
  /* Configure the system clock */
  SystemClock_Config();
	
	/*bsp资源的初始化*/
    AD_Key_Init();

	LCD_Init();
	LCD_Clear(Black);
	LCD_SetBackColor(Black);
    LCD_SetTextColor(White);

  while (1)
  {
		Lcd_Proc();
  }
}

3.3.5 完整代码 

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "RCC\bsp_rcc.h"
#include "LCD\bsp_lcd.h"
#include "ADC\bsp_adc.h"
//***全局变量声明区
//*减速变量
__IO uint32_t uwTick_Lcd_Set_Point = 0;//控制Lcd_Proc的执行速度

//*LCD显示专用变量
unsigned char Lcd_Disp_String[22];

//AD_Key变量
uint8_t Btn_Num = 0;

	
//***子函数声明区
void Lcd_Proc(void);
void AD_Key_Proc(void);

//***系统主函数
int main(void)
{
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
  /* Configure the system clock */
  SystemClock_Config();
	
  /*bsp资源的初始化*/
  AD_Key_Init();

  LCD_Init();
  LCD_Clear(Black);
  LCD_SetBackColor(Black);
  LCD_SetTextColor(White);
  while (1)
  {
		AD_Key_Proc();
		Lcd_Proc();
  }
}

//***LCD子函数
void Lcd_Proc(void)
{
	if((uwTick - uwTick_Lcd_Set_Point)<100)return;//减速处理
	uwTick_Lcd_Set_Point = uwTick;

	sprintf((char*)Lcd_Disp_String,"AD_Key:%d",Btn_Num);
	LCD_DisplayStringLine(Line2,Lcd_Disp_String);
}

void AD_Key_Proc(void)
{
	Btn_Num = Scan_Btn();
}


void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

4、测试 

使用开发板通过杜邦线连接扩展版,进行AD_Key模块的按键测试。可以看到在按不同按键时,LCD屏幕显示了对应的按键值。

5、总结

本文通过AD采集并滤波的方式获取到按键电压,再根据不同按键产生不同电压范围的电路原理进行按键的判断,通过代码测试成功。 

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值