蓝桥杯嵌入式组第十四届省赛题目解析+STM32G431RBT6实现源码
文章目录
- 1.题目解析
- 1.1 分而治之,藕断丝连
- 1.2 模块化思维导图
- 1.3 模块解析
- 1.3.1 KEY模块
- 1.3.2 LED模块
- 1.3.3 LCD模块
- 1.3.4 TIM模块
- 1.3.4.1 频率变化处理
- 1.3.4.1 占空比计算
- 1.3.5 ADC模块
- 2.源码
- 2.1cubemx配置
- 3.第十四届题目
前言:STM32G431RBT6实现嵌入式组第十四届题目解析+源码,本文默认读者具备基础的stm32知识。文章末尾附有第十四届题目。
1.题目解析
1.1 分而治之,藕断丝连
还是那句话,将不同模块进行封装,通过变量进行模块间的合作。
函数将模块分而治之,变量使模块间藕断丝连。
1.2 模块化思维导图
下图根据题目梳理。还是使用思维导图。
1.3 模块解析
1.3.1 KEY模块
还是控制按一次处理一次。老朋友了我们就不多说了,题目限制了按键消抖和单次处理,所以我们要加上消抖,和第前几届的处理一模一样。
正常按键逻辑:
开始按下—>按下—>释放;
但是题目要求得按一次处理一次,根据代码逻辑加了一种等待释放状态
根据机械按键的特性开始和结束都得消抖,加上按一次执行一次,所以我们的处理逻辑是:
开始按下—>按下消抖—>短按—>等待弹起—>长按—>弹起—>弹起消抖—>释放;
为了实现按一次执行一次,中间加了一个等待弹起状态(key_state_gain()函数获取到按键状态,key_state_set()设置按键对应按键涉及标志位,下一次进入到key_state_gain()函数中,按键状态就变成了等待弹起状态,这就保证了,短按长按只执行key_state_set()一次)
这里主要说逻辑,具体看源码
if(按键按下){if(是否是释放状态){ //开始按下进入消抖状态,开始消抖计时}else if(是否是消抖状态){ //按下消抖if(当前时间-消抖计时>=消抖时长){消抖完成,进入按下状态}}else if(是否是短按状态 || 是否是长按状态){ //等待弹起状态等待释放状态记录长按2s开始时间}else if(是否是等待状态){ //长按实现if(时间达到2s) 长按状态}
}
else{//没有按下if(是否是等待释放或者按下状态){ //弹起进入消抖状态,开始消抖计时}else if(是否是消抖状态){ //弹起消抖if(当前时间-消抖计时>=消抖时长){消抖完成,按键释放}}
}
1.3.2 LED模块
ld1:数据界面亮,否则灭;
ld2:频率切换期间,以0.1s间隔闪烁;
ld3:占空比锁定亮,否则灭;
其他led保持熄灭状态。
解决办法,设置一个标志位代表ld1~ld8,改变对应位的的值,再将标志位写入ODR寄存器中来控制led的亮灭。
具体实现看源码
1.3.3 LCD模块
lcd显示三个界面,注意首次切换的时候得清屏。
根据B1进行三个界面的切换;
状态0:DATA;
状态1:PARA;
状态1:RECD。
具体实现看源码
1.3.4 TIM模块
TIM4产生0.1s时基。PSC:1699,ARR:9999;
TIM2,chn2: 16, 2499 , 4KHzPWM;
TIM3,chn2: 169, 9999, 捕获范围T<=10ms。
PSC和ARR计算公式(计算周期就是频率的倒数):
1.3.4.1 频率变化处理
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{tim_100ms ^= 1;if(freq_conv_5s != 0){ //频率转换开始freq_conv_5s++;}Hv_2s = Hv_2s < 20 ? Hv_2s+1 : 20; //最大值保持2s计时Lv_2s = Lv_2s < 20 ? Lv_2s+1 : 20;if(freq_conv_5s > 1){ //设置对应的输出频率if(current_freq_mode == 0){current_ARR -= 25;TIM2->ARR = current_ARR;TIM2->CCR2 = (uint32_t)current_ARR*old_duty;}else{current_ARR += 25;TIM2->ARR = current_ARR;TIM2->CCR2 = (uint32_t)current_ARR*old_duty;}if(freq_conv_5s == 51){freq_conv_5s = 0;current_freq_mode ^= 1;conv_N++;}}led_process();HAL_ADC_Start_IT(&hadc2);
}
1.3.4.1 占空比计算
看图可以知道这是一个分段函数。
我们可以这样解决
float caculate_duty()
{if(adc_smp_volt<=1.0){return 0.1;}else if(adc_smp_volt>1.0 && adc_smp_volt<=3.0){return (0.375*adc_smp_volt - 0.275);}else return 0.85;
}
1.3.5 ADC模块
这里adc采集R37电位器电压,这里就不多说。
具体请看源码
2.源码
我所有的实现都在main.c文件中。
2.1cubemx配置
/* USER CODE BEGIN Header */
/********************************************************************************* @file : main.c* @brief : Main program body******************************************************************************* @attention** Copyright (c) 2025 STMicroelectronics.* All rights reserved.** This software is licensed under terms that can be found in the LICENSE file* in the root directory of this software component.* If no LICENSE file comes with this software, it is provided AS-IS.********************************************************************************/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "adc.h"
#include "tim.h"
#include "gpio.h"/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stdio.h"
#include "string.h"
#include "lcd.h"
/* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD *//* USER CODE END PTD *//* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define PI 3.14
/* USER CODE END PD *//* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*//* USER CODE BEGIN PV *//* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP *//* USER CODE END PFP *//* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
//按键状态
enum{key_released = 0U,key_reduction,key_short_pressed,key_wait_pressed,key_long_pressed,
};//记录低频和高频速度
struct{float ML_new;float MH_new;float ML_old;float MH_old;
} max_v = {0.0f};
/*
adc_smp_volt: adc采集电压
current_duty: 实时占空比
old_duty: 保持占空比,比如锁定会记录上一次占空比
*/
float adc_smp_volt = 0.0f, current_duty = 0.0f, old_duty = 0.0f;
/*
keys_volt: 按键电平
keys_state: 按键状态
RK_val: 实际起作用的RK值
RK_val_set: 设置时候的RK值
*/
uint8_t keys_volt[4] = {0}, keys_state[4] = {0}, RK_val[2] = {1,1}, RK_val_set[2] = {1,1};
/*
key_redu: 记录消抖时间戳
key_long_2s: 长按时间戳
current_ARR: tim3的arr值
IC_freq: 捕获到的频率
conv_N: 界面三N的值
*/
uint32_t key_redu = 0, key_long_2s = 0, current_ARR = 2499, IC_freq = 0, conv_N = 0;
/*
lcd_show_conv: 界面切换标志
RK_choose_conv: RK按键切换选择
freq_conv_5s: 切换5s计时
duty_lock: 锁定标志
current_freq_mode: pinlv模式
Hv_2s: 高频速度2s计时
Lv_2s: 低频速度2s计时
lcd_clear_flag: 界面刷新
ld_flag: led控制标志
tim_100ms: 100ms标志
*/
uint8_t lcd_show_conv = 0, RK_choose_conv = 0,freq_conv_5s = 0, duty_lock = 0, current_freq_mode = 0,Hv_2s = 0, Lv_2s = 0, lcd_clear_flag = 0, ld_flag = 0, tim_100ms = 0;
/*
old_IC_val: 采集CCR值,计算频率
new_IC_val: 采集CCR值
*/
uint16_t old_IC_val = 0, new_IC_val = 0;
//lcd显示
char lcd_str[25] = {0};void key_state_gain();
void key_process();
void lcd_process();
void led_process();
float caculate_duty();
void caculate_v();/* USER CODE END 0 *//*** @brief The application entry point.* @retval int*/
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init */LCD_Init();LCD_Clear(Black);LCD_SetBackColor(Black);LCD_SetTextColor(White);/* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_TIM2_Init();MX_TIM3_Init();MX_TIM4_Init();MX_ADC2_Init();/* USER CODE BEGIN 2 */HAL_ADCEx_Calibration_Start(&hadc2, ADC_SINGLE_ENDED);HAL_TIM_Base_Start_IT(&htim4);HAL_TIM_PWM_Start_IT(&htim2, TIM_CHANNEL_2);HAL_TIM_IC_Start_IT(&htim3, TIM_CHANNEL_2);HAL_ADC_Start_IT(&hadc2);/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */key_state_gain();key_process();caculate_v();lcd_process();}/* USER CODE END 3 */
}/*** @brief System Clock Configuration* @retval None*/
void SystemClock_Config(void)
{RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};/** Configure the main internal regulator output voltage*/HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1_BOOST);/** Initializes the RCC Oscillators according to the specified parameters* in the RCC_OscInitTypeDef structure.*/RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV6;RCC_OscInitStruct.PLL.PLLN = 85;RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB buses clocks*/RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK){Error_Handler();}
}/* USER CODE BEGIN 4 */
//获取按键状态
void key_state_gain()
{keys_volt[0] = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0);keys_volt[1] = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1);keys_volt[2] = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2);keys_volt[3] = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0);for(uint8_t i=0;i<4;i++){if(keys_volt[i] == 0){if(keys_state[i] == key_released){key_redu = HAL_GetTick();keys_state[i] = key_reduction;}else if(keys_state[i] == key_reduction){if(HAL_GetTick()-key_redu>=10){keys_state[i] = key_short_pressed;key_long_2s = HAL_GetTick();} }else if(keys_state[i] == key_short_pressed){keys_state[i] = key_wait_pressed;}else if(keys_state[i] == key_wait_pressed){if(HAL_GetTick() - key_long_2s>=2000){keys_state[i] = key_long_pressed;}}else if(keys_state[i] == key_long_pressed){keys_state[i] = key_wait_pressed;}}else{if(keys_state[i] == key_short_pressed || keys_state[i] == key_wait_pressed ||keys_state[i] == key_long_pressed){keys_state[i] = key_reduction;key_redu = HAL_GetTick(); }else if(keys_state[i] == key_reduction){if(HAL_GetTick()-key_redu>=10){keys_state[i] = key_released;} }}}
}
//根据按键状态设置对应标志位
void key_process()
{if(keys_state[0] == key_short_pressed){lcd_show_conv = lcd_show_conv!=2 ? lcd_show_conv+1 : 0;if(lcd_show_conv == 2){RK_val[0] = RK_val_set[0];RK_val[1] = RK_val_set[1];}}if(keys_state[1] == key_short_pressed){if(lcd_show_conv == 0){if(freq_conv_5s == 0){freq_conv_5s = 1;old_duty = current_duty;} }else if(lcd_show_conv == 1){RK_choose_conv ^= 1;}}if(keys_state[2] == key_short_pressed){if(lcd_show_conv == 1){RK_val_set[RK_choose_conv] = RK_val_set[RK_choose_conv]<10?RK_val_set[RK_choose_conv]+1:10;}}if(keys_state[3] == key_short_pressed){if(lcd_show_conv == 1){RK_val_set[RK_choose_conv] = RK_val_set[RK_choose_conv]>1?RK_val_set[RK_choose_conv]-1:1;}duty_lock = 0;}if(keys_state[3] == key_long_pressed){duty_lock = 1;old_duty = current_duty;}
}
//lcd显示
void lcd_process()
{switch(lcd_show_conv){case 0:if(lcd_clear_flag == 2){LCD_Clear(Black);lcd_clear_flag = 0;}LCD_DisplayStringLine(Line1, (uint8_t*)" DATA ");if(current_freq_mode == 0) sprintf(lcd_str, " M=L ");else sprintf(lcd_str, " M=H ");LCD_DisplayStringLine(Line3, (uint8_t*)lcd_str);if(duty_lock == 1 || freq_conv_5s != 0) {sprintf(lcd_str, " P=%d%% ", (int)(old_duty*100));}else sprintf(lcd_str, " P=%d%% ", (int)(current_duty*100));LCD_DisplayStringLine(Line4, (uint8_t*)lcd_str);sprintf(lcd_str, " V=%.1f ", (float)IC_freq*PI*RK_val[0]/50.0/RK_val[1]);LCD_DisplayStringLine(Line5, (uint8_t*)lcd_str);break;case 1:if(lcd_clear_flag == 0){LCD_Clear(Black);lcd_clear_flag = 1;}LCD_DisplayStringLine(Line1, (uint8_t*)" PARA ");sprintf(lcd_str, " R=%hhu ", RK_val_set[0]);LCD_DisplayStringLine(Line3, (uint8_t*)lcd_str);sprintf(lcd_str, " K=%hhu " , RK_val_set[1]);LCD_DisplayStringLine(Line4, (uint8_t*)lcd_str);break;case 2:if(lcd_clear_flag == 1){LCD_Clear(Black);lcd_clear_flag = 2;}LCD_DisplayStringLine(Line1, (uint8_t*)" RECD ");sprintf(lcd_str, " N=%u ", conv_N);LCD_DisplayStringLine(Line3, (uint8_t*)lcd_str);sprintf(lcd_str, " MH=%.1f ", max_v.MH_old);LCD_DisplayStringLine(Line4, (uint8_t*)lcd_str);sprintf(lcd_str, " ML=%.1f ", max_v.ML_old);LCD_DisplayStringLine(Line5, (uint8_t*)lcd_str);break;}
}
//led处理
void led_process()
{if(lcd_show_conv == 0){ld_flag = 1;}else ld_flag = 0;if(freq_conv_5s!=0){ld_flag += tim_100ms << 1;}if(duty_lock == 1){ld_flag += 1<<2;}HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2,1);GPIOC->ODR = 0xffff ^ ld_flag << 8;HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2,0);
}//计算占空比
float caculate_duty()
{if(adc_smp_volt<=1.0) return 0.1;else if(adc_smp_volt>1.0 && adc_smp_volt<3.0) return 0.375*adc_smp_volt - 0.275;else return 0.85;
}//计算速度最大值
void caculate_v(){static float maxl = 0, maxh = 0;if(maxh != max_v.MH_new){Hv_2s = 0;maxh = max_v.MH_new;}else{if(Hv_2s == 20 && max_v.MH_old < maxh){max_v.MH_old = maxh;}}if(maxl != max_v.ML_new){Lv_2s = 0;maxl = max_v.ML_new;}else{if(Lv_2s == 20 && max_v.ML_old < maxl){max_v.ML_old = maxl;}}
}void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{if(duty_lock == 1){ //锁定状态占空比不变TIM2->CCR2 = (uint32_t)current_ARR*old_duty;}else{ TIM2->CCR2 = (uint32_t)current_ARR*current_duty;}
}void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{new_IC_val = TIM3 -> CCR2; //采集ccr值if(new_IC_val > old_IC_val){ IC_freq = 100*10000/(new_IC_val - old_IC_val); //f2 = f1的arr /f2的arr * f1}else{IC_freq = 100*10000/(new_IC_val + 10000 - old_IC_val);}old_IC_val = new_IC_val;if(current_freq_mode == 0){ //根据模式计算更新速度最大值max_v.ML_new = (float)IC_freq*PI*RK_val[0]/50.0/RK_val[1];}else max_v.MH_new = (float)IC_freq*PI*RK_val[0]/50.0/RK_val[1];
}void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{tim_100ms ^= 1;if(freq_conv_5s != 0){ //频率转换开始freq_conv_5s++;}Hv_2s = Hv_2s < 20 ? Hv_2s+1 : 20; //最大值保持2s计时Lv_2s = Lv_2s < 20 ? Lv_2s+1 : 20;if(freq_conv_5s > 1){ //设置对应的输出频率if(current_freq_mode == 0){current_ARR -= 25;TIM2->ARR = current_ARR;TIM2->CCR2 = (uint32_t)current_ARR*old_duty;}else{current_ARR += 25;TIM2->ARR = current_ARR;TIM2->CCR2 = (uint32_t)current_ARR*old_duty;}if(freq_conv_5s == 51){freq_conv_5s = 0;current_freq_mode ^= 1;conv_N++;}}led_process();HAL_ADC_Start_IT(&hadc2);
}void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{adc_smp_volt = HAL_ADC_GetValue(hadc)*3.3/4096;current_duty = caculate_duty();
}
/* USER CODE END 4 *//*** @brief This function is executed in case of error occurrence.* @retval None*/
void Error_Handler(void)
{/* USER CODE BEGIN Error_Handler_Debug *//* User can add his own implementation to report the HAL error return state */__disable_irq();while (1){}/* USER CODE END Error_Handler_Debug */
}#ifdef USE_FULL_ASSERT
/*** @brief Reports the name of the source file and the source line number* where the assert_param error has occurred.* @param file: pointer to the source file name* @param line: assert_param error line source number* @retval None*/
void assert_failed(uint8_t *file, uint32_t line)
{/* USER CODE BEGIN 6 *//* User can add his own implementation to report the file name and line number,ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) *//* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
3.第十四届题目
相关文章:
蓝桥杯嵌入式组第十四届省赛题目解析+STM32G431RBT6实现源码
文章目录 1.题目解析1.1 分而治之,藕断丝连1.2 模块化思维导图1.3 模块解析1.3.1 KEY模块1.3.2 LED模块1.3.3 LCD模块1.3.4 TIM模块1.3.4.1 频率变化处理1.3.4.1 占空比计算 1.3.5 ADC模块 2.源码2.1cubemx配置3.第十四届题目 前言:STM32G431RBT6实现嵌入…...
让双向链表不在云里雾里
又来博客留下我的足迹了,哈哈哈,这次是对于双向链表的理解 目录 创建双向链表: 申请结点: 双向链表初始化: 双向链表插入结点: 双向链表删除结点: 双向链表的打印: 双向链表…...
基于django+vue的购物商城系统
开发语言:Python框架:djangoPython版本:python3.8数据库:mysql 5.7数据库工具:Navicat11开发软件:PyCharm 系统展示 系统首页 热卖商品 优惠资讯 个人中心 后台登录 管理员功能界面 用户管理 商品分类管理…...
在Vue3中使用Echarts的示例
1.常用-引用ts文件方式 1.1 导出ts文件-一个简单的柱状图 export const baseBarChart (xdata: string[], data: number[][], legendData: string[]) > {if (data.length 0) {return noData;}// 定义颜色数组const color [#00CCCC,#FF9900,#1677DC,#FF6666,#B366FF,#666…...
TCP协议的多线程应用、多线程下的网络编程
DAY13.2 Java核心基础 多线程下的网络编程 基于单点连接的方式,一个服务端对应一个客户端,实际运行环境中是一个服务端需要对应多个客户端 创建ServerSocketNable类,多线程接收socket对象 public class ServerSocketNable implements Run…...
每日学习Java之一万个为什么(待补充)
Git分支操作 git branch 分支名 git branch -v git checkout -b 分支名 git checkout 分支名 git merge 分支名 git branch -d | -D 分支名Git冲突 git同名文件合并的最基本单位是行。同名文件同一行不同就会发生冲突。 解决办法:及时沟通,手动更改&…...
设计C语言的单片机接口
一、主要内容 (一)控制引脚 1、定义管脚 // 定义管脚的结构体 struct pin{ int id; // 管脚编号 int mode; // 模式,输入为1,输出为0 int pull; // 输入电阻 int driver; // 功率 } 2、输出电平 语法: void pin_output(s…...
博客迁移----宝塔面板一键迁移遇到问题
前景 阿里云轻量级服务器到期了,又免费领了个ESC, 安转了宝塔面板。现在需要迁移数据,使用宝塔面板一键迁移功能,完成了数据的迁移,改了域名的解析,现在进入博客是显示502 bad grateway 宝塔搬家参考链接…...
抽象工厂模式 (Abstract Factory Pattern)
抽象工厂模式 (Abstract Factory Pattern) 是一种创建型设计模式,它提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。 一、基础 1. 意图 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。 2. …...
LeetCode 第14~16题
目录 LeetCode 第14题:最长公共前缀 LeetCode 第15题:三数之和 LeetCode 第16题:最接近的三数之和 LeetCode 第14题:最长公共前缀 题目描述 编写一个函数来查找字符数组中的最长公共前缀。如果不存在公共前缀,返回字符…...
深入了解Linux —— git三板斧
版本控制器git 为了我们方便管理不同版本的文件,就有了版本控制器; 所谓的版本控制器,就是能够了解到一个文件的历史记录(修改记录);简单来说就是记录每一次的改动和版本迭代的一个管理系统,同…...
再学:abi编码 地址类型与底层调用
目录 1.内置全局变量及函数 2.abi 3.地址类型 4.transfer 1.内置全局变量及函数 2.abi data就是abi编码 abi描述:以json格式表明有什么方法 3.地址类型 4.transfer x.transfer:合约转给x call 和 delegatecall 是 Solidity 中用于底层合约调用的函数࿰…...
Redis的消息队列是怎么实现的
Redis 本身并不是一个专门的消息队列系统,但它的 List、Pub/Sub 和 Stream 数据结构可以用来实现消息队列的功能。以下是 Redis 实现消息队列的几种常见方式: 1. 基于 List 实现消息队列 Redis 的 List 是一个双向链表,支持在头部和尾部进行高效的插入和删除操作,非常适合…...
图论入门【数据结构基础】:什么是树?如何表示树?
图论是计算机科学和数学中的一个重要分支,研究图的结构及其性质。之前我们介绍了图的基本概念和表示:图论入门【数据结构基础】:什么是图?如何表示图?,本文将介绍树的基本概念、性质及其在计算机科学中的应…...
微信小程序订阅消息发送消息,点击消息进入小程序页面
1、在小程序官网订阅消息选用或创建消息模板获取模板ID可多个 如图: 2、微信小程序前端页面发送请求订阅权限 请求模板id的权限可以是一个可以是多个,用户同意订阅,获取code传递给后端——后端拿到code生成唯一的openid用于发送订阅消息 注…...
基于小参数量大语言模型(Small Language Models) ---- 在制造业落地降本增效应用:可行性研究初探
文章大纲 一、引言二、小参数量模型概述基本技术要求小参数量大语言模型在制造业场景中的适用性分析(一)排产优化(二)错误根因分析三、制造业小参数量大语言模型开源解决方案简介Bert 系列 模型Google微软MetaMistral AI国产解决方案四、技术实现方案进行逻辑(一)模型选择…...
pandas中excel自定义单元格颜色
writerpd.ExcelWriter(filepathf05教师固定学生占比1月{today}.xlsx,engineopenpyxl) df.to_excel(writer,sheet_name明细) piv1.to_excel(writer,sheet_name1月分布) wswriter.book.create_sheet(口径) ws.cell(1,1).value综合占比: ws.cell(1,2).value固定学生占比…...
MySQL事务:确保数据一致性的关键机制
目录 1. 为什么需要事务? 2. 什么是事务? 3. 事务的四大特性 3.1 原子性(Atomicity) 3.2 一致性(Consistency) 3.3 隔离性(Isolation) 3.4 持久性(Durability&…...
图论入门【数据结构基础】:什么是图?如何表示图?
图(Graph) 是一种非线性数据结构,用于表示对象之间的关系。图由 顶点(Vertex) 和 边(Edge) 组成,其中顶点表示对象,边表示对象之间的关系。图广泛应用于计算机科学、数学…...
SpringBoot中使用AJ-Captcha实现行为验证码(滑动拼图、点选文字)
简介 AJ-Captcha行为验证码,包含滑动拼图、文字点选两种方式,UI支持弹出和嵌入两种方式。后端提供Java、Golang实现,前端提供了php、angular、html、vue、uni-app、flutter、android、ios等代码示例。点击前往AJ-Captcha代码仓库 引入Maven…...
【国际研讨会】2025年3-5月通信、算法、电气工程、自动化等领域国际学术会议征稿开启!大型学术盛宴!
【国际研讨会】2025年3-5月通信、算法、电气工程、自动化等领域国际学术会议征稿开启!大型学术盛宴! 【国际研讨会】2025年3-5月通信、算法、电气工程、自动化等领域国际学术会议征稿开启!大型学术盛宴! 文章目录 【国际研讨会】…...
AI战略家:X厂三年复盘大纲——业务与组织双视角深度拆解
一、业务负责人视角:从0到1与从1到100的核心能力模型 (一)阶段能力要求与问题预判 1. 从0到1:破局能力 核心能力升级框架: 需求洞察三阶漏斗: 行业需求池:广泛收集行业内的各种需求ÿ…...
LuaJIT 学习(4)—— FFI 语义
文章目录 C Language SupportC Type Conversion RulesConversions from C types to Lua objects例子:访问结构体成员 Conversions from Lua objects to C typesConversions between C types例子:修改结构体成员 Conversions for vararg C function argum…...
剑指 Offer II 078. 合并排序链表
comments: true edit_url: https://github.com/doocs/leetcode/edit/main/lcof2/%E5%89%91%E6%8C%87%20Offer%20II%20078.%20%E5%90%88%E5%B9%B6%E6%8E%92%E5%BA%8F%E9%93%BE%E8%A1%A8/README.md 剑指 Offer II 078. 合并排序链表 题目描述 给定一个链表数组,每个链…...
go回调函数的使用
在Go语言中,回调函数可以有参数,也可以没有参数。它们的定义和使用方式略有不同,但本质上都是将函数作为参数传递给另一个函数,并在适当的时候调用它。以下是带参数和不带参数的回调函数的示例和说明。 1. 不带参数的回调函数 不…...
CBNet:一种用于目标检测的复合骨干网架构之论文阅读
摘要 现代顶级性能的目标检测器在很大程度上依赖于骨干网络,而骨干网络的进步通过探索更高效的网络结构带来了持续的性能提升。本文提出了一种新颖且灵活的骨干框架——CBNet,该框架利用现有的开源预训练骨干网络,在预训练-微调范式下构建高…...
k8s中PAUSE容器与init容器比较 local卷与hostpath卷比较
目录 一、PAUSE容器与INIT容器比较 1. Pause 容器 作用 特点 示例 2. Init 容器 作用 特点 示例 3. Pause 容器 vs Init 容器 4. 总结 这两个哪个先启动呢? 详细启动顺序 为什么 Pause 容器最先启动? 示例 总结 二、local卷与hostpath卷…...
施耐德PLC仿真软件Modbus tcp通讯测试
安装仿真软件:EcoStruxure™ Control Expert - PLC 仿真器 下载地址:https://www.schneider-electric.cn/zh/download/document/EIO0000001719/ 配置CPU: 切换至仿真模式,系统托盘中出现仿真器图标 新建变量test,地址…...
TCP、UDP协议的应用、ServerSocket和Socket、DatagramSocket和DatagramPacket
DAY13.1 Java核心基础 TCP协议 TCP 协议是面向连接的运算层协议,比较复杂,应用程序在使用TCP协议之前必须建立连接,才能传输数据,数据传输完毕之后需要释放连接 就好比现实生活中的打电话,首先确保电话打通了才能进…...
【HarmonyOS Next】常见的字节转换
【HarmonyOS Next】常见的字节转换 字节转换、位运算在实际开发中具有广泛的应用价值,特别是在处理字节级数据时发挥着重要作用。例如,在网络通信中用于大小端序转换,在数据解析时进行位提取操作。这些特性使得位运算在USB通信、蓝牙&#x…...
Redis-锁-商品秒杀防止超卖
一、秒杀(Seckill) 1. 定义 秒杀:短时间内(如1秒内)大量用户同时抢购 限量低价商品 的营销活动。典型场景:双11热门商品抢购、小米手机首发、演唱会门票开售。 2. 技术挑战 挑战点说明后果…...
RHCE(RHCSA复习:npm、dnf、源码安装实验)
七、软件管理 7.1 rpm 安装 7.1.1 挂载 [rootlocalhost ~]# ll /mnt total 0 drwxr-xr-x. 2 root root 6 Oct 27 21:32 hgfs[rootlocalhost ~]# mount /dev/sr0 /mnt #挂载 mount: /mnt: WARNING: source write-protected, mounted read-only. [rootlocalhost ~]# [rootlo…...
KNN算法性能优化技巧与实战案例
KNN算法性能优化技巧与实战案例 K最近邻(KNN)在分类和回归任务中表现稳健,但其计算复杂度高、内存消耗大成为IT项目中的主要瓶颈。以下从 算法优化、数据结构、工程实践 三方面深入解析性能提升策略,并附典型应用案例。 一、核心性…...
安装并使用anaconda(宏观版)
conda安装 windows 安装 1 官网下载-下载地址 2 配置环境 - 安装目录 bin,script 三个填入环境变量(windows “系统属性” -> “高级系统设置” -> “环境变量” ) 这些值可以被运行在操作系统上的程序使用。它是一个通用的概念,在不同的操作系统和应用程序…...
Qwen2.5-VL 开源视觉大模型,模型体验、下载、推理、微调、部署实战
一、Qwen2.5-VL 简介 Qwen2.5-VL,Qwen 模型家族的旗舰视觉语言模型,比 Qwen2-VL 实现了巨大的飞跃。 欢迎访问 Qwen Chat (Qwen Chat)并选择 Qwen2.5-VL-72B-Instruct 进行体验。 1. 主要增强功能 1)直观地理解事物&…...
【sql靶场】第18-22关-htpp头部注入保姆级教程
目录 【sql靶场】第18-22关-htpp头部注入保姆级教程 1.回顾知识 1.http头部 2.报错注入 2.第十八关 1.尝试 2.爆出数据库名 3.爆出表名 4.爆出字段 5.爆出账号密码 3.第十九关 4.第二十关 5.第二十一关 6.第二十二关 【sql靶场】第18-22关-htpp头部注入保姆级教程…...
SpringBoot实现发邮件功能+邮件内容带模版
发送简单邮件模版邮件 1.pom引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId><version>2.5.13</version></dependency><dependency><groupId&…...
C# NX二次开发:矩形阵列和线性阵列等多种方法讲解
大家好,今天讲一些关于阵列相关的UFUN函数。 UF_MODL_create_linear_iset (view source):这个函数为创建矩形阵列。 intmethodInputMethod: 0 General 1 Simple 2 Identicalchar *number_in_xInputNumber in XC direction.char *distance_xInputSpac…...
OpenBMC:BmcWeb添加路由1 getParameterTag
BmcWeb对于路由的设计其实是参考了Crow BMCWEB_ROUTE(app, "/upload/image/<str>").privileges({{"ConfigureComponents", "ConfigureManager"}}).methods(boost::beast::http::verb::post, boost::beast::http::verb::put)([](const cro…...
【Android性能】Systrace分析
1,分析工具 1,Systrace新UI网站 Perfetto UI 2,Systrace抓取 可通过android sdk中自带的systrace抓取,路径一般如下,..\AppData\Local\Android\Sdk\platform-tools, 另外需要安装python2.7,…...
多种语言请求API接口方法
在当今的互联网世界中,应用程序编程接口(API)扮演着至关重要的角色,它们允许不同的服务和应用程序之间进行数据交换和功能共享。无论是获取天气预报、社交媒体数据还是进行支付操作,API都是背后的关键。不同的编程语言…...
【css酷炫效果】纯CSS实现瀑布流加载动画
【css酷炫效果】纯CSS实现瀑布流加载动画 缘创作背景html结构css样式完整代码基础版进阶版(无限往复加载) 效果图 想直接拿走的老板,链接放在这里:https://download.csdn.net/download/u011561335/90492012 缘 创作随缘,不定时更新。 创作…...
【第15届蓝桥杯】软件赛CB组省赛
个人主页:Guiat 归属专栏:算法竞赛真题题解 文章目录 A. 握手问题(填空题)B. 小球反弹(填空题)C. 好数D. R格式E. 宝石组合F. 数字接龙G. 爬山H. 拔河 正文 总共8道题。 A. 握手问题(填空题&…...
20242817李臻《Linux⾼级编程实践》第四周
20242817李臻《Linux⾼级编程实践》第4周 一、AI对学习内容的总结 第5章 Linux进程管理 5.1 进程基本概念 进程与程序的区别 程序:静态的二进制文件(如/bin/ls),存储在磁盘中,不占用运行资源。进程:程…...
【AI大模型】提示词(Prompt)工程完全指南:从理论到产业级实践
【AI大模型】提示词(Prompt)工程完全指南:从理论到产业级实践 一、Prompt 提示词介绍:AI的“密码本” 1. Prompt的底层定义与价值 本质:Prompt是人与AI模型的“协议语言”,通过文本指令激活模型的特定推理…...
HTML中required与aria required区别
在HTML中,required和aria-required"true"都用于标识表单字段为必填项,但它们的作用和适用场景有所不同: 1. required 属性 • 功能属性:属于HTML5原生属性,直接控制表单验证逻辑。 • 作用: • …...
MySQL 锁
MySQL中最常见的锁有全局锁、表锁、行锁。 全局锁 全局锁用于锁住当前库中的所有实例,也就是说会将所有的表都锁住。一般用于做数据库备份的时候就需要添加全局锁,数据库备份的时候是一个表一个表备份,如果没有加锁的话在备份的时候会有其他的…...
halcon几何测量(一)3d_position_of_rectangle
目录 一、提取目标区域,选择不和边缘相交的目标二、计算矩形工件的姿态三、显示矩形的立体结构 一、提取目标区域,选择不和边缘相交的目标 1、提取目标区域:mean_image 、dyn_threshold 、fill_up 、connection 、select_shape 2、选择不和边…...
docker可视化之dpanel
1. 使用镜像加速 vim /etc/docker/daemon.json{ "registry-mirrors": ["https://docker.registry.cyou","https://docker-cf.registry.cyou","https://dockercf.jsdelivr.fyi","https://docker.jsdelivr.fyi","https…...
Swagger 从 .NET 9 中删除:有哪些替代方案
微软已经放弃了对 .NET 9 中 Swagger UI 包 Swashbuckle 的支持。他们声称该项目“不再由社区所有者积极维护”并且“问题尚未得到解决”。 这意味着当您使用 .NET 9 模板创建 Web API 时,您将不再拥有 UI 来测试您的 API 端点。 我们将调查是否可以在 .NET 9 中使用…...