蓝桥杯嵌入式国三备赛经验分享
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…...
【Go】3、Go语言进阶与依赖管理
前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes࿰…...

【Java_EE】Spring MVC
目录 Spring Web MVC 编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 编辑参数重命名 RequestParam 编辑编辑传递集合 RequestParam 传递JSON数据 编辑RequestBody …...

让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比
在机器学习的回归分析中,损失函数的选择对模型性能具有决定性影响。均方误差(MSE)作为经典的损失函数,在处理干净数据时表现优异,但在面对包含异常值的噪声数据时,其对大误差的二次惩罚机制往往导致模型参数…...

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...

STM32HAL库USART源代码解析及应用
STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...

脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)
一、OpenBCI_GUI 项目概述 (一)项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台,其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言,首次接触 OpenBCI 设备时,往…...

AI语音助手的Python实现
引言 语音助手(如小爱同学、Siri)通过语音识别、自然语言处理(NLP)和语音合成技术,为用户提供直观、高效的交互体验。随着人工智能的普及,Python开发者可以利用开源库和AI模型,快速构建自定义语音助手。本文由浅入深,详细介绍如何使用Python开发AI语音助手,涵盖基础功…...

数据结构:递归的种类(Types of Recursion)
目录 尾递归(Tail Recursion) 什么是 Loop(循环)? 复杂度分析 头递归(Head Recursion) 树形递归(Tree Recursion) 线性递归(Linear Recursion)…...

RKNN开发环境搭建2-RKNN Model Zoo 环境搭建
目录 1.简介2.环境搭建2.1 启动 docker 环境2.2 安装依赖工具2.3 下载 RKNN Model Zoo2.4 RKNN模型转化2.5编译C++1.简介 RKNN Model Zoo基于 RKNPU SDK 工具链开发, 提供了目前主流算法的部署例程. 例程包含导出RKNN模型, 使用 Python API, CAPI 推理 RKNN 模型的流程. 本…...

免费批量Markdown转Word工具
免费批量Markdown转Word工具 一款简单易用的批量Markdown文档转换工具,支持将多个Markdown文件一键转换为Word文档。完全免费,无需安装,解压即用! 官方网站 访问官方展示页面了解更多信息:http://mutou888.com/pro…...