彩钢做网站能赚钱吗,大数据精准营销获客系统,wordpress设置导航栏,wordpress数据库端口蓝桥杯嵌入式专栏正在加班加点更新#xff0c;帮助你备考#xff0c;可以关注作者或者专栏祝大家在蓝桥杯比赛中能取得好的成绩第十四届蓝桥杯嵌入式省赛 题目全解析这是蓝桥杯嵌入式省赛的标准综合题型#xff0c;总分85分#xff0c;无复杂算法#xff0c;核心考察STM32…蓝桥杯嵌入式专栏正在加班加点更新帮助你备考可以关注作者或者专栏祝大家在蓝桥杯比赛中能取得好的成绩第十四届蓝桥杯嵌入式省赛 题目全解析这是蓝桥杯嵌入式省赛的标准综合题型总分85分无复杂算法核心考察STM32基础外设的熟练度、逻辑严谨性和细节把控能力分层得分点明确细节决定最终得分。一、题目整体定位与核心考点总览1. 系统核心定位实现一个带参数配置的PWM信号发生器频率测速数据统计的嵌入式系统围绕「输入输出、人机交互、数据统计」三大核心展开所有功能均基于STM32基础外设实现难度中等适合嵌入式入门级综合考核。2. 核心考点全覆盖模块类型核心考点分值占比外设驱动TIM(PWM输出/输入捕获)、ADC单通道采集、GPIO(按键/LED)、LCD多界面显示~45%逻辑实现按键消抖/长短按识别、多界面状态管理、PWM频率平滑过渡、带时间阈值的峰值统计、状态机设计~30%规范细节初始状态合规性、显示格式匹配、边界值处理、防误触逻辑、命名规范~10%3. 硬件资源分配必对应根据题目系统框图和功能要求硬件资源固定分配如下功能对应引脚核心外设PWM信号输出PA1定时器PWM模式如TIM2_CH1频率测量输入捕获PA7定时器输入捕获模式如TIM3_CH2避免与PWM定时器冲突模拟电压采集R37电位器ADC单通道如ADC2_INx按键输入B1/B2/B3/B4GPIO上拉输入LED指示LD1-LD8GPIO推挽输出显示交互板载LCDLCD驱动库二、分模块详细拆解要求实现要点避坑1. PWM输出模块3.3节基础核心分必拿题目核心要求双模式固定频率低频4KHz、高频8KHz占空比调节规则输入电压1V → 占空比固定10%1V≤电压≤3V → 占空比从10%线性增长到85%电压3V → 占空比固定85%模式切换要求占空比保持不变频率在5秒内均匀过渡到目标值步进值200Hz输出引脚PA1。实现要点定时器配置选择通用定时器如TIM2配置为PWM输出模式预分频PSC固定通过修改ARR实现频率调整保证占空比不变平滑过渡实现用100ms周期的定时器中断每次调整频率步进80Hz4K→8K差值4000Hz5秒50次中断4000/5080Hz符合步进200Hz要求分段函数处理ADC采集电压后严格按照三段式规则计算占空比边界值必须锁死。高频坑点模式切换时必须保持占空比不变不能重置占空比频率必须均匀渐变禁止直接跳变否则直接扣分占空比边界必须严格锁死1V10%3V85%不能超范围。2. 频率测量与速度转换模块3.4节计算核心题目核心要求测量PA7引脚输入的信号频率f速度转换公式v (f · 2πR) / (100K)其中π固定取3.14禁止用math库的M_PIR、K为可调整参数范围1-10的整数速度显示保留1位小数。实现要点测频方案采用测周期法蓝桥杯最常用适配中低频信号通过定时器输入捕获模式测量信号周期再通过f1000000/周期(us)计算频率精度处理所有计算用float浮点类型避免整数除法丢失小数精度中断处理输入捕获中断中仅完成捕获值读取频率计算放在主循环避免中断耗时过长。高频坑点定时器通道冲突禁止用PWM输出的同一个定时器/通道做输入捕获必须用独立定时器如PWM用TIM2捕获用TIM3否则功能完全失效π必须固定取3.14用其他值会导致精度不符扣分必须处理捕获溢出避免频率计算错误。3. LCD多界面显示模块3.5节占分最高细节决定成败题目核心要求共3个固定界面严格要求显示内容、大小写、行列位置、格式黑底白字数据项用间隔。数据界面DATA界面名称DATA、输出模式MH高频L低频、实时占空比Pxx%、实时速度Vxx.x参数界面PARA界面名称PARA、参数Rxx、Kxx记录界面RECD界面名称RECD、模式切换次数Nxx、高频最大速度MHxx.x、低频最大速度MLxx.x通用要求模式切换未完成时M的显示保持不变切换完成后再更新。实现要点界面切换用lcd_select状态变量0DATA1PARA2RECD管理主循环中根据状态调用对应显示函数格式化输出用sprintf格式化字符串严格匹配格式整数%d小数保留1位%.1f界面名称必须全大写与题目完全一致刷新优化主循环中固定频率刷新如100ms一次避免频繁刷新导致屏幕闪烁。高频坑点界面名称、变量名的大小写必须和题目完全一致如DATA不能写成Data写错直接扣分小数位数必须严格符合要求多一位少一位均扣分模式切换过程中M的显示不能变化必须等切换完成后再更新界面切换时必须覆盖显示避免字符叠加。4. 按键功能模块3.6节最易出bug题目核心要求4个独立按键分场景实现不同功能要求消抖、长短按分离、防误触、无效按键屏蔽。按键功能场景核心要求B1全场景循环切换界面数据→参数→记录→数据下降沿触发B2数据界面切换高低频模式按下后5秒内禁止再次触发B2参数界面切换选中参数R/K进入界面默认选中R退出后参数生效B3参数界面选中参数11-10循环边界不溢出B4参数界面选中参数-11-10循环边界不溢出B4数据界面长按≥2秒锁定占空比电位器失效短按解锁通用要求全场景软件消抖、长短按互不影响、当前界面无效按键不触发实现要点按键消抖20ms软件消抖采用下降沿触发当前状态0上一次状态1避免长按重复触发长按识别用100ms定时器中断累加计时按下时开始计时松开时判断时长区分长短按功能隔离用lcd_select判断当前界面仅执行对应界面的按键功能屏蔽无效按键按键锁B2按下后用标志位锁定5秒计时完成后解锁禁止重复触发。高频坑点必须是下降沿触发禁止电平持续触发否则会出现按一次多次执行的问题B2的5秒锁必须严格执行哪怕模式切换提前完成5秒内也不能再次触发长按和短按必须完全分离长按松开后不能触发短按功能参数必须在退出参数界面后才生效不能在调整时实时生效。5. 统计功能模块3.7节易丢分细节题目核心要求N高低频模式切换次数完成一次完整切换后计数1MH高频模式下的最大速度值稳定保持不足2秒的速度不纳入统计ML低频模式下的最大速度值稳定保持不足2秒的速度不纳入统计。实现要点状态机设计用WAITING/MONITORING两状态机实现峰值检测WAITING等待有效峰值当速度大于当前最大值时进入MONITORING记录候选值和起始时间MONITORING持续监测出现更大值则重置计时数值大幅下降则重置状态稳定满2秒则更新对应最大值模式隔离高频模式仅更新MH低频模式仅更新ML模式切换时重置状态机避免数据混淆切换计数仅当模式切换完成频率到达目标值后N才1不能按下按键就计数。高频坑点必须稳定满2秒的速度才纳入统计瞬时峰值、波动值禁止更新MH/ML必须严格对应高低频模式不能混在一起统计初始状态MH/ML/N必须为0不能有初始值。6. LED指示模块3.8节送分题绝对不能丢题目核心要求LD1处于数据界面点亮否则熄灭LD2模式切换期间以0.1秒为间隔闪烁切换完成后熄灭LD3占空比锁定状态点亮否则熄灭LD4-LD8始终熄灭。实现要点LD2闪烁用100ms定时器中断翻转电平切换完成后强制拉灭状态联动LED状态完全跟随系统状态主循环中统一刷新避免分散控制导致的状态异常。高频坑点LD2闪烁间隔必须严格0.1秒不能过快过慢LD4-LD8必须始终熄灭不能有任何点亮情况初始状态必须符合要求不能上电亮错灯。7. 初始状态要求4.节最易忽略的丢分点上电后必须严格满足以下状态否则直接扣分参数R1K1模式切换次数N0PWM输出为低频模式高低频最大速度MH/ML0处于解锁状态电位器可控制占空比处于数据显示界面。三、比赛开发顺序与得分优先级蓝桥杯比赛核心是「先拿稳分再冲细节」推荐开发顺序如下第一优先级基础分约40分必拿GPIO初始化LED点亮测试先实现LED的基础控制ADC采集实现R37电压采集通过LCD/串口验证采集正确性TIM PWM输出实现4KHz固定频率、占空比随电压调节验证PA1输出正常LCD驱动实现3个界面的基础显示先把界面名称、固定内容显示正确按键驱动实现B1的界面切换打通3个界面的切换逻辑。第二优先级核心分约30分PWM模式切换实现5秒频率平滑过渡、LD2闪烁功能输入捕获测频实现PA7频率测量、速度公式计算数据界面正常显示VB2/B3/B4全功能实现参数界面的R/K加减、数据界面的模式切换B4长按锁定功能LD3状态联动。第三优先级细节分约15分统计功能实现模式切换计数、MH/ML带2秒阈值的峰值统计全细节优化显示格式匹配、边界值处理、无效按键屏蔽、防误触逻辑初始状态全检查确保上电所有状态符合题目要求全功能联调覆盖所有场景测试修复隐藏bug。四、高频致命bug避坑指南定时器通道冲突PWM输出和输入捕获必须用不同的定时器禁止用同一个TIM的不同通道否则会出现功能互相覆盖、完全失效的问题按键边沿触发错误必须用「当前状态0上一次状态1」的下降沿判断禁止用电平直接判断否则会出现重复触发浮点精度丢失速度公式必须全浮点运算所有变量用float类型禁止用整数运算否则小数部分完全丢失速度值错误峰值统计逻辑错误必须先计时满2秒再更新最大值不能一出现峰值就更新否则不符合题目要求初始状态遗漏所有全局变量必须显式初始化不能依赖编译器默认值否则上电状态错误直接扣分占空比锁定逻辑错误锁定后必须冻结占空比禁止电位器继续修改解锁后才能恢复控制。1.CubeMx 配置2.代码模块3.key.c#include headfile.h uint8_t B1_state ; uint8_t B2_state ; uint8_t B3_state ; uint8_t B4_state ; uint8_t B1_last_state ; uint8_t B2_last_state ; uint8_t B3_last_state ; uint8_t B4_last_state ; uint8_t fre_flag; uint8_t RK_select; uint8_t B4_pressd; uint16_t B4_press_duration; /** * brief 按键扫描函数 * details 扫描四个按键的状态处理按键事件包括界面切换、参数调整、频率扫描控制等 */ void Key_Scan() { // 读取四个按键的当前状态0表示按下1表示释放 B1_state HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0); // 读取B1按键状态 B2_state HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1); // 读取B2按键状态 B3_state HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2); // 读取B3按键状态 B4_state HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0); // 读取B4按键状态 // B1按键按下时切换LCD显示界面 if(B1_state0 B1_last_state1) // 检测B1按键按下下降沿 { lcd_select; // 切换到下一个界面 lcd_select%3; // 界面循环0-20表示数据界面1表示参数界面2表示记录界面 if(lcd_select 1) // 如果切换到参数界面 { RK_select 0;//默认当前可编辑的参数为 R } } // B2按键多功能按键根据当前界面执行不同操作 if(B2_state0 B2_last_state1) // 检测B2按键按下 { if(lcd_select0) // 在数据界面时 { if(0flag_5s) // 如果频率递变未开始 { if(0fre_flag) // 频率增加准备阶段 { fre_flag1; // 启动频率上升阶段 flag_5s1; // 激活5秒计时 } if(2fre_flag) // 频率增加准备阶段结束 频率减少准备阶段 { fre_flag3; // 启动频率下降阶段 flag_5s1; // 激活5秒计时 } } } else if(lcd_select 1) // 在参数界面时 { RK_select ; // 切换可编辑参数R/K RK_select % 2; // 循环切换0-10表示R参数1表示K参数 } } // B3按键在参数界面时增加参数值 if(B3_state0 B3_last_state1) // 检测B3按键按下 { if(lcd_select 1) // 仅在参数界面有效 { if(RK_select 0) // 如果当前编辑的是R参数 { R_num; // R参数增加 if(R_num10)R_num1; // 超过10则循环到1 } else // 如果当前编辑的是K参数 { K_num; // 系数值增加 if(K_num10)K_num1; // 超过10则循环到1 } } } // B4按键多功能按键在参数界面减少参数值在数据界面控制占空比锁定 if(B4_state0 B4_last_state1) // 检测B4按键按下 { if(lcd_select 1) // 在参数界面时 { if(RK_select 0) // 如果当前编辑的是R参数 { R_num--; // R参数减少 if(R_num1)R_num10; // 小于1则循环到10 } else // 如果当前编辑的是K参数 { K_num--; // 系数值减少 if(K_num1)K_num10; // 小于1则循环到10 } } else if(lcd_select 0) // 在数据界面时 { B4_pressd 1;//标记B4状态为按下开始计时 B4_press_duration 0;//重置计时器为0 } } // B4按键释放处理 if(B4_state1 B4_last_state0)//检测B4按键释放 { if(B4_pressd) // 如果之前标记为按下状态 { if(B4_press_duration 20)//如果B4按下超过2秒20*100ms进入占空比锁定模式 { B4_pressd 0; // 清除按下标记 B4_press_duration 0; // 重置计时器 duty_flag 1; // 设置占空比锁定标志 } else // 按下时间不足2秒 { duty_flag 0;//0表示自动模式1表示锁定模式短按B4解锁 } } } // 保存当前按键状态用于下次检测边沿 B1_last_state B1_state; // 保存B1状态 B2_last_state B2_state; // 保存B2状态 B3_last_state B3_state; // 保存B3状态 B4_last_state B4_state; // 保存B4状态 }4.fun.c#include headfile.h float V_num;//速度值 float MH_num;//高频模式最大速度 float ML_num;//低频模式最大速度 double PWM_duty;//PWM占空比 uint8_t PWM_num;//PWM 输出模式切换次数 uint8_t duty_flag;//占空比锁定标志位 uint8_t R_v 1;//R缓存值 uint8_t K_v 1;//K缓存值 uint8_t R_num 1;//R展示值 uint8_t K_num 1;//K展示值 uint32_t start_tick;//2s峰值监测计时起始点 char text[20]; void Led_Show(uint8_t led, uint8_t mode) { HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET); if(modeON) { HAL_GPIO_WritePin(GPIOC,(GPIO_PIN_8)(led-1),GPIO_PIN_RESET); } if(modeOFF) { HAL_GPIO_WritePin(GPIOC,(GPIO_PIN_8)(led-1),GPIO_PIN_SET); } HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET); } double Get_Vol(void) { HAL_ADC_Start(hadc2); uint32_t adc_value HAL_ADC_GetValue(hadc2); return 3.3 * adc_value/4096.0; } /** * brief LCD显示和控制更新函数 * details 根据当前状态更新PWM占空比、计算速度值、检测峰值、控制LED指示灯 */ void Lcd_Change() { // 根据电压值调整PWM占空比仅在数据界面时生效 if(DATAduty_flag) { // 电压小于1V时设置最小占空比10% if(Get_Vol()1) { PWM_duty10; } // 电压在1V-3V之间时线性调整占空比 else if(Get_Vol()1 Get_Vol()3) { PWM_duty 37.5 * Get_Vol() - 27.5; // 线性关系y37.5x-27.5 } // 电压大于3V时设置最大占空比85% else if(Get_Vol()3) { PWM_duty85; } } // 更新TIM2通道2的捕获比较寄存器值实现PWM占空比调整 TIM2-CCR2 PWM_duty/100.0 * (TIM2-ARR1); // 当不在参数设置界面时保存当前参数值 if(lcd_select!PARA) { R_v R_num; // 保存R值 K_v K_num; // 保存K值 } // 计算速度值V (频率 * 2π * 半径) / (100 * 系数) V_num (freA * 2 *3.14*R_v)/(100 * K_v); // 峰值检测状态机根据M_flag判断是检测最大频率还是最小频率 if(M_flag) // 检测最大值 { switch(peak_state) { case WAITING: // 等待新峰值状态 if(V_num MH_num) // 发现新的潜在最大值 { candidate_max V_num; // 记录候选最大值 start_tick HAL_GetTick(); // 记录开始时间 peak_state MONITORING; // 切换到监控状态 } break; case MONITORING: // 持续检测新峰值状态 if(V_num candidate_max 0.5f) // 发现更大的值更新候选值 这里进行0.5的容差调整避免微小波动导致频繁更新 { candidate_max V_num; start_tick HAL_GetTick(); // 重置计时 } else if(V_num candidate_max - 0.5f) // 值下降过多放弃当前候选 这里进行0.5的容差调整避免微小波动导致频繁更新 { candidate_max 0; peak_state WAITING; // 返回等待状态 } else if(HAL_GetTick() - start_tick 2000) // 值稳定2秒以上 { MH_num candidate_max; // 确认新的最大值 candidate_max 0; peak_state WAITING; // 返回等待状态 } break; default: break; } } else // 检测最小值 { switch(peak_state) { case WAITING: // 发现潜在新峰值状态 if(V_num ML_num) // 发现新的潜在峰值 { candidate_max V_num; start_tick HAL_GetTick(); peak_state MONITORING; } break; case MONITORING: // 持续监控状态 if(V_num candidate_max 0.5f) // 发现更大的值更新候选值 { candidate_max V_num; start_tick HAL_GetTick(); // 重置计时 } else if(V_num candidate_max - 0.5f) // 值下降过多放弃当前候选 { candidate_max 0; peak_state WAITING; } else if(HAL_GetTick() - start_tick 2000) // Vcandidate_max持续2s未变化确认新峰值 { ML_num candidate_max; // 确认新的最小值 candidate_max 0; peak_state WAITING; } break; default: break; } } // LED指示灯控制 if(lcd_select DATA)Led_Show(1,1); // 数据界面时LED1亮起 else Led_Show(1,OFF); // 非数据界面时LED1熄灭 Led_Show(2, led_state); // LED2根据系统状态闪烁 if(duty_flag)Led_Show(3,ON); // 占空比锁定时LED3亮起 else Led_Show(3,OFF); // 占空比未锁定时LED3熄灭 } void Data_Show() { sprintf(text, DATA ); LCD_DisplayStringLine(Line1,(uint8_t*) text); if(M_flag) { sprintf(text, MH ); LCD_DisplayStringLine(Line3, (uint8_t *)text); } else { sprintf(text, ML ); LCD_DisplayStringLine(Line3, (uint8_t *)text); } sprintf(text, P%d%% ,(int)PWM_duty); LCD_DisplayStringLine(Line4,(uint8_t*) text); sprintf(text, V%.1f ,V_num); LCD_DisplayStringLine(Line5,(uint8_t*) text); } void Para_Show() { sprintf(text, PARA ); LCD_DisplayStringLine(Line1,(uint8_t*) text); sprintf(text, R%d ,R_num); LCD_DisplayStringLine(Line3,(uint8_t*) text); sprintf(text, K%d ,K_num); LCD_DisplayStringLine(Line4,(uint8_t*) text); sprintf(text, ); LCD_DisplayStringLine(Line5,(uint8_t*) text); } void Recd_Show() { sprintf(text, RECD ); LCD_DisplayStringLine(Line1,(uint8_t*) text); sprintf(text, N%d ,PWM_num); LCD_DisplayStringLine(Line3,(uint8_t*) text); sprintf(text, MH%.1f ,MH_num); LCD_DisplayStringLine(Line4,(uint8_t*) text); sprintf(text, ML%.1f ,ML_num); LCD_DisplayStringLine(Line5,(uint8_t*) text); } uint8_t lcd_select; void Lcd_Show() { switch(lcd_select) { case DATA: Data_Show(); break; case PARA: Para_Show(); break; case RECD: Recd_Show(); break; default: break; } }5.handler.c#include headfile.h uint8_t flag_5s; uint8_t key_5s; uint8_t M_flag; uint8_t led_state; uint16_t timer_5s; uint16_t fre4000 4000; uint32_t freA; uint32_t freA_meature; PeadState peak_state WAITING; float candidate_max; /** * brief 定时器输入捕获回调函数 * param htim 定时器句柄指针 * details 当定时器捕获到输入信号边沿时自动调用此函数用于测量信号频率 */ void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) { // 检查是否是TIM3触发的中断 if(htim-InstanceTIM3) { // 读取TIM3通道2的捕获值并加1得到完整的周期计数值 freA_meature HAL_TIM_ReadCapturedValue(htim3,TIM_CHANNEL_2) 1; // 计算频率频率 1,000,000 / 周期计数值 // 假设定时器时钟为1MHz所以用1,000,000除以周期计数值得到频率(Hz) freA 1000000/freA_meature; } } /** * brief 定时器周期中断回调函数 * param htim 定时器句柄指针 * details 每100ms执行一次处理频率扫描、按键计时等功能 */ void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)//100ms { // 检查是否是TIM6触发的中断 if(htim-InstanceTIM6) { if(1fre_flag) { timer_5s; // 5秒计时器递增每100ms加150次为5秒 led_state ! led_state; // LED状态翻转实现闪烁效果 fre400080; // 频率增加80Hz TIM2-ARR1000000/fre4000 - 1; // 更新TIM2自动重载值调整输出频率 // 5秒增加时间到达 if(timer_5s50) { fre_flag2; // 进入频率增加暂停状态 timer_5s0; // 重置计时器 PWM_num; // PWM模式计数器递增 M_flag1; // 设置为最大值检测模式 candidate_max 0; // 重置候选最大值 peak_state WAITING; // 重置峰值检测状态为等待 led_state 0; // 关闭LED闪烁 } } if(3fre_flag) { timer_5s; // 5秒计时器递增 fre4000-80; // 频率减少80Hz led_state ! led_state; // LED状态翻转实现闪烁效果 TIM2-ARR1000000/fre4000 - 1; // 更新TIM2自动重载值调整输出频率 // 5秒扫描时间到达 if(timer_5s50) { fre_flag0; // 停止频率扫描 timer_5s0; // 重置计时器 PWM_num; // PWM模式计数器递增 flag_5s0; // 清除5秒标志 led_state 0; // 关闭LED闪烁 } } } // 5秒标志处理用于按键长按检测 if(flag_5s)//5秒计时 { key_5s ; // 按键5秒计时器递增 if(key_5s 50) // 5秒时间到达 { key_5s 0; // 重置按键计时器 flag_5s 0; // 清除5秒标志 } } // B4按键按下持续时间计时 if(B4_pressd)//检测B4按下时间 { B4_press_duration ; // B4按键持续时间递增 } }6.lcd.c代码修改部分void LCD_Init(void) { uint16_t temp GPIOC-ODR; //此处修改 LCD_CtrlLinesConfig(); dummy LCD_ReadReg(0); if(dummy 0x8230) { REG_8230_Init(); } else { REG_932X_Init(); } dummy LCD_ReadReg(0); GPIOC-ODR temp; //此处修改 } void LCD_Clear(u16 Color) { uint16_t temp GPIOC-ODR; //此处修改 u32 index 0; LCD_SetCursor(0x00, 0x0000); LCD_WriteRAM_Prepare(); /* Prepare to write GRAM */ for(index 0; index 76800; index) { LCD_WriteRAM(Color); } GPIOC-ODR temp; //此处修改 } void LCD_DisplayStringLine(u8 Line, u8 *ptr) { uint16_t temp GPIOC-ODR; //此处修改 u32 i 0; u16 refcolumn 319;//319; while ((*ptr ! 0) (i 20)) // 20 { LCD_DisplayChar(Line, refcolumn, *ptr); refcolumn - 16; ptr; i; } GPIOC-ODR temp; //此处修改 }7.头文件headfile.h key.h fun.h handler.hheadfile.h#ifndef _HEADFILE_H__ #define _HEADFILE_H__ #include main.h #include adc.h #include tim.h #include gpio.h #include stdio.h #include stdint.h #include string.h #include key.h #include fun.h #include handler.h #include lcd.h #define ON 1 #define OFF 0 #define DATA 0 #define PARA 1 #define RECD 2 extern uint32_t freA; extern uint8_t lcd_select; extern uint8_t fre_flag; extern uint8_t PWM_num; extern uint8_t flag_5s; extern uint16_t fre4000 ; extern uint8_t R_num; extern uint8_t K_num; extern float V_num; extern uint8_t M_flag; extern PeadState peak_state; extern float candidate_max; extern uint8_t PWM_num; extern float MH_num; extern float ML_num; extern uint8_t led_state; extern uint8_t B4_pressd; extern uint16_t B4_press_duration; extern uint8_t duty_flag; extern double PWM_duty; #endiffun.h#ifndef _FUN_H__ #define _FUN_H__ void Led_Show(uint8_t led, uint8_t mode); void Lcd_Show(void); void Lcd_Change(void); typedef enum{ WAITING,//等待新峰值 MONITORING,//持续检测新峰值 }PeadState; #endifkey.h#ifndef _KEY_H__ #define _KEY_H__ void Key_Scan(void); #endifhandler.h#ifndef _HANDLER_H #define _HANDLER_H #endif8.源文件链接通过网盘分享的文件14届蓝桥杯嵌入式省赛真题链接: https://pan.baidu.com/s/1IyDC74yfF0DUcag-SOnqZg?pwdffc3 提取码: ffc3祝大家在蓝桥杯比赛中能取得好的成绩