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

一.题目分析

(1).题目

(2).题目分析

1.参考配置界面

注意上限和下限的调整,上限值必须大于下限值,低于下限LD2会闪烁,低于上限LD1会闪烁

2.按键功能分析

B1:显示界面和设置界面相互切换,同时将数据保存到E2PROM里面

B2:切换选择参数选项

B3:加按键(指示灯序号和电压参数)---要有边界保护,电压参数设置范围是0~3.3V,LED设置为LD1~LD8

B4:减按键(指示灯序号和电压参数)---要有边界保护,电压参数设置范围是0~3.3V,LED设置为LD1~LD8

3.LED功能分析

a. 输出电压高于上限,上限指示灯闪烁

b.输出电压低于下限,下限指示灯闪烁

c. 输出电压在上下限之间,两灯熄灭

d.除了上下限指示灯以外的其他灯熄灭

(3).逻辑导图

二.CubeMX配置

由于蓝桥杯使用的板子都是STM32G431RBT6,配置都是相同的,模板已经在第六届蓝桥杯嵌入式省赛程序设计题解析(基于HAL库)-CSDN博客配置完成,大家可以前往学习

三.相关代码实现

(1)MAIN

1.全局变量声明

#include "main.h"
#include "RCC\bsp_rcc.h"
#include "KEY_LED\bsp_key_led.h"
#include "LCD\bsp_lcd.h"
#include "I2C\bsp_i2c.h"
#include "ADC\bsp_adc.h"//***全局变量声明区
//*减速变量
__IO uint32_t uwTick_Key_Set_Point = 0;//控制Key_Proc的执行速度
__IO uint32_t uwTick_Led_Set_Point = 0;//控制Led_Proc的执行速度
__IO uint32_t uwTick_Lcd_Set_Point = 0;//控制Lcd_Proc的执行速度//*按键扫描专用变量
uint8_t ucKey_Val, unKey_Down, ucKey_Up, ucKey_Old;//*LED专用变量
uint8_t ucLed = 0x0;
uint8_t ucLed_Bor = 0x01;//*LCD显示专用变量
uint8_t Lcd_Disp_String[21];//最多显示20个字符//*EEPROM的相关变量
uint8_t EEPROM_String_1[5] = {0x11,0x22,0x33,0x44,0x55};
uint8_t EEPROM_String_2[5] = {0};//系统全局变量
uint8_t Sys_State;//整体状态
float Voltage;//R37的电压值
uint8_t Vot_State;//电压状态 0-低于 1-中间 2-高于
uint8_t Max_Min_LED[4] = {24,12,1,2};//0-上限值 1-下限值 2-高报警灯 3-低报警灯//***子函数声明区
void Key_Proc(void);
void Led_Proc(void);
void Lcd_Proc(void);

2.系统主函数

int main(void)
{/* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* Configure the system clock */SystemClock_Config();/*bsp资源的初始化*/KEY_LED_Init();LCD_Init();LCD_Clear(White);LCD_SetBackColor(White);LCD_SetTextColor(Blue);	I2CInit();ADC2_Init();	while (1){Key_Proc();Led_Proc();Lcd_Proc();}
}

3.按键扫描子函数

a.逻辑框图

b.程序源码

//***按键扫描子函数
void Key_Proc(void)
{if((uwTick -  uwTick_Key_Set_Point)<50)	return;//减速函数uwTick_Key_Set_Point = uwTick;ucKey_Val = Key_Scan();unKey_Down = ucKey_Val & (ucKey_Old ^ ucKey_Val); ucKey_Up = ~ucKey_Val & (ucKey_Old ^ ucKey_Val);	ucKey_Old = ucKey_Val;switch(unKey_Down){case 1://B1按键if(Sys_State == 0)  {Sys_State = 1;}else {Sys_State = 0;	iic_24c02_write(Max_Min_LED, 0, 4);}	LCD_Clear(White);break;case 2://B2按键if(Sys_State){if(++Sys_State == 5)Sys_State = 1;}break;//	uint8_t Max_Min_LED[4];//0-上限值 1-下限值 2-高报警灯 3-低报警灯case 3://B3按键+switch(Sys_State){case 1://上限值+0.3Max_Min_LED[0] += 3;if((Max_Min_LED[0] >= 33)&&(Max_Min_LED[0] <= 40))Max_Min_LED[0] = 33;break;case 2://下限值+0.3if((Max_Min_LED[1]+3) < Max_Min_LED[0])Max_Min_LED[1] += 3;						break;	case 3:if(++Max_Min_LED[2] >=8) Max_Min_LED[2] = 8;if(Max_Min_LED[2] == Max_Min_LED[3]){if(Max_Min_LED[3] == 8)Max_Min_LED[2] = 7;else {if(++Max_Min_LED[2] >=8) Max_Min_LED[2] = 8;		}								}							break;	case 4:if(++Max_Min_LED[3] >=8) Max_Min_LED[3] = 8;if(Max_Min_LED[3] == Max_Min_LED[2]){if(Max_Min_LED[2] == 8)Max_Min_LED[3] = 7;else {if(++Max_Min_LED[2] >=8) Max_Min_LED[2] = 8;		}								}									break;			}	break;case 4://B4按键-switch(Sys_State){case 1://上限值-0.3if((Max_Min_LED[0]-3) > Max_Min_LED[1])Max_Min_LED[0] -= 3;						break;case 2://下限值-0.3Max_Min_LED[1] -= 3;if(Max_Min_LED[1] >= 200)Max_Min_LED[1] = 0;					break;		case 3://-if(--Max_Min_LED[2] == 0) Max_Min_LED[2] = 1;if(Max_Min_LED[2] == Max_Min_LED[3]){if(Max_Min_LED[3] == 1)Max_Min_LED[2] = 2;else {if(--Max_Min_LED[2] == 0) Max_Min_LED[2] = 1;		}								}							break;	case 4://-if(--Max_Min_LED[3] == 0) Max_Min_LED[3] = 1;if(Max_Min_LED[3] == Max_Min_LED[2]){if(Max_Min_LED[2] == 1)Max_Min_LED[3] = 2;else {if(--Max_Min_LED[2] ==0) Max_Min_LED[2] = 1;		}								}									break;	}break;}
}

3.LED扫描子函数

a.逻辑分析

根据上下限和中间值控制灯的亮灭

b.程序源码

//***LED扫描子函数
void Led_Proc(void)
{if((uwTick -  uwTick_Led_Set_Point)<200)	return;//减速函数uwTick_Led_Set_Point = uwTick;
//Max_Min_LED    2-高报警灯 3-低报警灯    LD8    ucLed  1000 0000switch(Vot_State){case 0://低于下限ucLed ^= ( ucLed_Bor << (Max_Min_LED[3]-1));break;case 1://中间ucLed = 0x00;break;		case 2://高于上限ucLed ^= ( ucLed_Bor << (Max_Min_LED[2]-1));			break;	}LED_Disp(ucLed);
}

3.LCD扫描子函数

a.逻辑框图

b.程序源码

void Lcd_Proc(void)
{if((uwTick -  uwTick_Lcd_Set_Point)<100)	return;//减速函数uwTick_Lcd_Set_Point = uwTick;//采集数据专用区域
//	uint8_t Max_Min_LED[4];//0-上限值 1-下限值 2-高报警灯 3-低报警灯Voltage = ((((float)getADC2())/4096)*3.3);if((Voltage*10) > Max_Min_LED[0])Vot_State = 2;else if((Voltage*10) < Max_Min_LED[1])Vot_State = 0;	else Vot_State = 1;			//我的代码if(!Sys_State)//在主界面{sprintf((char *)Lcd_Disp_String, "    Main   ");LCD_DisplayStringLine(Line1, Lcd_Disp_String);	sprintf((char *)Lcd_Disp_String, "  Volt:%4.2fV",Voltage);LCD_DisplayStringLine(Line4, Lcd_Disp_String);		switch(Vot_State){case 0:sprintf((char *)Lcd_Disp_String, "  Status:Lower    ");break;case 1:sprintf((char *)Lcd_Disp_String, "  Status:Normal    ");break;				case 2:sprintf((char *)Lcd_Disp_String, "  Status:Upper    ");break;				}LCD_DisplayStringLine(Line6, Lcd_Disp_String);			}else//在设置界面{
//	uint8_t Max_Min_LED[4];//0-上限值 1-下限值 2-高报警灯 3-低报警灯		sprintf((char *)Lcd_Disp_String, "    Setting   ");LCD_DisplayStringLine(Line1, Lcd_Disp_String);	sprintf((char *)Lcd_Disp_String, " Max Volt:%3.1fV   ",((float)Max_Min_LED[0]/10.0));if(Sys_State == 1) 		LCD_SetBackColor(Green);LCD_DisplayStringLine(Line4, Lcd_Disp_String);				LCD_SetBackColor(White);sprintf((char *)Lcd_Disp_String, " Min Volt:%3.1fV   ",((float)Max_Min_LED[1]/10.0));if(Sys_State == 2) 		LCD_SetBackColor(Green);LCD_DisplayStringLine(Line5, Lcd_Disp_String);			LCD_SetBackColor(White);sprintf((char *)Lcd_Disp_String, " Upper:LD%1d    ",(unsigned int)Max_Min_LED[2]);if(Sys_State == 3) 		LCD_SetBackColor(Green);		LCD_DisplayStringLine(Line6, Lcd_Disp_String);				LCD_SetBackColor(White);		sprintf((char *)Lcd_Disp_String, " Lower:LD%1d     ",(unsigned int)Max_Min_LED[3]);if(Sys_State == 4) 		LCD_SetBackColor(Green);				LCD_DisplayStringLine(Line7, Lcd_Disp_String);		LCD_SetBackColor(White);		}
}

(2)BSP

第六届蓝桥杯嵌入式省赛程序设计题解析(基于HAL库)-CSDN博客里面有详细的讲解,大家可前往此链接学习

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/434996.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java IO 和 NIO

在 Java 编程中&#xff0c;输入输出&#xff08;IO&#xff09;是不可或缺的部分&#xff0c;随着技术的发展&#xff0c;Java 的 IO 系统也经历了显著的变化。本文将深入探讨 Java IO 和 NIO 的历史、优缺点以及适用场景。 1. Java IO 的历史 Java IO 包&#xff08;java.i…

Solidity智能合约中的异常处理(error、require 和 assert)

Solidity 中的三种抛出异常方法&#xff1a;error、require 和 assert 在 Solidity 开发中&#xff0c;异常处理是确保智能合约安全性和正确性的关键步骤。Solidity 提供了三种主要方法来抛出异常&#xff1a;error、require 和 assert。本文将详细介绍这三种方法的用途、实现方…

nginx+keepalived健康检查案例详解(解决nginx出现故障却不能快速切换到备份服务器的问题)

文章目录 简介配置过程前置环境请看创建健康检查脚本结果测试 简介 在我们通过nginxkeepalived实现高可用后&#xff0c;会发现nginx出现故障的时候keepalived并不会将虚拟ip切换到备份服务器上其原理就是nginx和keepalived是两个独立的服务&#xff0c;Nginx的故障状态不会触…

使用Docker-Compose部署SpringBoot项目的案例

Docker-Compose是Docker官方的一个开源项目&#xff0c;主要用于实现对Docker容器集群的快速编排和管理。该项目由Python编写&#xff0c;通过调用Docker服务提供的API来管理容器。只要所操作的平台支持Docker API&#xff0c;就可以利用Docker-Compose进行编排管理。Docker-Co…

【微服务即时通讯系统】——brpc远程过程调用、百度开源的RPC框架、brpc的介绍、brpc的安装、brpc使用和功能测试

文章目录 brpc1. brpc的介绍1.1 rpc的介绍1.2 rpc的原理1.3 grpc和brpc 2. brpc的安装3. brpc使用3.1 brpc接口介绍 4. brpc使用测试4.1 brpc同步和异步调用 brpc 1. brpc的介绍 1.1 rpc的介绍 RPC&#xff08;Remote Procedure Call&#xff09;远程过程调用&#xff0c;是一…

X86下一文带你构建Apollo9.0运行环境(基于Ubuntu20.04避坑版)

X86下一文带你构建Apollo9.0运行环境基于Ubuntu20.04避坑版 前言准备安装基础软件1.安装Docker19.03安装Nvidia驱动安装配置Nvidia container toolkit 下载Apollo源码&#xff08;笔者下载的是releases下9.0.0版本&#xff0c;大家可以参考&#xff09;编译Apollo9.0下载资源包…

如何使用GitHub Desktop管理GitLab库

不管是新手还是老手&#xff0c;Github Desktop都是在苹果系统和Windows系统上管理与创建项目的不错的方式&#xff0c;GitHub Desktop都能够让在GitHub上的工作流更为简单快捷。 注意&#xff0c;以下步骤只支持原版的GitHub Desktop 第一步 从这下载GitHub Desktop打开你的G…

【hot100-java】【柱状图中最大的矩形】

R9-栈篇 面积最大矩形的高度一定是 heights 中的元素 简单解释&#xff0c;就是说&#xff0c;最大高度必然是heights中的一个元素&#xff0c;我们假设是h&#xff0c;然后我们基于h&#xff0c;左右拓展&#xff0c;尽量拓展到h越来越高&#xff08;符合单调栈&#xff09;&a…

手机改IP地址怎么弄?全面解析与操作指南

在当今数字化时代&#xff0c;IP地址作为设备在网络中的唯一标识&#xff0c;其重要性不言而喻。有时候&#xff0c;出于隐私保护、网络访问需求或其他特定原因&#xff0c;我们可能需要更改手机的IP地址。然而&#xff0c;对于大多数普通用户来说&#xff0c;如何操作可能还是…

Redis 篇-深入了解 Redis 中的 RESP 通信协议与内存回收(过期 key 处理、内存淘汰策略)

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 Redis 通信协议 - RESP 协议 2.0 Redis 内存回收 2.1 Redis 内存回收 - 过期 key 处理 2.1.1 Redis 是如何知道一个 Key 是否过期呢&#xff1f; 2.1.2 是不是 TT…

Linux基础(三):安装CentOS7(系统安装+桥接联网+换源)

1.分区设置 由于使用 GPT 的关系&#xff0c; 因此根本无须考虑主/延伸/逻辑分区的差异。CentOS 默认使用 LVM 的方式来管理你的文件系统。使用GPT进行分区&#xff1a; 开机管理程序&#xff08; boot loader&#xff09; 使用CentOS 7.x默认的grub2软件。 2.各种分区格式 …

DataLight(V1.4.5) 版本更新,新增 Ranger、Solr

DataLight&#xff08;V1.4.5&#xff09; 版本更新&#xff0c;新增 Ranger、Solr DataLight 迎来了重大的版本更新&#xff0c;现已发布 V1.4.5 版本。本次更新对平台进行了较多的功能拓展和优化&#xff0c;新增了对 Ranger 和 Solr 服务组件的支持&#xff0c;同时对多项已…

Oracle 配置恢复目录catalog

一.介绍 Oracle中使用RMAN备份的数据我们分为两类 RMAN知识库数据库的数据块 Oracle默认把 RMAN知识库 放在目标数据库的控制文件中&#xff0c;在以后进行恢复的时候 我们要先读知识库的信息然后才能恢复。 但这样就产生了一个问题&#xff0c;知识库放在了控制文件上&#xf…

【C++】set与map

目录 一、预备知识&#xff1a; 1、关联式容器&#xff1a; 2、键值对&#xff1a; 3、树形结构的关联式容器&#xff1a; 二、set&#xff1a; 1、set的介绍&#xff1a; 2、使用&#xff1a; 1、set的构造&#xff1a; 2、set的各种功能&#xff1a; 3、multiset 三…

AOP-代理实现

三种代理实现 1 JDK动态代理实现-基于接口代理 2 CGLIB动态代理实现-基于类代理 3 AspectJ 适配实现 为什么Proxy.newProxyInstance 会生成新的字节码&#xff1f; 创建代理类&#xff1a; Proxy.newProxyInstance 首先会检查缓存中是否有已存在的代理类字节码。 如果没有&…

计算机毕业设计 C语言学习辅导网站的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

14.安卓逆向-frida基础-编写hook脚本2

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a;图灵Python学院 本人写的内容纯属胡编乱造&#xff0c;全都是合成造假&#xff0c;仅仅只是为了娱乐&#xff0c;请不要盲目相信。 工…

16. C++ TinyWebServer项目总结(16. 服务器调制、调试和测试)

主要包括&#xff1a; 使用 tcpdump 抓包&#xff1b;使用 gdb 调试器&#xff1b;使用压力测试工具&#xff0c;模拟现实世界中的高并发请求&#xff0c;测试服务器在高压状态下的稳定性。 最大文件描述符数 Linux 对应用进程能打开的最大文件描述符数量有两个层次的限制&a…

node的版本管理工具volta

安装方式 # mac curl https://get.volta.sh | bash # Windows Installation winget install Volta.Volta切换版本 volta install node指定版本根据项目固定node和包管理器版本和 该命令会在package.json生成volta的配置&#xff0c;volta会自动读取项目的该配置来决定node的…

【STM32】TCP/IP通信协议--LWIP内存管理

五、LWIP内存管理 1.什么是内存管理&#xff1f; &#xff08;1&#xff09;内存管理&#xff0c;是指软件运行时对计算机内存资源的分配的使用的技术&#xff0c;其主要目的是如何高效、快速的分配&#xff0c;并且在适当的时候释放和回收内存资源&#xff08;就比如C语言当…