STM32G431 FOC程序逻辑全解析:从主循环到中断与状态机设计
最近在调试一个基于STM32G431的无刷电机FOC控制项目时发现网上很多开源代码虽然功能完整但程序逻辑和代码结构对初学者来说像一团乱麻尤其是中断、状态机、SVPWM和PID环之间的耦合关系常常让人理不清头绪。本文将深入剖析一个典型的开源STM32G431 FOC程序从工程结构、主循环逻辑、中断服务到核心算法实现一步步拆解其运行机制。无论你是刚开始接触电机控制的学生还是希望优化现有代码的工程师都能通过本文获得一套清晰的代码阅读与调试方法。1. FOC与STM32G431项目背景与核心概念无刷直流电机BLDC和永磁同步电机PMSM的高性能控制离不开磁场定向控制Field-Oriented Control, FOC。FOC的核心思想是将电机的三相电流通过克拉克Clark和帕克Park变换从静止的三相坐标系转换到旋转的两相直交坐标系d-q轴上。在这个坐标系下励磁电流分量Id和转矩电流分量Iq被解耦可以像控制直流电机一样分别进行控制从而获得更快的动态响应、更高的效率以及更平稳的低速转矩。STM32G431是意法半导体推出的一款基于Arm® Cortex®-M4内核的微控制器其高主频170MHz、丰富的定时器资源特别是高级控制定时器如TIM1以及高精度ADC使其成为实现FOC算法的理想平台。开源社区中有许多基于HAL库或LL库的FOC工程它们通常包含了完整的双闭环电流环、速度环控制、SVPWM生成、位置与速度估算无感或有感等功能。理解这类开源工程关键在于把握其“逻辑”——即软件如何通过中断、状态机和数据流来协调硬件资源实时地完成电流采样、坐标变换、PID计算和PWM更新这一系列任务。本文将围绕一个典型的工程讲解其程序骨架和核心逻辑流。2. 工程环境准备与代码结构概览在开始分析代码逻辑之前我们需要搭建一个可以阅读、编译甚至调试的环境。2.1 软硬件环境说明开发板/主控STM32G431CBU6或其他G4系列芯片注意引脚兼容性。电机驱动板常用的三相全桥驱动电路如DRV8301、IR2136等栅极驱动器方案。开发环境IDE: STM32CubeIDE推荐便于管理HAL库和生成初始化代码。编译工具链: ARM GCC (已集成在CubeIDE中)。调试器: ST-LINK/V2。关键软件库STM32CubeG4 HAL库: 提供硬件抽象层驱动。FOC算法库: 开源工程中通常自己实现或封装了数学库包含clarke_transform,park_transform,svpwm等函数。工程来源本文分析的逻辑基于GitHub、Gitee等平台上常见的“STM32G431-FOC-无刷电机”开源项目。你可以搜索相关关键词找到并下载工程。版本兼容性提示不同版本的HAL库或CubeMX生成的代码在函数名或配置上可能有细微差别。如果遇到编译错误请根据错误信息调整头文件引用或函数调用核心逻辑通常不变。2.2 典型开源FOC工程目录结构下载并打开工程后你会看到类似如下的目录结构。理解这个结构是读懂逻辑的第一步。Your_FOC_Project/ ├── Core/ │ ├── Inc/ │ │ ├── main.h │ │ ├── foc_algorithm.h // FOC算法头文件 │ │ ├── pid_regulator.h // PID控制器头文件 │ │ ├── motor_control.h // 电机状态与控制头文件 │ │ └── ... │ ├── Src/ │ │ ├── main.c // 主函数与主循环 │ │ ├── foc_algorithm.c // FOC算法实现 │ │ ├── pid_regulator.c // PID控制器实现 │ │ ├── motor_control.c // 电机控制状态机 │ │ └── ... ├── Drivers/ │ ├── STM32G4xx_HAL_Driver/ // HAL库文件 │ └── CMSIS/ // Cortex微控制器软件接口标准 ├── STM32G431CBUX_FLASH.ld // 链接脚本 └── README.md // 工程说明核心文件说明main.c程序的入口包含系统初始化、外设初始化和主循环(while(1))。主循环通常处理非实时任务如通信接收、状态显示、目标值更新等。foc_algorithm.c/.hFOC数学运算的核心包含坐标变换、反变换、SVPWM扇区判断与占空比计算。pid_regulator.c/.h实现PID控制器用于电流环和速度环的调节。motor_control.c/.h定义电机控制的状态如停止、启动、运行、故障并实现状态机管理逻辑。中断服务程序通常直接在stm32g4xx_it.c文件中或者通过HAL库的回调函数机制实现。这是实时控制的关键。3. 核心控制逻辑与程序流程拆解一个完整的FOC程序运行依赖于精心设计的中断时序和主从任务分工。其核心逻辑可以概括为“后台规划前台执行”。3.1 主循环 (while(1))后台任务管理器主循环在系统初始化后一直运行负责非实时或实时性要求不高的任务。它的优先级最低。// 文件路径Core/Src/main.c (片段) int main(void) { // 1. HAL库、系统时钟、GPIO、ADC、定时器等初始化 HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_ADC1_Init(); MX_TIM1_Init(); // 高级定时器用于产生PWM和触发ADC MX_USART1_UART_Init(); // 用于调试输出或指令接收 // 2. FOC算法、PID参数、电机控制模块初始化 FOC_Init(); PID_Current_Init(pid_id, kp_id, ki_id, kd_id); // d轴电流PID PID_Current_Init(pid_iq, kp_iq, ki_iq, kd_iq); // q轴电流PID PID_Speed_Init(pid_speed, kp_spd, ki_spd, kd_spd); // 速度环PID Motor_Control_Init(motor); // 3. 启动关键定时器如PWM定时器TIM1 HAL_TIM_PWM_Start(htim1, TIM_CHANNEL_1); HAL_TIM_PWM_Start(htim1, TIM_CHANNEL_2); HAL_TIM_PWM_Start(htim1, TIM_CHANNEL_3); // 启动ADC注入组或规则组的触发定时器如TIM1的TRGO事件 HAL_TIM_Base_Start(htim1); // 4. 主循环开始 while (1) { // 4.1 处理来自上位机如串口、CAN的指令 // 例如设置目标速度、更改控制模式、读取状态等 if (UART_RxFlag) { Parse_UART_Command(); UART_RxFlag 0; } // 4.2 更新电机控制状态机非实时部分 Motor_Control_StateMachine(motor); // 4.3 非关键的系统状态监测与保护如温度、电压 System_Protection_Check(); // 4.4 调试信息输出频率较低如每100ms一次 static uint32_t debug_tick 0; if (HAL_GetTick() - debug_tick 100) { debug_tick HAL_GetTick(); printf(Speed: %d, Id: %.2f, Iq: %.2f\r\n, motor.speed, motor.i_d, motor.i_q); } // 4.5 空闲任务或低功耗模式可选 // __WFI(); } }逻辑解读主循环就像一个“指挥中心”它不直接参与每秒数万次的电流采样与PWM计算而是负责接收外部指令、管理电机运行的大状态启动、停止、故障处理、进行系统监控和输出调试信息。所有实时性要求高的任务都交给了中断服务程序。3.2 定时器中断与ADC采样实时控制的节拍器FOC的实时性体现在固定的控制频率上通常是10kHz到20kHz。这个频率由高级定时器如TIM1的更新中断来设定。常见的配置策略以中心对齐PWM和ADC采样为例TIM1配置为中心对齐模式1产生对称的PWM波形能有效降低谐波。使能TIM1的更新中断和触发输出(TRGO)。TRGO信号用于触发ADC采样。ADC配置为注入组或规则组由TIM1的TRGO事件触发转换。在ADC转换完成中断中读取三相电流值或两相直流母线电压然后进行FOC计算。在TIM1的更新中断中使用计算好的新占空比更新比较寄存器CCR从而更新下一个PWM周期的输出。// 文件路径Core/Src/stm32g4xx_it.c (或相应的回调函数) // ADC转换完成中断回调函数HAL库方式 void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) { if (hadc-Instance ADC1) { // 1. 读取ADC值并转换为实际的电流值单位安培 motor.i_a ADC_To_Ampere(ADC_GetValue(ADC_CHANNEL_A)); motor.i_b ADC_To_Ampere(ADC_GetValue(ADC_CHANNEL_B)); // i_c 可通过 i_a i_b i_c 0 计算得出或使用第三路ADC // 2. 执行FOC控制算法这是最核心的实时任务 FOC_Current_Loop(motor); // 3. 计算并更新SVPWM占空比 SVPWM_UpdateDutyCycle(motor); // 4. 将计算好的占空比写入到TIM1的比较寄存器影子寄存器 // 注意为了波形对称和防止毛刺通常在中心对齐模式的计数器溢出中断中更新CCR // 此处可能只是计算并暂存在TIM更新中断中再实际加载。 motor.duty_a ...; // 计算出的占空比 motor.duty_b ...; motor.duty_c ...; } } // TIM1更新中断回调函数 void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if (htim-Instance TIM1) { // 1. 将计算好的新占空比加载到TIM1的CCR寄存器中 __HAL_TIM_SET_COMPARE(htim1, TIM_CHANNEL_1, motor.duty_a); __HAL_TIM_SET_COMPARE(htim1, TIM_CHANNEL_2, motor.duty_b); __HAL_TIM_SET_COMPARE(htim1, TIM_CHANNEL_3, motor.duty_c); // 2. 速度环计算频率比电流环低例如每N个电流环周期执行一次 static uint8_t speed_loop_counter 0; if (speed_loop_counter SPEED_LOOP_DIVIDER) { speed_loop_counter 0; FOC_Speed_Loop(motor); // 这里面会调用速度PID } // 3. 无感算法位置/速度估算如果使用的是无传感器方案 // Observer_Update(motor); } }逻辑解读这里形成了两个关键的中断链。ADC中断是电流环的起点它在一个PWM周期中的固定时刻通常是在PWM中心点采样电流并立即进行快速计算为下一个PWM周期做好准备。TIM更新中断是PWM周期的终点和起点它负责将计算好的新值加载到硬件中并执行频率较低的速度环计算。这两个中断的紧密协作构成了FOC实时控制的“心跳”。3.3 FOC电流环函数详解这是整个程序算法最密集的部分我们深入FOC_Current_Loop函数内部。// 文件路径Core/Src/foc_algorithm.c void FOC_Current_Loop(Motor_t *motor) { // 步骤1克拉克变换 (Clark Transform) - 3相静止到2相静止 Clarke_Transform(motor-i_a, motor-i_b, motor-i_alpha, motor-i_beta); // 步骤2帕克变换 (Park Transform) - 2相静止到2相旋转(dq) Park_Transform(motor-i_alpha, motor-i_beta, motor-theta_electrical, motor-i_d, motor-i_q); // 步骤3电流环PID调节 // d轴电流控制通常用于弱磁控制基础FOC中常设Id_ref0 motor-v_d_ref PID_Calculate(pid_id, motor-i_d_ref, motor-i_d); // q轴电流控制转矩控制 motor-v_q_ref PID_Calculate(pid_iq, motor-i_q_ref, motor-i_q); // 步骤4反帕克变换 (Inverse Park Transform) - 2相旋转到2相静止 Inverse_Park_Transform(motor-v_d_ref, motor-v_q_ref, motor-theta_electrical, motor-v_alpha_ref, motor-v_beta_ref); // 步骤5计算SVPWM所需的占空比基于v_alpha, v_beta和直流母线电压 // 此函数会判断扇区并计算三相占空比Ta, Tb, Tc SVPWM_CalcDutyCycle(motor-v_alpha_ref, motor-v_beta_ref, motor-v_bus, motor-duty_a, motor-duty_b, motor-duty_c); // 步骤6更新电角度为下一个周期做准备 // 对于有传感器 motor-theta_electrical (motor-speed * DT * POLE_PAIRS); // 对于无传感器 motor-theta_electrical Observer_GetAngle(); // 从观测器获取 }逻辑解读这个函数清晰地展示了FOC算法的标准流水线。它在一个中断周期内将采样到的三相电流经过一系列数学变换最终转换为驱动三相逆变桥的PWM占空比。其中i_q_ref是速度环PID的输出这就将速度环和电流环串联了起来。3.4 电机控制状态机电机不能一上电就全速运行需要有序的启动流程如对齐、开环启动、闭环切换也需要处理各种故障状态过流、过压、过热。这些逻辑由状态机管理。// 文件路径Core/Src/motor_control.c typedef enum { MOTOR_STATE_IDLE 0, MOTOR_STATE_ALIGN, // 转子预定位 MOTOR_STATE_OPEN_LOOP, // 开环启动无感 MOTOR_STATE_CLOSED_LOOP, // 闭环运行 MOTOR_STATE_FAULT } MotorState_t; void Motor_Control_StateMachine(Motor_t *motor) { switch (motor-state) { case MOTOR_STATE_IDLE: if (motor-start_cmd true) { motor-state MOTOR_STATE_ALIGN; motor-start_cmd false; Motor_AlignRotor(); // 发送固定矢量将转子拉到预定位置 motor-align_timer HAL_GetTick(); } break; case MOTOR_STATE_ALIGN: // 预定位持续一段时间如200ms if (HAL_GetTick() - motor-align_timer 200) { motor-state MOTOR_STATE_OPEN_LOOP; motor-open_loop_angle 0; motor-open_loop_speed INIT_SPEED; } break; case MOTOR_STATE_OPEN_LOOP: // 开环递增角度模拟旋转磁场 motor-open_loop_angle motor-open_loop_speed * CONTROL_PERIOD; motor-theta_electrical motor-open_loop_angle; // 强制使用开环角度 // 当速度达到一定值切换到闭环 if (motor-open_loop_speed SWITCH_SPEED) { motor-state MOTOR_STATE_CLOSED_LOOP; // 初始化观测器无感或使能编码器中断有感 } // 缓慢加速 motor-open_loop_speed OPEN_LOOP_ACCEL; break; case MOTOR_STATE_CLOSED_LOOP: // 正常运行状态目标速度由外部指令设定 // i_q_ref 由速度环PID计算得出 motor-i_q_ref PID_Calculate(pid_speed, motor-speed_ref, motor-speed); // 故障检查 if (Check_OverCurrent() || Check_OverVoltage()) { motor-state MOTOR_STATE_FAULT; Emergency_Stop(); } break; case MOTOR_STATE_FAULT: // 关闭PWM输出等待故障复位 HAL_TIM_PWM_Stop(htim1, TIM_CHANNEL_ALL); // 等待复位指令 if (motor-fault_reset_cmd true) { Clear_Fault_Flags(); motor-state MOTOR_STATE_IDLE; motor-fault_reset_cmd false; } break; default: motor-state MOTOR_STATE_IDLE; break; } }逻辑解读状态机是程序稳健性的保证。它确保了电机在任何时候都处于一个明确的状态并且只能在定义好的条件下进行状态转移。例如从IDLE到ALIGN需要启动命令从OPEN_LOOP到CLOSED_LOOP需要达到一定的切换速度。主循环中周期性调用此状态机函数而实时中断中的FOC计算则会根据motor-state来决定使用何种角度开环强制角度或闭环估算角度和何种控制模式。4. 关键模块代码实现与配置要点4.1 SVPWM生成七段式与五段式SVPWM空间矢量脉宽调制是将电压矢量指令转换为具体PWM占空比的关键。开源工程中常见的是七段式SVPWM它在一个PWM周期内分7个段来合成目标矢量谐波特性更好。// 文件路径Core/Src/foc_algorithm.c (片段) // 简化的SVPWM扇区判断与时间计算 void SVPWM_CalcDutyCycle(float v_alpha, float v_beta, float v_bus, float *ta, float *tb, float *tc) { float u_alpha v_alpha / v_bus; float u_beta v_beta / v_bus; // 1. 扇区判断 uint8_t sector 0; if (u_beta 0) { if (u_alpha 0) { sector (sqrtf(3) * u_alpha u_beta) ? 1 : 2; } else { sector (-sqrtf(3) * u_alpha u_beta) ? 3 : 2; } } else { if (u_alpha 0) { sector (-sqrtf(3) * u_alpha u_beta) ? 6 : 5; } else { sector (sqrtf(3) * u_alpha u_beta) ? 4 : 5; } } // 2. 计算基本矢量作用时间 T1, T2 float t1, t2; float sqrt3 sqrtf(3.0f); switch (sector) { case 1: t1 u_beta; t2 (sqrt3 * u_alpha - u_beta) / 2.0f; break; case 2: t1 (sqrt3 * u_alpha u_beta) / 2.0f; t2 -u_beta; break; // ... 其他扇区计算 } // 3. 过调制处理确保T1T2 1 float sum t1 t2; if (sum 1.0f) { t1 t1 / sum; t2 t2 / sum; } // 4. 计算七段式各相占空比 float t_a, t_b, t_c; switch (sector) { case 1: t_a (1 - t1 - t2) / 2; t_b t_a t1; t_c t_b t2; break; case 2: t_a (1 - t1 - t2) / 2; t_c t_a t1; t_b t_c t2; break; // ... 其他扇区占空比分配 } // 5. 将占空比归一化到定时器计数范围 *ta t_a * PWM_PERIOD_COUNTS; *tb t_b * PWM_PERIOD_COUNTS; *tc t_c * PWM_PERIOD_COUNTS; }配置要点在CubeMX中配置TIM1时需要设置为“中心对齐模式1”预分频器和自动重载值(ARR)要根据你的控制频率和系统时钟来计算。PWM频率通常为10-20kHz。ARR的值就是上面代码中的PWM_PERIOD_COUNTS。4.2 PID控制器实现PID是闭环控制的核心需要特别注意积分饱和与抗积分饱和处理。// 文件路径Core/Src/pid_regulator.c typedef struct { float kp; float ki; float kd; float integral; float prev_error; float output_limit; // 输出限幅 float integral_limit; // 积分限幅 } PID_Handle_t; float PID_Calculate(PID_Handle_t *pid, float target, float feedback) { float error target - feedback; // 比例项 float p_out pid-kp * error; // 积分项带限幅和抗饱和 pid-integral pid-ki * error; if (pid-integral pid-integral_limit) pid-integral pid-integral_limit; if (pid-integral -pid-integral_limit) pid-integral -pid-integral_limit; float i_out pid-integral; // 微分项常用不完全微分 float d_out pid-kd * (error - pid-prev_error); pid-prev_error error; // 总和并限幅 float output p_out i_out d_out; if (output pid-output_limit) output pid-output_limit; if (output -pid-output_limit) output -pid-output_limit; return output; }参数整定顺序先调电流环内环再调速度环外环。电流环响应要快通常只使用PI控制器Kd0。调试时先将所有增益设为0逐步增加Kp直到系统开始振荡然后减小到80%左右再加入Ki消除静差。5. 常见问题与调试排查思路在移植或运行开源FOC代码时你可能会遇到以下问题问题现象可能原因排查思路与解决方案电机不转有啸叫声1. PWM输出引脚配置错误互补通道未使能。2. 死区时间设置不当太小导致桥臂直通太大会导致有效电压降低。3. 电流采样相位或极性错误。4. 电角度初始位置不对有感编码器零位无感对齐步骤。1. 用示波器检查6路PWM输出是否正常互补通道是否对称。2. 检查TIM1-BDTR寄存器的死区时间配置通常几百纳秒到1微秒。3. 电机静止时给定一个小的开环角度用手转动转子观察i_alpha, i_beta变化是否与角度同步。若无感检查反电动势观测器是否收敛。电机抖动运行不平稳1. PID参数不合适尤其是积分过大。2. 电流采样噪声大或延迟。3. 控制频率过低或计算耗时过长。4. SVPWM计算中存在数值溢出或错误。1. 重新整定PID参数优先保证电流环稳定。2. 检查ADC采样时刻是否在PWM中心点软件上可增加低通滤波。3. 优化代码将浮点运算移至硬件FPU减少中断服务程序中的计算量。4. 打印出v_alpha, v_beta和计算出的占空比检查其范围是否合理。启动失败无法从开环切闭环1. 开环启动加速度或初始速度设置不当。2. 切换速度阈值设置过高。3. 无感算法观测器在切换点未收敛估算角度误差大。4. 电机参数电阻、电感不准确。1. 降低开环启动加速度延长开环运行时间。2. 降低切换速度阈值确保在较低速时切入闭环。3. 调试观测器在开环阶段注入高频信号或使用其他方法辅助初始位置检测。4. 通过电机测试或查阅手册获取准确的电机参数并更新到代码中。ADC采样值异常1. ADC采样通道、触发源配置错误。2. 未校准ADC偏移。3. 硬件电路问题如运放偏置电压、采样电阻温漂。1. 确认CubeMX中ADC的“External Trigger Source”是否正确设置为TIM1_TRGO。2. 调用HAL_ADCEx_Calibration_Start()进行校准。3. 电机不上电测量采样电路在零电流时的ADC输出并在软件中减去这个偏移量。代码运行一段时间后跑飞1. 中断嵌套或优先级冲突。2. 栈溢出或堆溢出。3. 浮点运算未启用FPU导致中断处理超时。1. 合理设置中断优先级如ADC中断 TIM更新中断 串口中断。2. 在CubeIDE中调大Stack Size和Heap Size。3. 在CubeMX的Project Manager - Code Generator中勾选“FPU”并在代码开头调用SCB-CPACR6. 最佳实践与工程化建议理解了基本逻辑后要让代码更健壮、更易于维护和移植还需要注意以下几点模块化与解耦将FOC算法、PID控制、硬件驱动ADC、TIM、通信协议等严格分离。使用清晰的接口函数和结构体进行交互。这样便于单独测试和替换算法如将PID换成滑模控制。参数可配置化不要将PID参数、电机参数极对数、电阻、电感、控制频率等硬编码在代码中。可以将它们定义为全局变量并通过头文件或单独的config.h文件进行管理甚至通过串口或EEPROM在线调整和保存。安全与保护机制软件保护在关键函数如PID计算、SVPWM计算入口添加参数有效性检查如电压、电流范围。硬件保护利用STM32G4的定时器具有强大的刹车功能。配置GPIO引脚为刹车输入当发生过流时硬件能自动关闭PWM输出响应速度远快于软件中断。状态监控在主循环中定期检查母线电压、芯片温度、各相电流并设置合理的阈值进行保护。调试信息分级输出使用条件编译来控制调试信息的详细程度。例如#define DEBUG_LEVEL 1 // 0:关闭 1:基础信息 2:详细数据 #if DEBUG_LEVEL 0 printf([INFO] Motor started.\r\n); #endif #if DEBUG_LEVEL 1 printf([DATA] Id:%.2f, Iq:%.2f, Theta:%.2f\r\n, i_d, i_q, theta); #endif性能优化启用FPU务必在工程设置中启用单精度浮点单元(FPU)能极大提升计算速度。使用查表法对于频繁调用的三角函数如sinf,cosf可以预先计算一个正弦表用空间换时间。减少中断内耗时在ADC中断中只做最必要的计算电流环将速度环、状态机等移至TIM更新中断或主循环。版本管理与文档使用Git管理你的代码。在关键函数和复杂逻辑处添加清晰的注释。维护一个README.md记录工程依赖的库版本、硬件连接图、关键参数配置和已知问题。通过本文对STM32G431 FOC程序逻辑的层层剖析你应该已经对从主循环到中断服务从状态机到算法实现的完整链条有了清晰的认识。下一步建议你亲手打开一个开源工程结合本文的讲解对照代码逐行阅读并使用调试器和示波器进行验证。从让电机成功转起来到平稳运行再到动态响应调整每一步的实践都会加深你对FOC控制精髓的理解。

相关新闻

AI搜索来源多样性规划工具:从输入校验到离线报告的完整实现

AI搜索来源多样性规划工具:从输入校验到离线报告的完整实现

项目编号:20260731-010。本文代码、测试、文档、示例数据和效果图均为独立编写,不包含热点产品或开源项目源码、品牌素材与官方截图。 问题与目标 统计答案证据的域名、内容类型和发布时间分布,识别单一来源依赖与覆盖偏置。在真实工程里&am…

2026/8/2 16:27:35 阅读更多 →
国产GPU生态现状与开发者实践:从燧原过会看AI算力国产化

国产GPU生态现状与开发者实践:从燧原过会看AI算力国产化

1. 项目概述:从“过会”看国产GPU的产业突围最近,燧原科技在科创板成功过会的消息,在圈内激起了不小的波澜。这不仅仅是一家公司的阶段性胜利,更被许多人视为一个标志性事件——它意味着被业界称为“国产GPU四小龙”的几家代表性企…

2026/8/2 16:27:35 阅读更多 →
04数据结构

04数据结构

冒泡排序 : 两两比较 逻辑 : 给数组中的元素做两两比较,从首个元素开始,小的排前,大的排后,依次两两比较,比完整组后,元素做比较的次数减一,再循环此过程直到比#include <stdio.h> void printArray(int* arr,int length) { //判断数组中是否有元素if (length 0){print…

2026/8/2 16:27:35 阅读更多 →

最新新闻

顺势掌控者系统 同花顺期货通指标

顺势掌控者系统 同花顺期货通指标

今天给大家带来是一款同花顺期货通指标&#xff0c;并且已经上架到同花顺期货通的指标广场上了。喜欢的朋友可以去指标广场安装试用&#xff01;&#xff01;友情提示&#xff1a;&#xff08;指标只是辅助&#xff0c;不作建议&#xff09;拼多多店铺&#xff1a;指标公式编写…

2026/8/2 17:12:01 阅读更多 →
UE4SS终极安装指南:解锁虚幻引擎4游戏修改与脚本注入

UE4SS终极安装指南:解锁虚幻引擎4游戏修改与脚本注入

1. 项目概述&#xff1a;UE4SS是什么&#xff0c;以及为什么你需要它如果你是一个深度PC游戏玩家&#xff0c;尤其是那些基于虚幻引擎4&#xff08;UE4&#xff09;开发的游戏爱好者&#xff0c;那么你很可能已经厌倦了游戏本身的限制&#xff0c;或者渴望一些官方没有提供的功…

2026/8/2 17:12:01 阅读更多 →
如何在Mac上实现NTFS完整读写:Free-NTFS-for-Mac终极解决方案

如何在Mac上实现NTFS完整读写:Free-NTFS-for-Mac终极解决方案

如何在Mac上实现NTFS完整读写&#xff1a;Free-NTFS-for-Mac终极解决方案 【免费下载链接】Free-NTFS-for-Mac Nigate: An open-source NTFS utility for Mac. It supports all Mac models (Intel and Apple Silicon), providing full read-write access, mounting, and manage…

2026/8/2 17:12:01 阅读更多 →
全球协作机器人一哥越疆科技“跨界”造恐龙,能否走出盈利困境?

全球协作机器人一哥越疆科技“跨界”造恐龙,能否走出盈利困境?

全球第一&#xff0c;却依然“生活不易”想要重现《侏罗纪公园》里的恐龙&#xff0c;可能比起生物工程&#xff0c;靠具身智能还靠谱一点。7月底&#xff0c;正值暑假中期&#xff0c;深圳自然博物馆展出了两只“活”的恐龙&#xff0c;让恐龙展厅成了当天全馆排队最长的地方。…

2026/8/2 17:12:01 阅读更多 →
N皇后问题:从回溯算法到状态压缩的深度解析与优化实践

N皇后问题:从回溯算法到状态压缩的深度解析与优化实践

1. 问题引入&#xff1a;从棋盘到代码的经典回溯如果你对算法竞赛或者数据结构与算法这门课稍有接触&#xff0c;那么“N皇后问题”这个名字你一定不陌生。它就像一个算法领域的“Hello World”&#xff0c;但远比打印一行文字要复杂和深刻得多。我第一次在SCAU&#xff08;华南…

2026/8/2 17:12:01 阅读更多 →
解放双手的FGO全自动助手:智能战斗与任务管理的终极解决方案

解放双手的FGO全自动助手:智能战斗与任务管理的终极解决方案

解放双手的FGO全自动助手&#xff1a;智能战斗与任务管理的终极解决方案 【免费下载链接】FGO-py 自动爬塔! 自动每周任务! 全自动免配置跨平台的Fate/Grand Order助手.启动脚本,上床睡觉,养肝护发,满加成圣诞了解一下? 项目地址: https://gitcode.com/GitHub_Trending/fg/F…

2026/8/2 17:11:01 阅读更多 →

日新闻

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

1. 从水管网络到最大流&#xff1a;一个核心问题的诞生想象一下&#xff0c;你是一个城市供水系统的总工程师。你的城市有多个水源&#xff08;水库&#xff09;&#xff0c;需要通过一个复杂的地下管道网络&#xff0c;将水输送到各个居民区。每条管道都有其最大通水能力&…

2026/8/2 0:00:38 阅读更多 →
基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

温馨提示&#xff1a;本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;本人主页置顶文章(点我)开头有 CSDN 平台…

2026/8/2 0:00:38 阅读更多 →
MATLAB xcorr函数详解:从互相关原理到四大实战应用

MATLAB xcorr函数详解:从互相关原理到四大实战应用

1. 从一次信号“找茬”说起&#xff1a;为什么我们需要互相关几年前&#xff0c;我在处理一组声学传感器数据时遇到了一个棘手的问题。我有两个麦克风记录了一段相同的音频信号&#xff0c;理论上它们接收到的声音波形应该非常相似&#xff0c;只是由于麦克风位置不同&#xff…

2026/8/2 0:00:38 阅读更多 →

周新闻

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

1. 从水管网络到最大流&#xff1a;一个核心问题的诞生想象一下&#xff0c;你是一个城市供水系统的总工程师。你的城市有多个水源&#xff08;水库&#xff09;&#xff0c;需要通过一个复杂的地下管道网络&#xff0c;将水输送到各个居民区。每条管道都有其最大通水能力&…

2026/8/2 0:00:38 阅读更多 →
基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

温馨提示&#xff1a;本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;本人主页置顶文章(点我)开头有 CSDN 平台…

2026/8/2 0:00:38 阅读更多 →
MATLAB xcorr函数详解:从互相关原理到四大实战应用

MATLAB xcorr函数详解:从互相关原理到四大实战应用

1. 从一次信号“找茬”说起&#xff1a;为什么我们需要互相关几年前&#xff0c;我在处理一组声学传感器数据时遇到了一个棘手的问题。我有两个麦克风记录了一段相同的音频信号&#xff0c;理论上它们接收到的声音波形应该非常相似&#xff0c;只是由于麦克风位置不同&#xff…

2026/8/2 0:00:38 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速&#xff1a;macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/2 6:34:16 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南&#xff1a;3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗&#xff1f;ncmdump解密工具帮你轻松解决这个困…

2026/8/2 2:47:48 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片&#xff1a;为英语学习 App 打造桌面级学习助手适用平台&#xff1a;HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0&#xff08;API 26 Beta&#xff09;新增了 AgentCard 智能体卡片能力&#xff0c;这是继 HMAF&#xff08;鸿蒙智能体框架&#x…

2026/8/2 0:23:22 阅读更多 →