当前位置: 首页 > news >正文

蓝桥杯嵌入式国赛笔记(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 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采集并滤波的方式获取到按键电压,再根据不同按键产生不同电压范围的电路原理进行按键的判断,通过代码测试成功。 

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • pwa动态修改manifest.json(start_url)
  • PHP发票真假API、医疗电子票据查验、发票识别接口开发示例
  • 元组推导式
  • Keras深度学习框架第二十九讲:在自定义训练循环中应用KerasTuner超参数优化
  • qt 布局学习笔记
  • 气膜体育馆主要能耗解析—轻空间
  • 2024,java开发,已经炸了吗?
  • Python 开心消消乐
  • C# 实现腾讯云点播之媒体上传常用接口
  • java中的类加载器
  • 精通C++ STL(二):string类的模拟实现
  • AI绘画图生图有什么用?
  • React项目中使用各表单库性能对比调研报告
  • 等保服务是一次性服务吗?为什么?怎么理解?
  • wireshark抓包,丢包分析?
  • Druid 在有赞的实践
  • JavaScript/HTML5图表开发工具JavaScript Charts v3.19.6发布【附下载】
  • nginx 配置多 域名 + 多 https
  • PHP 使用 Swoole - TaskWorker 实现异步操作 Mysql
  • react-core-image-upload 一款轻量级图片上传裁剪插件
  • sublime配置文件
  • Twitter赢在开放,三年创造奇迹
  • yii2权限控制rbac之rule详细讲解
  • 编写高质量JavaScript代码之并发
  • 搞机器学习要哪些技能
  • 观察者模式实现非直接耦合
  • 前端每日实战:61# 视频演示如何用纯 CSS 创作一只咖啡壶
  • 前言-如何学习区块链
  • 视频flv转mp4最快的几种方法(就是不用格式工厂)
  • 学习笔记DL002:AI、机器学习、表示学习、深度学习,第一次大衰退
  • 正则与JS中的正则
  • #100天计划# 2013年9月29日
  • #中的引用型是什么意识_Java中四种引用有什么区别以及应用场景
  • (3)选择元素——(17)练习(Exercises)
  • (4)(4.6) Triducer
  • (JSP)EL——优化登录界面,获取对象,获取数据
  • (动态规划)5. 最长回文子串 java解决
  • (九十四)函数和二维数组
  • (每日持续更新)信息系统项目管理(第四版)(高级项目管理)考试重点整理 第13章 项目资源管理(七)
  • (四)Linux Shell编程——输入输出重定向
  • (原創) 如何動態建立二維陣列(多維陣列)? (.NET) (C#)
  • (转)http-server应用
  • (转)jQuery 基础
  • (转)甲方乙方——赵民谈找工作
  • .MyFile@waifu.club.wis.mkp勒索病毒数据怎么处理|数据解密恢复
  • .NET BackgroundWorker
  • .NET CF命令行调试器MDbg入门(一)
  • .net framwork4.6操作MySQL报错Character set ‘utf8mb3‘ is not supported 解决方法
  • .Net mvc总结
  • .NET 依赖注入和配置系统
  • .net获取当前url各种属性(文件名、参数、域名 等)的方法
  • .NET命令行(CLI)常用命令
  • .NET下的多线程编程—1-线程机制概述
  • @Mapper作用
  • @RequestMapping 和 @GetMapping等子注解的区别及其用法