第十届蓝桥杯嵌入式省赛程序设计题(HAL库版)

2024-03-30 14:18

本文主要是介绍第十届蓝桥杯嵌入式省赛程序设计题(HAL库版),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

蓝桥杯嵌入式(HAL库版)省赛系列文章

第六届蓝桥杯嵌入式省赛程序设计题(HAL库版)
第九届蓝桥杯嵌入式省赛程序设计题(HAL库版)
第十一届蓝桥杯嵌入式省赛程序设计题(HAL库版)
第十三届蓝桥杯嵌入式省赛程序设计题(HAL库版)


第十届蓝桥杯嵌入式省赛程序设计题(HAL库版)

  • 蓝桥杯嵌入式(HAL库版)省赛系列文章
  • 前言
  • 一、赛题要求
    • 1.硬件框图
    • 2.功能描述
  • 二、配置工程
    • 1.配置流程
      • 1.1选择芯片
      • 1.2配置引脚
      • 1.3配置时钟
      • 1.4建立工程
  • 三、软件实现(模块化编程)
    • 1. 按键扫描
    • 2. 按键控制电压参数改变(配合扫描函数使用)
    • 3. 按键控制指示灯序号改变(配合扫描函数使用)
    • 4. 读取ADC数值(启动->读取->返回)
    • 5. 上限报警
    • 6. 下限报警
    • 7. 正常工作情况
    • 8. 数据显示界面
    • 9. 参数设置界面
    • 10. 界面切换
  • 总结


前言

报名参加蓝桥杯嵌入式组别,通过做往年省赛例题的方式进行能力整体提升,需要的小伙伴可以简单看一下哈,写的不好,还请大家多多包涵,欢迎大佬指出问题!
需要其他届赛题的朋友可以从顶部链接直达喔!
闲话少说,进入正题!


一、赛题要求

1.硬件框图

硬件框图

2.功能描述

基本功能数据显示界面
参数配置界面
参数配置界面要求
按键功能B1
按键功能B2
按键功能B3、B4
要求
初始状态:

  1. 默认输出提醒指示灯。
    超过上限提醒指示灯:LD1
    低于下限提醒指示灯:LD2
  2. 默认电压阈值参数。
    电压的上限值:2.4V
    电压的下限值:1.2V

根据上述任务要求,使用STM32CubeMX生成Keil文件进行程序编写。

二、配置工程

1.配置流程

使用STM32CubeMX的流程可以概括为四个步骤,分别为:选择芯片、配置引脚、配置时钟、建立工程

1.1选择芯片

蓝桥杯嵌入式平台所使用的芯片为STM32G431RBTx,故我们进行搜索并建立工程。
在这里插入图片描述

1.2配置引脚

LED灯由PC8-PC15控制,低电平点亮,由PD2引脚控制锁存,低电平变为高电平开锁,高电平变为低电平上锁,设置引脚模式为输出模式。在这里插入图片描述
开发板上共配备了4个按键,分别连接在PB0,PB1,PB2,PA0引脚上,设置引脚模式为输入模式。在这里插入图片描述
由于题目中设计电压测量,故需要配置ADC,参考原理图可知,R37与PB15相连,PB15为ADC2_IN15在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.3配置时钟

时钟配置这里考虑到芯片最高频率为170MHz,所以我直接选择将HCLK一栏设置为最大值170MHz在这里插入图片描述

1.4建立工程

一定要将Toolchain/IDE更改为MDK-ARM,版本号根据大家的实际情况确定即可
在这里插入图片描述
这里我勾选的是只将必要的库文件粘贴过来,可以减小工程建立的大小。
在这里插入图片描述
至此,建立工程阶段结束,可以开始写代码啦!

三、软件实现(模块化编程)

1. 按键扫描

uint8_t Key_Scan(GPIO_TypeDef *GPIOx,uint16_t GPIO_PIN)
{if(HAL_GPIO_ReadPin(GPIOx,GPIO_PIN) == RESET){while(HAL_GPIO_ReadPin(GPIOx,GPIO_PIN) == RESET);return 2;}elsereturn 1;
}

2. 按键控制电压参数改变(配合扫描函数使用)

void Key_Volt_Change(double *Volt)
{if (Key_Scan(B3_Plus_GPIO_Port,B3_Plus_Pin) == 2){*Volt += 0.3;if(*Volt >= 3.3)*Volt = 3.3;}if(Key_Scan(B4_Minus_GPIO_Port,B4_Minus_Pin) == 2){*Volt -= 0.3;if(*Volt <= 0)*Volt = 0;}
}

3. 按键控制指示灯序号改变(配合扫描函数使用)

void Key_LD_Change(uint16_t *LD)
{if (Key_Scan(B3_Plus_GPIO_Port,B3_Plus_Pin) == 2){*LD += 1;if(*LD >= 8)*LD = 8;}if(Key_Scan(B4_Minus_GPIO_Port,B4_Minus_Pin) == 2){*LD -= 1;if(*LD <= 1)*LD = 1;}
}

4. 读取ADC数值(启动->读取->返回)

double Get_ADC(void)
{HAL_ADC_Start(&hadc2);						//启动ADC2adc = HAL_ADC_GetValue(&hadc2);		//定义变量adc,用于获取ADC2的值return (adc*3.3/4096);						//函数返回值为adc*3.3/4096,3.3V为最大电压值,4096为12位的LSB
}

5. 上限报警

void LD_Upper_Warning(uint8_t Upper)
{GPIOC -> ODR = ~(0x0001 << (Upper + 7));HAL_GPIO_WritePin(LD_Control_GPIO_Port,LD_Control_Pin,GPIO_PIN_SET);HAL_GPIO_WritePin(LD_Control_GPIO_Port,LD_Control_Pin,GPIO_PIN_RESET);HAL_Delay(200);HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPIO_PIN_SET);HAL_GPIO_WritePin(LD_Control_GPIO_Port,LD_Control_Pin,GPIO_PIN_SET);HAL_GPIO_WritePin(LD_Control_GPIO_Port,LD_Control_Pin,GPIO_PIN_RESET);
}

6. 下限报警

void LD_Lower_Warning(uint8_t Lower)
{GPIOC -> ODR = ~(0x0001 << (Lower + 7));HAL_GPIO_WritePin(LD_Control_GPIO_Port,LD_Control_Pin,GPIO_PIN_SET);HAL_GPIO_WritePin(LD_Control_GPIO_Port,LD_Control_Pin,GPIO_PIN_RESET);HAL_Delay(200);HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPIO_PIN_SET);HAL_GPIO_WritePin(LD_Control_GPIO_Port,LD_Control_Pin,GPIO_PIN_SET);HAL_GPIO_WritePin(LD_Control_GPIO_Port,LD_Control_Pin,GPIO_PIN_RESET);
}

7. 正常工作情况

void LD_Normal()
{HAL_GPIO_WritePin(LD_Control_GPIO_Port,LD_Control_Pin,GPIO_PIN_SET);HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPIO_PIN_SET);HAL_GPIO_WritePin(LD_Control_GPIO_Port,LD_Control_Pin,GPIO_PIN_RESET);
}

8. 数据显示界面

if(KEYB1_FLAG == 0){LCD_SetBackColor(Blue);LCD_SetTextColor(White);LCD_DisplayStringLine(Line0,(uint8_t*)"                    ");LCD_DisplayStringLine(Line1,(uint8_t*)"       Main         ");LCD_DisplayStringLine(Line2,(uint8_t*)"                    ");LCD_DisplayStringLine(Line3,(uint8_t*)"                    ");LCD_DisplayStringLine(Line4,(uint8_t*)"  Volt:             ");LCD_DisplayStringLine(Line5,(uint8_t*)"                    ");LCD_DisplayStringLine(Line6,(uint8_t*)"                    ");LCD_DisplayStringLine(Line7,(uint8_t*)"                    ");LCD_DisplayStringLine(Line8,(uint8_t*)"                    ");LCD_DisplayStringLine(Line9,(uint8_t*)"                    ");V = Get_ADC();sprintf(ADC_TEXT,"  Volt:%.2fV        ",V);LCD_DisplayStringLine(Line4,(uint8_t*)ADC_TEXT);if( V >= Max_Volt){LCD_DisplayStringLine(Line6,(uint8_t*)"  Status:Upper      ");LD_Upper_Warning();}if( V < Max_Volt && V > Min_Volt){LCD_DisplayStringLine(Line6,(uint8_t*)"  Status:Normal     ");LD_Normal();}if( V <= Min_Volt){LCD_DisplayStringLine(Line6,(uint8_t*)"  Status:Lower      ");LD_Lower_Warning();}if(Key_Scan(B1_Setting_GPIO_Port,B1_Setting_Pin) ==2){KEYB1_FLAG += 1;}}

9. 参数设置界面

else{if(Key_Scan(B2_Selection_GPIO_Port,B2_Selection_Pin) == 2)KEYB2_FLAG += 1;if(KEYB2_FLAG > 4)KEYB2_FLAG = 0;LCD_SetBackColor(White);LCD_SetTextColor(Blue);LCD_DisplayStringLine(Line0,(uint8_t*)"                    ");LCD_DisplayStringLine(Line1,(uint8_t*)"      Setting       ");LCD_DisplayStringLine(Line2,(uint8_t*)"                    ");LCD_DisplayStringLine(Line5,(uint8_t*)"                    ");LCD_DisplayStringLine(Line8,(uint8_t*)"                    ");LCD_DisplayStringLine(Line9,(uint8_t*)"                    ");sprintf(LCD_TEXT,"  Max Volt:%.2fV       ",Max_Volt);if(KEYB2_FLAG == 1){LCD_SetBackColor(Green);LCD_DisplayStringLine(Line3,(uint8_t*)LCD_TEXT);LCD_SetBackColor(White);Key_Volt_Change(&Max_Volt);}elseLCD_DisplayStringLine(Line3,(uint8_t*)LCD_TEXT);sprintf(LCD_TEXT,"  Min Volt:%.2fV       ",Min_Volt);if(KEYB2_FLAG == 2){LCD_SetBackColor(Green);LCD_DisplayStringLine(Line4,(uint8_t*)LCD_TEXT);LCD_SetBackColor(White);Key_Volt_Change(&Min_Volt);}elseLCD_DisplayStringLine(Line4,(uint8_t*)LCD_TEXT);sprintf(LD_TEXT,"  Upper:LD%d            ",Upper);if(KEYB2_FLAG == 3){LCD_SetBackColor(Green);LCD_DisplayStringLine(Line6,(uint8_t*)LD_TEXT);LCD_SetBackColor(White);Key_LD_Change(&Upper);}elseLCD_DisplayStringLine(Line6,(uint8_t*)LD_TEXT);sprintf(LD_TEXT,"  Lower:LD%d            ",Lower);if(KEYB2_FLAG == 4){LCD_SetBackColor(Green);LCD_DisplayStringLine(Line7,(uint8_t*)LD_TEXT);LCD_SetBackColor(White);Key_LD_Change(&Lower);}elseLCD_DisplayStringLine(Line7,(uint8_t*)LD_TEXT);if(Key_Scan(B1_Setting_GPIO_Port,B1_Setting_Pin) ==2){KEYB1_FLAG += 1;}if(Upper == Lower){LCD_SetTextColor(Red);LCD_DisplayStringLine(Line5,(uint8_t*)"  LD Conflicted!    ");}elseLCD_DisplayStringLine(Line5,(uint8_t*)"                    ");}

10. 界面切换

if(KEYB1_FLAG >1)KEYB1_FLAG = 0;

总结

通过上述代码基本可以实现任务的全部要求,但存在频繁闪烁的问题,我也不是很清楚是因为硬件原因还是软件原因,还望各路大佬指出!

如果需要全部代码可以直接私信我哈,文章已经很长啦,就不放全部代码啦!希望与各位小伙伴一同进步呀!

这篇关于第十届蓝桥杯嵌入式省赛程序设计题(HAL库版)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/861717

相关文章

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

荣耀嵌入式面试题及参考答案

在项目中是否有使用过实时操作系统? 在我参与的项目中,有使用过实时操作系统。实时操作系统(RTOS)在对时间要求严格的应用场景中具有重要作用。我曾参与的一个工业自动化控制项目就采用了实时操作系统。在这个项目中,需要对多个传感器的数据进行实时采集和处理,并根据采集到的数据及时控制执行机构的动作。实时操作系统能够提供确定性的响应时间,确保关键任务在规定的时间内完成。 使用实时操作系统的

嵌入式Openharmony系统构建与启动详解

大家好,今天主要给大家分享一下,如何构建Openharmony子系统以及系统的启动过程分解。 第一:OpenHarmony系统构建      首先熟悉一下,构建系统是一种自动化处理工具的集合,通过将源代码文件进行一系列处理,最终生成和用户可以使用的目标文件。这里的目标文件包括静态链接库文件、动态链接库文件、可执行文件、脚本文件、配置文件等。      我们在编写hellowor

嵌入式方向的毕业生,找工作很迷茫

一个应届硕士生的问题: 虽然我明白想成为技术大牛需要日积月累的磨练,但我总感觉自己学习方法或者哪些方面有问题,时间一天天过去,自己也每天不停学习,但总感觉自己没有想象中那样进步,总感觉找不到一个很清晰的学习规划……眼看 9 月份就要参加秋招了,我想毕业了去大城市磨练几年,涨涨见识,拓开眼界多学点东西。但是感觉自己的实力还是很不够,内心慌得不行,总怕浪费了这人生唯一的校招机会,当然我也明白,毕业

深入探索嵌入式 Linux

摘要:本文深入探究嵌入式 Linux。首先回顾其发展历程,从早期尝试到克服诸多困难逐渐成熟。接着阐述其体系结构,涵盖硬件、内核、文件系统和应用层。开发环境方面包括交叉编译工具链、调试工具和集成开发环境。在应用领域,广泛应用于消费电子、工业控制、汽车电子和智能家居等领域。关键技术有内核裁剪与优化、设备驱动程序开发、实时性增强和电源管理等。最后展望其未来发展趋势,如与物联网融合、人工智能应用、安全性与

C语言程序设计(数据类型、运算符与表达式)

一、C的数据类型 C语言提供的数据类型: 二、常量和变量 2.1常量和符号常量 在程序运行过程中,其值不能被改变的量称为常量。 常量区分为不同的类型: 程序中用#define(预处理器指令)命令行定义变量将代表常量,用一个标识符代表一个常量,称为符合常量。 2.2变量 变量代表内存中具有特定属性的一个存储单元,用来存放数据,在程序运行期间,这些值是可以 改变的。 变

C语言程序设计(选择结构程序设计)

一、关系运算符和关系表达式 1.1关系运算符及其优先次序 ①<(小于) ②<=(小于或等于) ③>(大于) ④>=(大于或等于 ) ⑤==(等于) ⑥!=(不等于) 说明: 前4个优先级相同,后2个优先级相同,关系运算符的优先级低于算术运算符,关系运算符的优先级高于赋值运算符 1.2关系表达式 用关系运算符将两个表达式(可以是算术表达式或关系表达式,逻辑表达式,赋值表达式,字符

C语言蓝桥杯

一、语言基础 竞赛常用库函数 最值查询 min_element和max_element在vector(迭代器的使用) nth_element函数的使用 例题lanqiao OJ 497成绩分析 第一种用min_element和max_element函数的写法 第二种用min和max的写法 二分查找 二分查找只能对数组操作 binary_s

嵌入式技术的核心技术有哪些?请详细列举并解释每项技术的主要功能和应用场景。

嵌入式技术的核心技术包括处理器技术、IC技术和设计/验证技术。 1. 处理器技术    通用处理器:这类处理器适用于不同类型的应用,其主要特征是存储程序和通用的数据路径,使其能够处理各种计算任务。例如,在智能家居中,通用处理器可以用于控制和管理家庭设备,如灯光、空调和安全系统。    单用途处理器:这些处理器执行特定程序,如JPEG编解码器,专门用于视频信息的压缩或解压。在数字相机中,单用途

STM32CubeMX和HAL库-新建项目

目录 新建项目 选择开发板  MCU图形化配置界面总览 MCU配置 新建项目 新建项目包含选择MCU创建项目、选择开发板新建项目和交叉选择MCU新建项目三部分。 1. 选择MCU创建项目 单击主菜单项File→New Project,或Home视图上的ACCESS TO MCU SELECTOR 按钮,都可以打开的New Project from a MCU/MPU对话框。