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

devtools/2024/10/15 5:30:14/

目录

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 50uint16_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);elsereturn 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;elsereturn 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采集并滤波的方式获取到按键电压,再根据不同按键产生不同电压范围的电路原理进行按键的判断,通过代码测试成功。 


http://www.ppmy.cn/devtools/42685.html

相关文章

Android android.os.DeadObjectException aidl通信异常分析及解决

问题描述 做一款音乐播放应用&#xff0c;播放服务是通过AIDL形式对外暴露&#xff0c;允许跨进程调用且多个App同时操作音乐播放&#xff0c;偶现android.os.DeadObjectException问题 12-15 09:28:12.371: W/System.err(5412): android.os.DeadObjectException 12-15 09:28:…

Rust:如何在 Windows 的 Linux 子系统(WSL)下安装

一、安装步骤 在Windows Subsystem for Linux (WSL)下安装Rust&#xff0c;可以按照以下步骤进行&#xff1a; 打开WSL终端&#xff1a; 首先&#xff0c;确保你的WSL已经安装并正常运行。你可以在Windows搜索栏中输入“WSL”并选择你安装的Linux发行版&#xff08;如Ubuntu&a…

在 Visual Studio 2022 (VS2022) 中删除 Git 分支的步骤如下

git branch -r PS \MauiApp1> git push origin --delete “20240523备份” git push origin --delete “20240523备份”

Node.js —— Express 中间件、接口编写、接口跨域 【0基础向Express模块学习】

目录 中间件的概念 什么是中间件 现实生活中的例子 Express 中间件的调用流程 ​编辑 Express 中间件的格式 next 函数的作用 Express 中间件的初体验 定义中间件函数 全局生效的中间件 定义全局中间件的简化形式 中间件的作用 ​编辑 定义多个全局中间件 局部生…

光伏电站在线监测智能诊断系统:开启无人值守新纪元

光伏电站在线监测智能诊断系统&#xff1a;开启无人值守新纪元 大家都知道光伏电站是通过汲取着太阳的光芒&#xff0c;为人类提供源源不断的电能源。然而&#xff0c;随着光伏电站规模的扩大和复杂性的增加&#xff0c;如何有效提高发电效率、减少人工维护成本&#xff0c;实…

【深度学习】多卡训练问题及解决方案

使用双卡训练遇到的问题1&#xff1a; Error: mkl-service Intel(R) MKL: MKL_THREADING_LAYERINTEL is incompatible with libgomp.so.1 library. Try to import numpy first or set the threading layer accordingly. Set MKL_SERVICE_FORCE_INTEL to force it. 解决…

双路金牌至强高性能服务器主板,具有高可靠全加固的超融合计算服务器的特征

产品介绍 产品概述 是一款基于Intel Xeon Gold系列处理器设计的双CPU主板&#xff0c;遵循商用EEB主板规范&#xff0c;专为高性能全加固服务器设计&#xff0c;具有贴片内存颗粒64GB DDR4内存&#xff0c;并提供了丰富的高强度IO接口连接器&#xff08;6路SATA3.0/USB3.0/千兆…

10个顶级的论文降重指令,让你的论文降重至1.9%

10个顶级的论文降重指令&#xff0c;本硕博写论文必备&#xff01; 在ChatGPT4o对话框中输入&#xff1a;写一个Spring BootVue实现的车位管理系统的论文大纲&#xff0c;并对其具体章节进行详细描述。 几小时即可完成一份1万字论文的编写 在GPTS中搜索论文降重&#xff0c;使…