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

蓝桥杯嵌入式备赛教程(1、led,2、lcd,3、key)

一、工程模版创建流程


第一步 创建新项目

第二步 选择型号和管脚封装

 第三步 RCC使能   外部时钟,高速外部时钟

第四步晶振时钟配置 

由数据手册7.1可知外部晶振频率为24MHz  最后一项设置为80

按下回车他会自动配置时钟

 第五步,如果不勾选可能程序只会下载一次到时候不好找问题

第6步 名字和路径不能有中文

 第七步bsp为创建的程序存放的文件

八创建一个新组

注意程序只能写在USER CODE BEGIN include 和user code end include

9Debug设置 点击确定板载调试器 

 

 二、点亮一颗LED灯


原理图

PD2锁存器控制端口

第一步、打开PC8~15的接口配置为output模式

且选中管脚output设置为HIGHPD2低电平时候为开,防止别的引脚冲突 

点击生成即可

第二步 创建两个文件led.c和led.h

定义缩写  在main.h函数内typedef unsigned char  uchar

头文件位置要在BEGIN和END之间

 第三步、引用头文件配置,这步是点击魔术棒

 

案例程序----点亮led

main

/----------------------------------main.h-------------------------------/

/* USER CODE BEGIN Includes */
typedef unsigned char uchar;
typedef unsigned int  uint;/* USER CODE END Includes */

/----------------------------------main.h-------------------------------/

头文件

/* USER CODE BEGIN Includes */
#include "led.h"
/* USER CODE END Includes */

 主函数

LED_Disp(0x00);//LED初始化/* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */LED_Disp(0x02);HAL_Delay(500);LED_Disp(0x00);HAL_Delay(1000);				}/* USER CODE END 3 */

led

/-----------------------------------led.h---------------------------------/

#ifndef __LED_H__
#define __LED_H__#include "main.h"
void LED_Disp(uchar dsLED);#endif

/-----------------------------------led.c---------------------------------/


#include "led.h"void LED_Disp(uchar dsLED)
{HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPIO_PIN_SET);//先将所有引脚设为高电平由原理图设计HAL_GPIO_WritePin(GPIOC,dsLED << 8,GPIO_PIN_RESET);//推向高8位HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);//锁存器低电平触发HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);}

三、lcd相关配置及代码案例

LCD原理图

 参考和移植官方的案例程序

第一步、引脚配置

全部配置为output

配置完引脚后点击GENERATE CODE即可无需其他操作

第二步、将这两个头文件复制到

在给的案例路径下将lcd.c、fonts、lcd.h也复制到bsp路径下面

 第三步、添加头文件

官方案例程序 

使用这种格式的颜色背景方便机器阅卷 背景色要求

        

案例程序----lcd显示

添加lcd

/--------------------------------main.c----------------------------/

头文件

/* USER CODE BEGIN Includes */
#include "led.h"
#include "lcd.h"
#include "stdio.h"
/* USER CODE END Includes */

 主函数

sprintf函数打印到字符串中

(要注意字符串的长度要足够容纳打印的内容,否则会出现内存溢出),而printf函数打印输出到屏幕上。sprintf函数在我们完成其他数据类型转换成字符串类型的操作中应用广泛
3、sprintf函数的格式
int sprintf( char *buffer, const char *format [, argument,…] );       

/* Initialize all configured peripherals */MX_GPIO_Init();/* USER CODE BEGIN 2 */LED_Disp(0x00);//LED初始化LCD_Init();//LCD初始化LCD_Clear(Black);LCD_SetBackColor(Black);LCD_SetTextColor(White);/* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */LED_Disp(0x02);HAL_Delay(500);LED_Disp(0x00);HAL_Delay(1000);char text[30];uint i = 5;sprintf(text,"  CNBR:%d      ",i);LCD_DisplayStringLine(Line9, (uint8_t *)text);}/* USER CODE END 3 */

三、按键配置


按键原理图

第一步、引脚配置

引脚设置为input

第二步 模式设置上下拉模式选择上拉

第三步定时器配置 

随便选择一个定时器 

时钟选择外部时钟80Mhz---为了达到非阻塞式延时消抖

分屏系数和自动重装载值设置 

100HZ=10ms中断一次  从0开始0~79是80个数

 计算延时时间实例

 中断使能

点击生成代码即可

程序及环境配置

新建两个文件-另存interrupt.c,interrupt.h保存地址为该文件路径下的bsp中

 /----------------------------------------------interrupt.h------------------------------------/

interrupt


#ifndef __INTERRUPT_H__
#define __INTERRUPT_H__#include "main.h"
#include "stdbool.h"
struct keys
{uchar judge_sta;//按键判断bool key_sta;bool single_flag;//确认被按下他为1
};void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);#endif

 /----------------------------------------------interrupt.c------------------------------------/

在一个具有多个按键的嵌入式设备按键检测程序中,通过循环遍历 key 数组(改变 i 的值从 0 到数组元素个数减 1),就可以依次获取每个按键的 judge_sta 状态,判断是否满足某些条件来进一步确认按键是否有效按下或者是否进入了特定的操作判断阶段等。

  1. case 0 分支

    • 逻辑描述:当 key[i].judge_sta 的值为 0 时进入该分支。在这个分支里,有一个条件判断语句 if(key[i].key_sta == 0),也就是当 key[i].key_sta(表示按键当前基本状态,0 在这里可能意味着未按下或者非激活状态等)也为 0 时,会将 key[i].judge_sta 的值更新为 1。这可能意味着当按键初始处于某个默认的未激活且符合某种前置条件时(由 judge_sta 为 0 和 key_sta 为 0 共同界定),将其状态推进到下一个阶段或者设置为另一种待确认的中间状态(用 judge_sta 变为 1 来表示)。
    • 可能的应用场景示例:比如在一个设备启动后,按键初始都处于默认未操作状态,当检测到按键没有被按下(key_sta 为 0)且其整体判断状态处于初始的 0 阶段时,就将其推进到一个准备检测后续是否有按下动作的状态阶段,对应 judge_sta 更新为 1
  2. case 1 分支

    • 逻辑描述:当 key[i].judge_sta 等于 1 时执行此分支逻辑。这里的条件判断是 if(key[i].key_sta == 0),如果 key[i].key_sta 为 0(即按键此时处于未按下状态),会执行两个操作:一是将 key[i].judge_sta 重置回 0,可能表示此次针对该按键的操作周期结束或者恢复到初始的一种状态等待下次操作;二是将 key[i].single_flag 设置为 1,根据之前结构体定义中对 single_flag 的注释理解(确认被按下它为 1),这里虽然当前按键是未按下状态,但可能是在满足了之前从 judge_sta 为 1 阶段的一些检测逻辑后,确认了一次完整的按键操作过程(比如之前从初始状态进入到 1 阶段后,又检测到按键松开了,就认为这是一次完整操作),所以设置 single_flag 为 1 来标记这次操作已完成,可以供程序后续部分依据这个标志做相应处理。
    • 可能的应用场景示例:在一个游戏控制按键的处理中,当按下某个按键后 judge_sta 变为 1 表示正在检测按下动作,然后松开按键(key_sta 变为 0),此时就可以认为完成了一次有效的按键操作,将 judge_sta 回置到 0 等待下次操作,同时设置 single_flag 为 1 通知程序去执行比如游戏角色对应动作等相关功能代码。
  3. case 2 分支

    • 逻辑描述:当 key[i].judge_sta 的值为 2 进入该分支。这里的条件判断是 if(key[i].key_sta == 1),即如果此时按键处于按下状态(key_sta 为 1),会将 key[i].judge_sta 的值设置为 0。这或许意味着当按键处于该 2 所代表的状态阶段时,如果又检测到它被按下了,那就将其状态重置回初始或者某个默认状态(用 judge_sta 变为 0 表示),可能是出现了不符合预期的重复按下或者需要重新开始检测该按键的情况等原因。
    • 可能的应用场景示例:在一个具有按键组合功能的设备中,如果某个按键单独按下去后进入了 judge_sta 为 2 的特定组合检测状态,但随后又检测到它再次被按下不符合当前功能的按键操作逻辑,就将其状态复位到 0 以便重新正确地检测后续操作。
#include "interrupt.h"struct keys key[4] = {0,0,0};void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{if(htim->Instance==TIM3){key[0].key_sta  = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);key[1].key_sta  = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);key[2].key_sta  = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);key[3].key_sta  = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);for(int i = 0;i<4;i++){switch (key[i].judge_sta){		case 0:{if(key[i].key_sta == 0) key[i].judge_sta=1;}break;case 1:{if(key[i].key_sta ==0){key[i].judge_sta=0;key[i].single_flag=1;}}break;case 2:{if(key[i].key_sta==1){key[i].judge_sta=0;}}break;case 3:{				}break;}}}
}

/---------------------------main.c--------------------------------------------/

main 

* USER CODE BEGIN Includes */
#include "led.h"
#include "lcd.h"
#include "stdio.h"
#include "interrupt.h"/* USER CODE BEGIN PTD */
extern struct keys key[];
/* USER CODE END PTD */

/-----------------------------main.c------------------------------------------/

int main(void)
{
/* USER CODE BEGIN 2 */LED_Disp(0x00);//LED初始化LCD_Init();//LCD初始化LCD_Clear(Black);LCD_SetBackColor(Black);LCD_SetTextColor(White);HAL_TIM_Base_Start_IT(&htim3);  //定时器中断/* USER CODE END 2 */while (1){
char text[30];uint i = 5;sprintf(text,"  CNBR:%d      ",i);LCD_DisplayStringLine(Line9, (uint8_t *)text);//实现按键的功能//第一个按键if(key[0].single_flag==1){sprintf(text,"       key0down      ");LCD_DisplayStringLine(Line8,(uint8_t *)text);key[0].single_flag=0;}if(key[1].single_flag==1){sprintf(text,"       key1down      ");LCD_DisplayStringLine(Line8,(uint8_t *)text);key[1].single_flag=0;}}/* USER CODE END 3 */
}

相关文章:

蓝桥杯嵌入式备赛教程(1、led,2、lcd,3、key)

一、工程模版创建流程 第一步 创建新项目 第二步 选择型号和管脚封装 第三步 RCC使能 外部时钟&#xff0c;高速外部时钟 第四步晶振时钟配置 由数据手册7.1可知外部晶振频率为24MHz 最后一项设置为80 按下回车他会自动配置时钟 第五步&#xff0c;如果不勾选可能程序只会…...

取多个集合的交集

1.我们取多个集合的交集&#xff0c;先把各个集合放入list中 List < Set < String > > listnew ArrayList<>();HashSet<String> set1new HashSet<>();set1.add( "A" );set1.add("B" );set1.add("C" );HashSet<…...

如何实现电子发票XML文件的合规性存档?

随着国家税务改革的推进&#xff0c;企业对电子发票的管理和存档要求越来越高。尤其是《财政部 国家税务总局关于进一步深化增值税发票管理改革的通知》&#xff08;财会〔2023〕18号文&#xff09;的发布&#xff0c;明确规定了电子发票的存档要求。这为企业在财务管理中的电子…...

IOT、MES、WMS、MOM 和 EPMS 系统综合技术与业务文档

IOT、MES、WMS、MOM 和 EPMS 系统综合技术与业务文档 一、引言 在现代制造业和工业管理领域&#xff0c;IOT&#xff08;物联网&#xff09;、MES&#xff08;制造执行系统&#xff09;、WMS&#xff08;仓库管理系统&#xff09;、MOM&#xff08;制造运营管理系统&#xff…...

IntelliJ IDEA Docker集成

一、概述 Docker是一种用于在隔离和可复制环境中部署和运行可执行文件的工具。这可能很有用&#xff0c;例如&#xff0c;在与生产相同的环境中测试代码。 IntelliJ IDEA集成了Docker功能&#xff0c;并为创建Docker映像、运行Docker容器、管理Docker Compose应用程序、使用公…...

【react项目】从零搭建react项目[nodejs安装]

〇、模板git下载地址 下载即用的模板地址&#xff1a; http:https://e.coding.net/uijiio/init_app/react_init_app.git ssh:gite.coding.net:uijiio/init_app/react_init_app.git 目前更新至:登录与主页跳转&#xff0c;主页包含菜单和容器区 一、搭建基础空白React项目 1.准备…...

【专题】2024年悦己生活消费洞察报告汇总PDF洞察(附原数据表)

原文链接&#xff1a; https://tecdat.cn/?p38654 在当今时代背景下&#xff0c;社会发展日新月异&#xff0c;人们的生活方式与消费观念正经历深刻变革。MoonFox 月狐数据的《2024 年悦己生活消费洞察报告》聚焦于这一充满活力与变化的消费领域。随着就业、婚姻等社会压力的…...

Github——网页版上传文件夹

第一步&#xff1a;创建一个新的仓库或进入已存在的仓库页面 第二步&#xff1a;点进对应的文件夹下&#xff0c;然后 点击 “Upload files” 第三步&#xff1a;将文件夹拖拽到上传区域 打开资源管理器&#xff0c;将要上传的文件夹从计算机中拖拽到上传区域。 注意&#xf…...

LMDeploy 量化部署进阶实践

1 配置LMDeploy环境 1.1 InternStudio开发机创建与环境搭建 打开InternStudio平台&#xff0c;进入如下界面创建环境 在终端中&#xff0c;让我们输入以下指令&#xff0c;来创建一个名为lmdeploy的conda环境&#xff0c;python版本为3.10&#xff0c;创建成功后激活环境并安…...

MFC/C++学习系列之简单记录9——简单加法

MFC/C学习系列之简单记录9——简单加法 前言界面设计控件添加添加变量添加事件 后台代码总结 前言 基本的一些使用已经了解&#xff0c;那么就做个简单的加法来练手吧&#xff01; 界面设计 控件添加 在工具箱中选择Edit control和Static Text两个控件&#xff0c;分别设置为…...

二分查找题目:两球之间的磁力

文章目录 题目标题和出处难度题目描述要求示例数据范围 解法思路和算法代码复杂度分析 题目 标题和出处 标题&#xff1a;两球之间的磁力 出处&#xff1a;1552. 两球之间的磁力 难度 5 级 题目描述 要求 在代号为地球 C-137 的世界中&#xff0c;Rick 发现如果他将两个…...

OpenCV相机标定与3D重建(28)估计两个三维点集之间的最优平移变换函数estimateTranslation3D()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 计算两个3D点集之间的最优平移。 它计算 [ x y z ] [ X Y Z ] [ b 1 b 2 b 3 ] \begin{bmatrix} x\\ y\\ z\\ \end{bmatrix} \begin{bmatri…...

UE5仿漫威争锋灵蝶冲刺技能

这两天玩了一下漫威争锋Marvel Rivals&#xff0c;发现是UE5做的&#xff0c;对里面一些角色技能挺感兴趣的&#xff0c;想简单复刻一下技能功能&#xff0c;顺便复习一下学过的知识 首先把摄像机设置调整一下 CameraBoom里搜索lag 把摄像机延迟关掉 &#xff0c;这样摄像机就…...

CSS盒子模型(溢出隐藏,块级元素和行级元素的居中对齐,元素样式重置)

overflow&#xff1a;值 规定了内容溢出元素框时所发生的事情 visible&#xff1a;内容不会被修剪&#xff0c;会显示在元素框之外&#xff0c;默认值 overflow: visible; hidden&#xff1a;内容会被修剪&#xff0c;溢出内容不可见 overflow: hidden; scroll&#xff1a;内…...

语音增强的损失函数选择

一、最优尺度不变信噪比&#xff08;OSISNR&#xff09;损失函数 参考&#xff1a;论文解读 --Optimal scale-invariant signal-to-noise ratio and curriculum learning for monaural multi-spea   最优尺度不变信噪比&#xff08;OSI-SNR&#xff09;是一种用于评估信号质量…...

【python自动化六】UI自动化基础-selenium的使用

selenium是目前用得比较多的UI自动化测试框架&#xff0c;支持java&#xff0c;python等多种语言&#xff0c;目前我们就选用selenium来做UI自动化。 1.selenium安装 安装命令 pip install selenium2.selenium的简单使用 本文以chrome浏览器为例&#xff0c;配套selenium中c…...

【习题答案】让您的应用拥有领先的位置服务能力

判断题 1.在使用&#xff08;逆&#xff09;地理编码前&#xff0c;需要使用isGeocoderAvailable检查服务状态。 正确(True) 错误(False) 2.当同时配置定位场景和优先级策略时&#xff0c;会优先使用优先级策略。 正确(True) 错误(False) 单选题 1.获取精准定位需要申请哪个权…...

java中list和map区别

在Java中&#xff0c;List和Map是两种不同类型的集合接口&#xff0c;它们用于不同的场景并且具有不同的特性和用途。以下是List和Map的主要区别&#xff1a; 1. 数据结构 List&#xff1a;是一个有序的集合&#xff0c;允许重复元素。它实现了Collection接口&#xff0c;并且…...

java后端传时间戳给前端的三种方式

一. 后端传时间戳给前端的几种方式 使用System.currentTimeMillis() 这是最简单的方式&#xff0c;返回自1970年1月1日&#xff08;UTC&#xff09;以来的毫秒数&#xff0c;可以直接传递给前端。 long timestamp1 System.currentTimeMillis();使用java.time.Instant Java…...

【机器学习与数据挖掘实战】案例06:基于Apriori算法的餐饮企业菜品关联分析

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈机器学习与数据挖掘实战 ⌋ ⌋ ⌋ 机器学习是人工智能的一个分支,专注于让计算机系统通过数据学习和改进。它利用统计和计算方法,使模型能够从数据中自动提取特征并做出预测或决策。数据挖掘则是从大型数据集中发现模式、关联…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析

今天聊的内容&#xff0c;我认为是AI开发里面非常重要的内容。它在AI开发里无处不在&#xff0c;当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗"&#xff0c;或者让翻译模型 "将这段合同翻译成商务日语" 时&#xff0c;输入的这句话就是 Prompt。…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢

随着互联网技术的飞速发展&#xff0c;消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁&#xff0c;不仅优化了客户体验&#xff0c;还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用&#xff0c;并…...

Java多线程实现之Callable接口深度解析

Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

第25节 Node.js 断言测试

Node.js的assert模块主要用于编写程序的单元测试时使用&#xff0c;通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试&#xff0c;通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

【AI学习】三、AI算法中的向量

在人工智能&#xff08;AI&#xff09;算法中&#xff0c;向量&#xff08;Vector&#xff09;是一种将现实世界中的数据&#xff08;如图像、文本、音频等&#xff09;转化为计算机可处理的数值型特征表示的工具。它是连接人类认知&#xff08;如语义、视觉特征&#xff09;与…...

Ascend NPU上适配Step-Audio模型

1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统&#xff0c;支持多语言对话&#xff08;如 中文&#xff0c;英文&#xff0c;日语&#xff09;&#xff0c;语音情感&#xff08;如 开心&#xff0c;悲伤&#xff09;&#x…...

AspectJ 在 Android 中的完整使用指南

一、环境配置&#xff08;Gradle 7.0 适配&#xff09; 1. 项目级 build.gradle // 注意&#xff1a;沪江插件已停更&#xff0c;推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...

前端中slice和splic的区别

1. slice slice 用于从数组中提取一部分元素&#xff0c;返回一个新的数组。 特点&#xff1a; 不修改原数组&#xff1a;slice 不会改变原数组&#xff0c;而是返回一个新的数组。提取数组的部分&#xff1a;slice 会根据指定的开始索引和结束索引提取数组的一部分。不包含…...

nnUNet V2修改网络——暴力替换网络为UNet++

更换前,要用nnUNet V2跑通所用数据集,证明nnUNet V2、数据集、运行环境等没有问题 阅读nnU-Net V2 的 U-Net结构,初步了解要修改的网络,知己知彼,修改起来才能游刃有余。 U-Net存在两个局限,一是网络的最佳深度因应用场景而异,这取决于任务的难度和可用于训练的标注数…...