蓝桥杯嵌入式国三备赛经验分享

1 学习STM32入门视频
向大家推荐一套宝藏级别的视频:
【STM32入门教程-2023版 细致讲解 中文字幕】
如果已经比过蓝桥杯单片机或学习过单片机相关课程的同学,你们可以尝试不需要STM32套件进行学习。如果没有学过单片机相关课程的同学,可以买套件边用边学。
尽量把这套视频看完,无论是对参加蓝桥杯嵌入式设计与开发竞赛(蓝桥杯)、嵌入式芯片与系统设计大赛STM32赛道(嵌入式大赛)或全国大学生物联网设计竞赛(华为杯)都有好处!
2 学习嵌入式开发板备赛视频
我主要看的是这套嵌入式视频:
【【备战2024蓝桥杯 嵌入式组】CT117E-M4 新款开发板 3小时省赛模块 速成总结】
从视频中可以学习到一些好的代码编写方式,从而避免各个外设的冲突、提高硬件运行效率。
3 备赛笔记
GPIO_Mode_AIN = 0x0, //模拟输入
GPIO_Mode_IN_FLOATING = 0x04, //浮空输入
GPIO_Mode_IPD = 0x28, //下拉输入
GPIO_Mode_IPU = 0x48, //上拉输入
GPIO_Mode_Out_OD = 0x14, //开漏输出
GPIO_Mode_Out_PP = 0x10, //推挽输出
GPIO_Mode_AF_OD = 0x1C, //复用开漏
GPIO_Mode_AF_PP = 0x18 //复用推挽
GPIO_SetBits //设置成高电平
GPIO_ResetBits //设置成低电平
HAL_GPIO_Write();//写GPIO电平状态函数

Key_State 里面的Key一定要初始化Key = 0;
长按键需要给25延时(Key_Time1)+长按键启用标志位
双击按键需要给40延时(Key_Time2)+双击按键启用标志位+暂时双击按键号

通用定时器可以产生4路频率相同,占空比不同的PWM输出
高级定时器可以产生7路频率相同,占空比不同的PWM输出


![]()
%d数据后面加空格 防止数据末位不清除
__HAL_TIM__SETCOMPARE(定时器,通道x, 占空比);
AT24C02 写一条语句延时5ms
MCP4017的从机地址(写操作):0X5E
随着我们向MCP中输入的数越大,他对应的电阻也就越大,当我们传入0x7f时,对应的电阻就是100K。这里要注意的一点是,我们写进去的一个数字(0-127),读出来也是一个数字,转化为电阻阻值:R = 787.4 * read_resistor 欧,电压:3.3*(R/(R+10)) (假设外接的电压为3.3)
新建工程
开启时钟(选择外部时钟) -> 配置时钟树 -> 配置DAP下载模式 -> 工程名 -> 配置MDK文件 -> 勾上生成code选项 -> 生成文件 -> 打开Keil -> 配置DAP下载 -> 勾上清除并更新 -> 建立bsp文件夹
LED
在CubeMX选择PC8-PC15、PD2为推挽输出模式 -> 配置PC8-PC15为高电平,PD2为低电平 -> 更新文件
->
void LED_Display(uchar data)
{HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);HAL_GPIO_WritePin(GPIOC, GPIO_PIN_All, GPIO_PIN_SET);HAL_GPIO_WritePin(GPIOC, (~data)<<8, GPIO_PIN_RESET);HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
}
(在main.c文件写代码时,写在Bagin和End注释之间)
LCD
复制资源包里LCD例程中2.h文件、1.c文件 -> 打开main.c,复制以下代码
LCD_Init();LCD_Clear(Black);LCD_SetBackColor(Black);LCD_SetTextColor(White);LCD_DisplayStringLine(Line9, (unsigned char *)str);
-> 创建char str[30];、引用”stdio.h”使用sprintf函数
Key(短按键)
在CubeMX打开TI63时钟配置外部时钟源 -> 配置PSC、ARR -> 使能中断 -> 更新文件
->
uint8_t Key_State(void){uchar Key = 0;if(!HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0))Key = 1;if(!HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1))Key = 2;if(!HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2))Key = 3;if(!HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0))Key = 4;return Key;}void Key_Loop(void){static uint8_t LastState, NowState;uint8_t i;LastState = NowState;NowState = Key_State();for(i = 1;i <= 4;i ++){if(LastState == 0 && NowState == i)KeyNum = i;}}
->
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)//中断回调函数(中断服务函数){static uint8_t Count0;if(htim -> Instance == TIM6){if(++Count0 >= 20){Count0 = 0;KeyStart = 1;}}}
->
HAL_TIM_Base_Start_IT(&htim6);//使能定时器中断
Key(长按键)
uint8_t Key_Short, Key_Long, Key_Time, Long_State = 1;void Key_Loop(void)
{static uint8_t LastState, NowState;uint8_t i;LastState = NowState;NowState = Key_State();for(i = 1;i <= 4;i ++){if(LastState == 0 && NowState == i)Key_Time = 0;if(LastState == i && NowState == i){if(++Key_Time >= 25 && Long_State){Key_Long = i;Long_State = 0;}}if(LastState == i && NowState == 0){if(Key_Time < 25)Key_Short = i;Long_State = 1;}}
}
PWM
在CubeMX打开相应定时器选择PWM生成选项 -> 配置时钟PSC:待定频率,ARR:100-1、CCR:占空比初值 -> 更新文件
->
HAL_TIM_PWM_Start(&htim16, TIM_CHANNEL_1);//使能PWM某通道输出
->
__HAL_TIM_SetCompare(&htim16, TIM_CHANNEL_1, PA6_PWM);//改变占空比
IC(测频率+占空比):
在CubeMX打开相应定时器 - > 配置Clock Source -> 选择CH1为直接通道、CH2为间接通道 -> 配置时钟PSC:80-1、ARR满重装值 -> CH1为上升沿触发、CH2为下降沿触发 -> 配置从模式(Combined Reset Trigger Mode) -> 选择触发源(TI1FP1)-> 更新文件 -> 创建IC.c、IC.h文件 -> 引入tim.h头文件 ->
uint32_t Read_Fre(uint8_t Command)
{if(Command == 15) return 1000000 / (HAL_TIM_ReadCapturedValue(&htim2, TIM_CHANNEL_1) + 1);else if(Command == 4) return 1000000 / (HAL_TIM_ReadCapturedValue(&htim3, TIM_CHANNEL_1) + 1);else return 0;
}double Read_Buty(uint8_t Command)
{if(Command == 15) return (HAL_TIM_ReadCapturedValue(&htim2, TIM_CHANNEL_2) + 1) * 100.0 / (HAL_TIM_ReadCapturedValue(&htim2, TIM_CHANNEL_1) + 1);else if(Command == 4) return (HAL_TIM_ReadCapturedValue(&htim3, TIM_CHANNEL_2) + 1) * 100.0 / (HAL_TIM_ReadCapturedValue(&htim3, TIM_CHANNEL_1) + 1);else return 0;
}
->
HAL_TIM_IC_Start(&htim2, TIM_CHANNEL_1);
HAL_TIM_IC_Start(&htim3, TIM_CHANNEL_1);//使能通道1
HAL_TIM_IC_Start(&htim2, TIM_CHANNEL_2);
HAL_TIM_IC_Start(&htim3, TIM_CHANNEL_2);//使能通道2
IC(中断测频率)
在CubeMX打开相应定时器TIMx的时钟 -> 选择相应通道CHx -> 配置时钟PSC:80-1、ARR满重装值-> 使能中断 -> 更新文件 -> 创建IC.c、IC.h文件 ->
uint32_t TIM2_IC_CRR1;void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{if(htim -> Instance == TIM2){TIM2_IC_CRR1 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);__HAL_TIM_SetCounter(htim, 0);}
}uint32_t Read_Fre(void)
{return 1000000 / (TIM2_IC_CRR1 + 1);
}
->
HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1);//使能输入捕获中断
ADC + DMA
在CubeMX打开相应引脚ADC通道 -> 配置ADC1、ADC2中相应通道使能(Single-ended) -> 使能连续转换 -> 添加DAM -> 配置循环模式Circular -> 使能DMA请求为连续模式 -> 失能DMA中断 -> 更新文件 ->
HAL_ADC_Start_DMA(&hadc1,(uint32_t *)adc1,1);
HAL_ADC_Start_DMA(&hadc2,(uint32_t *)adc2,1); //使能DAM转运
IIC
在CubeMX设置PB6、PB7引脚为输出模式 ->
void Write_AT24C02(uint8_t Command, uint8_t Data)
{I2CStart();I2CSendByte(0xa0);I2CWaitAck();I2CSendByte(Command);I2CWaitAck();I2CSendByte(Data);I2CWaitAck();I2CStop();
}uint8_t Read_AT24C02(uint8_t Command)
{uint8_t Data;I2CStart();I2CSendByte(0xa0);I2CWaitAck();I2CSendByte(Command);I2CWaitAck();I2CStart();I2CSendByte(0xa0 | 0x01);I2CWaitAck();Data = I2CReceiveByte();I2CSendNotAck();//不需要继续读就给非应答I2CStop();return Data;
}uint8_t Read_AT24C02(uint8_t Command)
{uint8_t Data;I2CStart();I2CSendByte(0xa0);I2CWaitAck();I2CSendByte(Command);I2CWaitAck();I2CStart();I2CSendByte(0xa0 | 0x01);I2CWaitAck();Data = I2CReceiveByte();I2CSendNotAck();//不需要继续读就给非应答I2CStop();return Data;
}
USART1
在CubeMX配置USART1模式为Asynchronous -> 配置波特率 -> 使能中断 -> 配置PA9、PA10为USART1 -> 更新文件 -> 创建MyUSART.c、.h文件 -> 引用usart.h->
uint8_t Rxdata,Receive_Over, pRxPacket;
char RxPacket[30];void Send_USART(char *data)
{HAL_UART_Transmit(&huart1, (uint8_t *)data, strlen(data), 50);
}void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{if(huart -> Instance == USART1){HAL_UART_Receive_IT(huart, &Rxdata, 1);RxPacket[pRxPacket ++] = RXdata;}
}void Receive_USART(void)
{static uint8_t p;if(pRxPacket != 0){p = pRxPacket;HAL_Delay(1);if(p == pRxPacket){Receive_Over =1;
Send_USART(RxPacket);pRxPacket = 0;
memset(RxPacket, 0, 30);}}
}
->
HAL_UART_Receive_IT(&huart1, &Rxdata, 1);//使能接收中断
4 备赛过程
嵌入式省赛备赛过程与单片机备赛过程类似,这里不再赘述,详情可以查看博主的另一篇博客:
【蓝桥杯单片机大一零基础到国二经验分享】

奇数届嵌入式国赛备赛时,可以多学习一些串口方面的c语言函数,比如第十五届嵌入式串口相关的收发数据及提取数据就比较多。
偶数届嵌入式国赛备赛时,需要学习扩展板相关外设的使用。
5 资料

如需十五届嵌入式资料可以私信我,本人很乐意开源,欢迎大家在评论区交流学习,预祝大家在蓝桥杯嵌入式设计与开发竞赛中取得优异成绩!!!
相关文章:
蓝桥杯嵌入式国三备赛经验分享
1 学习STM32入门视频 向大家推荐一套宝藏级别的视频:【STM32入门教程-2023版 细致讲解 中文字幕】 如果已经比过蓝桥杯单片机或学习过单片机相关课程的同学,你们可以尝试不需要STM32套件进行学习。如果没有学过单片机相关课程的同学,可以买…...
AI编程工具合集
1. 简介 1.1. 概述 AI编程,即人工智能编程,是编写用于创建智能系统(如机器学习模型、自然语言处理应用程序等)的代码的过程。AI编程涉及使用算法和数据结构来实现能够执行任务的程序,这些任务通常需要人类智能才能完成。 AI编程的基础是计算机科学原理,包括数据结构、…...
[网络编程]通过java用TCP实现网络编程
文章目录 一. 通过java用TCP实现网络编程api介绍代码实现上述代码存在的问题 一. 通过java用TCP实现网络编程 api介绍 1. ServerSocket ServerSocket是专门给服务器用的api 构造方法: 方法: 2. Socket 不管是客⼾端还是服务端Socket,都是双⽅建⽴连接以后&#…...
Python(TensorFlow)和Java及C++受激发射损耗导图
🎯要点 神经网络监督去噪预测算法聚焦荧光团和检测模拟平台伪影消除算法性能优化方法自动化多尺度囊泡动力学成像生物研究多维分析统计物距粒子概率算法 Python和MATLAB图像降噪算法 消除噪声的一种方法是将原始图像与表示低通滤波器或平滑操作的掩模进行卷积。…...
IEEE投稿模板翻译
>将这一行替换为您的稿件id号(双击此处编辑)< IEEE 期刊和会议论文的撰写准备(2022) 第一作者 A. 作者,IEEE成员,第二作者 B. 作者,第三作者 C. 作者 Jr.,IEEE成员 摘要—本文档为IEEE会刊、期刊和…...
log4j 1.x 日志输出线程以唯一ID的形式配置
在 Log4j 1.x 中,直接以线程ID(如Java中的Thread.currentThread().getId()返回的ID)的形式记录日志是可行的,但 Log4j 1.x 本身并不直接提供一个内建的、自动将每个线程ID转换为“同一时间段内唯一ID”的机制。线程ID本身在JVM的上…...
宏观学习笔记:GDP分析(二)
GDP分析(一)主要是介绍GDP相关的定义以及核算逻辑,本节主要介绍GDP的分析思路。GDP分析主要是2种方法:总量分析和结构分析。 1. 总量分析 1.1 数值选择 一般情况下,分析的对象都是 官方公布的GDP当季值。 1.2 趋势规…...
两个月冲刺软考——访问位与修改位的题型(淘汰哪一页);内聚的类型;关于码制的知识点;地址映射的相关内容
1.访问位与修改位的题型(淘汰哪一页) 访问位:为1时表示在内存期间被访问过,为0时表示未被访问;修改位:为1时表示该页面自从被装入内存后被修改过,为0时表示未修改过。 置换页面时,最先置换访问位和修改位为…...
C高级编程 第十六天(树 二叉树)
1.树 1.1结构特点 非线性结构,有一个直接前驱,但可能有多个直接后继有递归性,树中还有树可以为空,即节点个数为零 1.2相关术语 根:即根结点,没有前驱叶子:即终端结点,没有后继森…...
OpenCV结构分析与形状描述符(11)椭圆拟合函数fitEllipse()的使用
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 围绕一组2D点拟合一个椭圆。 该函数计算出一个椭圆,该椭圆在最小二乘意义上最好地拟合一组2D点。它返回一个内切椭圆的旋转矩形。使…...
904.水果成篮
题目 链接:leetcode链接 思路分析(滑动窗口) 读完题目,很明显,这个题目需要我们寻找一个最长子数组,使得这个子数组里面最多存在两种不同的数字,很容易联想到使用滑动窗口。 另外ÿ…...
【网络安全】漏洞挖掘之 2FA 恢复代码安全措施不当
未经许可,不得转载。 文章目录 正文正文 目标:example.com 2024年6月,我在HackerOne上参与一个私人项目时发现了一个与2FA(双因素身份验证)恢复代码管理相关的安全漏洞。该漏洞发生在用户禁用并重新启用2FA的过程中。问题在于,系统在2FA重新启用后,仍然接受此前生成的…...
指令微调与参数微调的代码实践与分析
文章目录 指令微调的实验性分析LoRA 代码实践与分析指令微调的示例代码与预训练的代码高度一致,区别主要在于指令微调数据集的构建(SFTDataset)和序列到序列损失的计算(DataCollatorForSupervisedDataset)。以下代码展示了 LLMBox 和 YuLan-Chat 中指令微调的整体训练流程…...
Android14音频进阶之高通Elite架构指定通道播放(八十四)
简介: CSDN博客专家、《Android系统多媒体进阶实战》一书作者 新书发布:《Android系统多媒体进阶实战》🚀 优质专栏: Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏: 多媒体系统工程师系列【原创干货持续更新中……】🚀 优质视频课程:AAOS车载系统+…...
常见的正则化方法以及L1,L2正则化的简单描述
深度学习中的正则化是通过在模型训练过程中引入某些技术来防止模型过拟合的一种策略。过拟合是指模型在训练数据上表现非常好,但在新的、未见过的数据上表现不佳。正则化通过限制模型的复杂度或对模型参数施加约束,从而提高模型的泛化能力。 常见的正则…...
深入理解 Milvus:新一代向量数据库的基础技术与实战指南
一、什么是 Milvus? Milvus 是一个开源的向量数据库,专门设计用于存储和检索大规模的高维向量数据。无论是图像、视频、音频还是文本,通过将这些数据转换为向量,Milvus 都能通过近似最近邻搜索(Approximate Nearest N…...
Maven教程——从入门到入坑
第1章 为什么要使用Maven 1.1 获取第三方jar包 开发中需要使用到的jar包种类繁多,获取jar包的方式都不尽相同。为了查找一个jar包找遍互联网,身心俱疲。不仅如此,费劲心血找到的jar包里有的时候并没有你需要的那个类,又或者有…...
研究生深度学习入门的十天学习计划------第九天
第9天:深度学习中的迁移学习与模型微调 目标: 理解迁移学习的核心概念,学习如何在实际应用中对预训练模型进行迁移和微调,以应对不同领域的任务。 9.1 什么是迁移学习? 迁移学习(Transfer Learning&#…...
perl的学习记录——仿真regression
1 记录的背景 之前只知道有这个强大语言的存在,但一直侥幸自己应该不会用到它,所以一直没有开始学习。然而人生这么长,怎就确定自己不会用到呢? 这次要搭建一个可以自动跑完所有case并且打印每个case的pass信息到指定的文件中。…...
【Go】go连接clickhouse使用TCP协议
离开你是傻是对是错 是看破是软弱 这结果是爱是恨或者是什么 如果是种解脱 怎么会还有眷恋在我心窝 那么爱你为什么 🎵 黄品源/莫文蔚《那么爱你为什么》 package mainimport ("context""fmt""log""time&q…...
Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...
学校招生小程序源码介绍
基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码,专为学校招生场景量身打造,功能实用且操作便捷。 从技术架构来看,ThinkPHP提供稳定可靠的后台服务,FastAdmin加速开发流程,UniApp则保障小程序在多端有良好的兼…...
C# SqlSugar:依赖注入与仓储模式实践
C# SqlSugar:依赖注入与仓储模式实践 在 C# 的应用开发中,数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护,许多开发者会选择成熟的 ORM(对象关系映射)框架,SqlSugar 就是其中备受…...
JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...
用docker来安装部署freeswitch记录
今天刚才测试一个callcenter的项目,所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...
如何在最短时间内提升打ctf(web)的水平?
刚刚刷完2遍 bugku 的 web 题,前来答题。 每个人对刷题理解是不同,有的人是看了writeup就等于刷了,有的人是收藏了writeup就等于刷了,有的人是跟着writeup做了一遍就等于刷了,还有的人是独立思考做了一遍就等于刷了。…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
10-Oracle 23 ai Vector Search 概述和参数
一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...
智能AI电话机器人系统的识别能力现状与发展水平
一、引言 随着人工智能技术的飞速发展,AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术,在客户服务、营销推广、信息查询等领域发挥着越来越重要…...
JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...
