STM32驱动MG90S舵机:PWM配置、供电与多路协同实战
1. 从一次“舵机抽搐”说起为什么MG90S值得单独写一篇很多人第一次把MG90S接到STM32上代码烧进去舵机要么纹丝不动要么像得了帕金森一样来回抖要么转到一个角度就“咔咔”响然后发烫。我当年做第一个云台项目时用的就是MG90S配一块常见的STM32开发板结果整整一个下午都在跟这个小小的金属齿轮舵机较劲。后来才发现问题根本不在舵机本身而在于PWM信号的频率、占空比精度、供电能力以及地线处理这四个环节里任何一个没做对MG90S都会用“抽搐”和“发热”来抗议。MG90S是一颗金属齿轮的模拟/数字兼容舵机市面上常见的版本标称扭矩约1.8kg·cm4.8V到2.2kg·cm6V工作电压4.8V到6V转动速度大约0.1秒每60度。它内部有一颗小电机、一套减速齿轮组、一个电位器和一块控制小板。控制小板负责把外部送来的PWM信号解算成目标角度然后驱动电机转动直到电位器反馈的电压与目标角度匹配为止。这个过程是闭环的所以舵机会“自己找位置”而不是像普通电机那样一直转。那为什么标题要强调“STM32”和“MG90S”的组合因为STM32的定时器资源丰富PWM输出精度高理论上非常适合驱动舵机。但恰恰因为STM32太灵活配置项太多新手很容易在时钟树、预分频、自动重装载值这几个地方算错导致输出的PWM频率不是50Hz或者占空比范围不对。MG90S对PWM的要求是周期20ms高电平宽度0.5ms到2.5ms对应0度到180度。这个范围是行业惯例但不同批次的MG90S会有微小差异有的0.4ms就到0度有的2.6ms才到180度。所以如果你直接抄别人的代码可能会出现“角度对不上”或者“一边到不了头”的情况。这篇文章适合谁看如果你正在用STM32做机械臂、云台、小车转向、摄像头俯仰或者任何需要角度控制的场景MG90S大概率是你绕不开的执行器。如果你已经会点灯、会串口但一碰到定时器PWM就头大那这篇内容就是为你准备的。我会从定时器参数计算开始一步步带你算出正确的预分频和重装载值然后给出可以直接复用的代码结构最后把我在实际项目中踩过的坑——包括供电、地线、抖动、发热、多舵机同步——全部摊开来讲。你不需要有很深的嵌入式基础只要知道怎么新建工程、怎么编译下载就能跟着做下来。2. 核心原理拆解MG90S到底在“听”什么2.1 舵机三线制与内部闭环的通俗理解MG90S引出三根线棕色是地GND红色是电源正VCC通常4.8V到6V橙色是信号线PWM输入。很多人以为信号线是“供电线”其实它只负责传递角度指令舵机内部的电机电源来自红色线。信号线的输入阻抗比较高所以STM32的3.3V电平可以直接驱动不需要电平转换。这一点和某些老式舵机不同那些舵机需要5V信号但MG90S的规格书里明确写了信号电压范围是3.0V到5.0V所以3.3V的STM32引脚可以直接连。内部闭环的工作过程可以这样理解控制小板收到PWM信号后先测量高电平持续时间。假设测得1.5ms它就认为目标角度是90度因为0.5ms对应0度2.5ms对应180度线性映射。然后它读取电位器的电压电位器与输出轴机械连接转动角度不同分压不同。控制小板比较目标角度和当前角度如果当前角度小于目标就驱动电机正转如果大于目标就反转如果相等就停止驱动。这个比较和驱动过程一直在循环频率很高所以舵机会持续“微调”以保持位置。这也是为什么舵机在到达目标角度后仍然会发出轻微的“滋滋”声那是电机在极短脉冲下工作以抵抗外力。注意MG90S是模拟舵机还是数字舵机市面上说法不一。严格来说MG90S原厂版本是模拟舵机但很多兼容版本用了数字控制芯片。数字舵机对PWM信号的刷新率要求更高通常需要更高的脉冲频率比如300Hz但MG90S兼容版本仍然标称50Hz。实际使用中50Hz到100Hz都能工作但频率太高会导致舵机内部死区时间不够出现抖动或发热。所以稳妥起见用50Hz。2.2 为什么是50Hz而不是其他频率舵机的PWM周期标准是20ms对应50Hz。这个标准来自早期模拟舵机的设计控制小板需要足够的时间来测量脉冲宽度、比较电位器电压、驱动电机。如果周期太短比如10ms100Hz控制小板可能还没完成一次完整的比较和驱动下一个脉冲就来了导致内部逻辑混乱。如果周期太长比如40ms25Hz舵机会变得“迟钝”因为指令更新慢了而且电机在等待新指令期间可能因为外力而偏移然后下一个脉冲来了又猛追产生抖动。那为什么有些数字舵机可以支持300Hz因为数字舵机的控制芯片处理速度更快而且内部有PID算法可以在更短的周期内完成闭环。但MG90S不是那种高端数字舵机它的控制板比较基础所以老老实实用50Hz最稳。我实测过用100Hz驱动MG90S短时间没问题但连续工作十分钟后舵机温度明显比50Hz时高而且静止时抖动更明显。所以除非你有特殊需求否则不要随意提高频率。2.3 STM32定时器输出PWM的底层逻辑STM32的通用定时器比如TIM2、TIM3、TIM4和高级定时器TIM1、TIM8都可以输出PWM。以TIM3为例它挂载在APB1总线上。假设你的STM32主频是72MHzAPB1预分频器设置为2那么APB1时钟是36MHz但定时器时钟有一个倍频器如果APB1预分频系数不为1定时器时钟就是APB1时钟的2倍也就是72MHz。这个细节非常关键因为很多人算PWM频率时直接用36MHz去算结果输出频率差了一倍。定时器输出PWM的频率公式是PWM频率 定时器时钟 / [(预分频器1) × (自动重装载值1)]我们要50Hz定时器时钟72MHz那么50 72,000,000 / [(PSC1) × (ARR1)]所以(PSC1) × (ARR1) 1,440,000。为了方便计算占空比我们通常让ARR固定为20000-1也就是20000个计数周期。那么PSC1 1,440,000 / 20,000 72所以PSC 71。这样定时器每计数20000次是一个周期每次计数的时间是1/72MHz ≈ 13.89ns20000次就是277.8us不对这里算错了。重新算定时器时钟72MHz预分频器71实际计数时钟是72MHz/(711)1MHz。那么每个计数是1us。ARR20000-1所以周期是20000us20ms频率50Hz。完美。接下来占空比0.5ms高电平对应0度2.5ms对应180度。因为计数时钟是1MHz所以0.5ms对应500个计数2.5ms对应2500个计数。所以CCR捕获比较寄存器的值从500到2500对应0到180度。中间值1.5ms对应1500计数即90度。线性关系CCR 500 (角度/180) × 2000。这个计算过程看起来简单但实际配置时如果你用了HAL库还要注意__HAL_TIM_SET_COMPARE函数的用法以及定时器通道的极性设置。极性不对高电平会变成低电平舵机就完全没反应。3. 手把手实操从零配置TIM3输出50Hz PWM3.1 时钟树与定时器参数确认我以常见的STM32F103C8T6为例外部晶振8MHz系统时钟倍频到72MHz。在CubeMX里配置时先确认RCC里HSE选择Crystal/Ceramic Resonator然后Clock Configuration里把PLL Source选HSEPLL Mul选9倍频得到72MHz。APB1 Prescaler选2这样APB1时钟36MHz但定时器时钟自动倍频到72MHz。这个倍频规则在参考手册的时钟树章节有明确说明如果你不确定可以在CubeMX里把鼠标悬停在APB1定时器时钟上它会显示实际频率。然后配置TIM3Clock Source选Internal ClockChannel1选PWM Generation CH1。Prescaler填71Counter Period填19999auto-reload preload选Enable。Pulse填1500初始1.5ms90度。CH Polarity选High表示高电平有效。其他保持默认。这样生成的代码里MX_TIM3_Init函数会自动计算好寄存器值。如果你用标准库需要手动写TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); TIM_TimeBaseStructure.TIM_Period 19999; TIM_TimeBaseStructure.TIM_Prescaler 71; TIM_TimeBaseStructure.TIM_ClockDivision TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_CounterMode TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, TIM_TimeBaseStructure); TIM_OCInitStructure.TIM_OCMode TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse 1500; TIM_OCInitStructure.TIM_OCPolarity TIM_OCPolarity_High; TIM_OC1Init(TIM3, TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); TIM_ARRPreloadConfig(TIM3, ENABLE); TIM_Cmd(TIM3, ENABLE);这段代码里TIM_Period是ARR的值TIM_Prescaler是PSC的值。注意标准库的TIM_Prescaler直接写71而CubeMX里填71也是同样的效果因为库函数内部会加1。但有些教程里写72那是错误的会导致频率变成49.3Hz左右虽然舵机也能动但精度差一点。3.2 GPIO配置与信号线连接TIM3的通道1默认映射到PA6引脚。在CubeMX里PA6会自动配置为Alternate Function Push-Pull速度选High。如果你用标准库需要手动使能GPIOA时钟配置PA6为复用推挽输出GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Pin GPIO_Pin_6; GPIO_InitStructure.GPIO_Mode GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz; GPIO_Init(GPIOA, GPIO_InitStructure);接线时MG90S的橙色线接PA6红色线接外部5V电源棕色线接外部电源的地同时必须把外部电源的地和STM32的地连在一起。这一点是新手最容易忽略的如果只接信号线和电源线不共地PWM信号就没有参考电平舵机会乱转或者完全不动。我见过有人用USB给STM32供电然后用另一路5V电源给舵机供电但忘记共地结果舵机像疯了一样。共地之后立刻正常。提示不要用STM32开发板上的5V引脚直接给MG90S供电除非你只接一个舵机并且开发板的5V来自USB且电流足够。MG90S堵转电流可以到1A以上USB口通常只能提供500mA多个舵机同时动作会导致电压跌落STM32复位。稳妥做法是单独用一个5V/2A以上的电源模块给舵机供电。3.3 角度控制函数的封装与测试配置好定时器后写一个简单的角度设置函数void MG90S_SetAngle(TIM_TypeDef* TIMx, uint8_t channel, float angle) { if (angle 0) angle 0; if (angle 180) angle 180; uint16_t ccr 500 (uint16_t)(angle / 180.0f * 2000); switch (channel) { case 1: TIM_SetCompare1(TIMx, ccr); break; case 2: TIM_SetCompare2(TIMx, ccr); break; case 3: TIM_SetCompare3(TIMx, ccr); break; case 4: TIM_SetCompare4(TIMx, ccr); break; } }这个函数把角度限制在0到180度然后线性映射到500到2500的CCR值。测试时先调用MG90S_SetAngle(TIM3, 1, 0)舵机应该转到最左边再调用MG90S_SetAngle(TIM3, 1, 180)舵机转到最右边最后调用90度舵机回到中间。如果方向反了比如0度跑到右边180度跑到左边那说明你的舵机安装方向或者机械结构是反的可以在函数里做映射反转或者调整机械装配。如果舵机不动先用示波器或者逻辑分析仪看PA6引脚有没有50Hz的PWM波形。没有波形的话检查定时器是否使能、GPIO是否配置为复用、通道是否使能。有波形但舵机不动检查供电和共地。有波形且供电正常但舵机抖动检查PWM频率是否准确以及电源是否稳定。4. 多舵机协同与供电设计从单路到六足机器人4.1 一个定时器驱动多路舵机的资源分配STM32F103C8T6有4个通用定时器每个定时器最多4个通道理论上可以驱动16路舵机。但实际项目中你不可能把所有定时器都用来输出PWM因为还要留串口、I2C、SPI等外设。常见的做法是用一个定时器驱动4路舵机比如TIM3的CH1到CH4分别接四个MG90S。配置时四个通道共用同一个ARR和PSC所以频率都是50Hz但每个通道的CCR可以独立设置互不影响。代码上只需要在初始化时把四个通道都配置为PWM模式然后封装一个函数根据通道号设置CCR。注意TIM3的CH1和CH2默认在PA6和PA7CH3和CH4默认在PB0和PB1。如果你要同时用这四个通道需要使能GPIOA和GPIOB的时钟并配置对应的引脚为复用推挽。多舵机同时动作时电流需求是叠加的。假设每个MG90S平均工作电流200mA堵转电流1A四个舵机同时堵转就是4A。所以电源必须留足余量。我一般按每个舵机1A来选电源四个舵机就用5V/5A的电源模块。如果空间有限至少也要5V/3A并且避免所有舵机同时堵转。4.2 电源去耦与地线布局的实战经验舵机电机在启动和换向时会产生很大的电流尖峰这些尖峰会在电源线上产生电压波动进而影响STM32的供电。我遇到过的情况是舵机一动STM32就复位串口输出乱码。解决办法是在舵机电源输入端并联一个大电容比如1000uF电解电容和一个小电容0.1uF陶瓷电容大电容提供瞬时电流小电容滤高频噪声。同时STM32的电源引脚也要加0.1uF去耦电容这个在开发板上通常已经有了。地线布局上不要用细长的杜邦线给舵机供电线阻会导致电压跌落。我用过20cm长的杜邦线给MG90S供电舵机转动时电源电压从5V跌到4.2V舵机扭矩明显下降。换成短而粗的线比如22AWG硅胶线后电压跌落只有0.1V。另外舵机的地线和STM32的地线要尽量在电源入口处单点连接避免地环路。如果多个舵机可以采用星型接地每个舵机的地线单独回到电源地而不是串联。注意有些MG90S的棕色线地和红色线电源在插头处是反的不同批次可能不同。接线前一定用万用表测一下或者看舵机标签上的线序说明。接反会瞬间烧毁舵机控制板。4.3 多舵机同步与运动平滑处理多舵机协同动作时如果直接同时设置所有舵机的角度由于舵机内部响应速度不同可能会出现“有的先到、有的后到”的情况机械结构上看起来就是抖动或者卡顿。解决办法是给每个舵机设置一个“目标角度”和“当前角度”然后在定时器中断里以固定时间间隔比如10ms逐步逼近目标角度每次增加或减少1度。这样所有舵机看起来是同步平滑运动的。实现上可以用一个软件定时器或者SysTick中断每10ms调用一次更新函数void MG90S_Update(void) { for (int i 0; i 4; i) { if (current_angle[i] target_angle[i]) { current_angle[i]; } else if (current_angle[i] target_angle[i]) { current_angle[i]--; } MG90S_SetAngle(TIM3, i1, current_angle[i]); } }这个逻辑很简单但效果很明显。舵机不再“跳”到目标角度而是以每秒100度的速度平滑转动。如果你需要更快或更慢调整每次增减的步长或者中断周期即可。注意步长太大比如5度会显得很生硬步长太小比如0.5度需要浮点运算在中断里可能耗时。我一般用整数步长1度中断周期10ms效果很顺滑。5. 常见问题排查与避坑指南5.1 舵机抖动、发热、不动的排查流程遇到MG90S工作异常我一般按以下顺序排查现象可能原因排查方法解决措施完全不动信号线没接对用示波器看信号引脚有无PWM检查GPIO配置和定时器使能完全不动电源没接或电压不足万用表测舵机红棕线间电压换5V/2A以上电源共地抖动PWM频率不对示波器测周期是否为20ms重新计算PSC和ARR抖动电源纹波大示波器看电源纹波并联大电容缩短电源线发热舵机堵转或过载手摸舵机外壳温度减轻负载检查机械卡死发热PWM占空比超出范围测高电平是否在0.5-2.5ms限制CCR在500-2500角度不准舵机个体差异分别测0度和180度的脉宽在代码里做校准偏移多舵机干扰地线环路检查地线连接方式星型接地单点连接这个表格是我在实际项目中总结的基本上覆盖了90%以上的问题。其中“角度不准”需要特别说明MG90S的0度和180度对应的脉宽并不是严格0.5ms和2.5ms有的舵机0.4ms就到0度2.6ms才到180度。如果你发现舵机在0度时还在往左转发出咔咔声说明脉宽太小了需要把最小值调大比如从500调到550。反之如果180度时还在往右转就把最大值调小。校准方法先给一个中间值1.5ms然后慢慢减小脉宽直到舵机刚好停止记录这个值作为0度再慢慢增大直到刚好停止记录为180度。这两个值替换代码里的500和2500。5.2 定时器配置中的隐蔽陷阱第一个陷阱是定时器时钟倍频。前面提过APB1预分频不为1时定时器时钟是APB1的2倍。但如果你用的是STM32F4系列APB1和APB2的定时器时钟规则又不一样。F4系列里如果APB预分频大于1定时器时钟也是APB的2倍但最高不超过系统时钟。所以配置前一定要查对应型号的参考手册时钟树章节不要凭感觉。第二个陷阱是ARR预装载。如果你在运行中动态修改ARR而没有使能ARR预装载新的ARR值会立即生效可能导致当前周期被截断输出一个异常窄的脉冲舵机就会抖一下。所以初始化时一定要调用TIM_ARRPreloadConfig(TIMx, ENABLE)这样ARR的修改会在下一个更新事件生效。第三个陷阱是CCR预装载。同样如果你在运行中频繁修改CCR而没有使能CCR预装载可能会出现竞争条件导致某个周期的高电平时间异常。HAL库默认会处理这个但标准库需要手动调用TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable)。第四个陷阱是通道极性。如果你把极性设成Low那么高电平有效变成低电平有效舵机会把低电平时间当作指令结果完全错乱。所以除非你明确知道自己在做什么否则一律用High。5.3 供电与接地的独家避坑技巧我踩过最惨的一次坑是用一块STM32开发板同时给两个MG90S供电开发板上的5V来自USB。单个舵机测试正常两个舵机一起动的时候STM32就复位。后来用万用表测发现舵机动作瞬间5V电压跌到3.8VSTM32的BOR欠压复位触发了。解决办法很简单把舵机电源从开发板上断开单独接一个5V/2A的电源适配器并且把适配器的地和开发板的地连起来。之后两个舵机同时动作电压只跌到4.9V完全稳定。另一个技巧是在舵机电源线上串联一个肖特基二极管。二极管的正向压降大约0.3V可以防止舵机产生的反向电动势倒灌到电源保护其他电路。但要注意二极管的电流额定值要大于舵机最大电流比如用1N58223A或者SS343A。如果舵机电流更大就用TO-220封装的肖特基二极管。还有不要用面包板给舵机供电。面包板的接触电阻和线阻都很大舵机一动电压就跌。我试过在面包板上接一个MG90S空载转动时电压从5V跌到4.5V带载时直接跌到4V以下。后来直接焊接在洞洞板上问题消失。所以如果你要做稳定项目至少用洞洞板或者PCB不要用面包板。6. 进阶玩法从MG90S到机械臂控制6.1 用串口指令控制舵机角度单机测试时你可以把角度写死在代码里。但实际项目中通常需要上位机或者遥控器发送指令。最简单的做法是用串口接收角度值然后调用MG90S_SetAngle。比如定义一个简单的协议接收三个字节第一个字节是通道号1到4后两个字节是角度值0到180。串口中断里解析后设置目标角度主循环里调用平滑更新函数。void USART1_IRQHandler(void) { if (USART_GetITStatus(USART1, USART_IT_RXNE) ! RESET) { static uint8_t buf[3]; static uint8_t idx 0; buf[idx] USART_ReceiveData(USART1); if (idx 3) { uint8_t ch buf[0]; uint8_t angle buf[1]; if (ch 1 ch 4 angle 180) { target_angle[ch-1] angle; } idx 0; } } }这个协议很简单但足够用。你可以用串口助手发送十六进制数据比如01 5A表示通道1转到90度。注意角度值用一个字节就够了因为0到180在uint8_t范围内。如果你需要更精细的控制可以用两个字节表示0到1800对应0.1度分辨率。6.2 多舵机机械臂的逆运动学入门如果你用多个MG90S搭一个机械臂比如三自由度底座旋转、大臂俯仰、小臂俯仰那就需要根据目标坐标反解出每个舵机的角度。这就是逆运动学。对于简单的平面三自由度机械臂可以用几何法求解。假设底座旋转角度为θ1大臂长度为L1小臂长度为L2目标点在平面内的坐标为(x, y)那么θ1 atan2(y, x)然后计算目标点到原点的距离r sqrt(x² y²)再用余弦定理求大臂和小臂的角度cos(θ2) (L1² r² - L2²) / (2 × L1 × r)θ2 acos(cos(θ2))θ3 acos((L1² L2² - r²) / (2 × L1 × L2))这些角度是弧度需要转换成度然后映射到舵机的0到180度范围。注意舵机的安装方向会影响角度的正负所以实际代码里需要根据机械结构做偏移和反转。我建议先用纸笔画一个侧视图标出每个舵机的零位和转动方向然后再写代码。否则很容易出现“越算越乱”的情况。MG90S的扭矩有限做机械臂时要注意力臂长度。如果大臂太长舵机堵转电流会很大甚至烧毁。我建议单节臂长不超过10cm并且用金属齿轮的MG90S塑料齿轮的版本容易扫齿。如果负载更大可以考虑MG996R或者更高级的舵机但那就是另一个话题了。6.3 用定时器中断实现多路软件PWM如果你的STM32定时器不够用或者需要驱动超过16路舵机可以用软件PWM。思路是用一个定时器产生一个高频中断比如1MHz然后在中断里维护多个计数器和多个GPIO引脚模拟出多路50Hz PWM。这种方法会消耗CPU资源但STM32F103在72MHz下1MHz中断就是每72个时钟周期进一次中断中断服务程序如果写得精简还是能撑住的。不过我不推荐新手这么做因为容易导致其他中断响应延迟。除非你确实需要很多路舵机否则还是用硬件PWM更稳。软件PWM的另一个问题是抖动。因为中断响应有延迟软件PWM的高电平时间会有几十纳秒的抖动对于舵机来说影响不大但对于某些对时序敏感的设备就不行了。所以能用硬件PWM就用硬件PWM这是STM32的强项不要浪费。7. 我的调试心得与最后几句实在话调MG90S这几年我最大的体会是舵机本身很简单复杂的是供电和地线。很多人把时间花在调代码上结果发现是电源功率不够。所以我的建议是拿到舵机后先不要写代码先用一个简单的舵机测试仪或者Arduino跑一下确认舵机本身是好的然后再接到STM32上。如果STM32这边有问题先查供电和共地再查PWM频率和占空比最后查代码逻辑。这个顺序能帮你省下大量时间。另外MG90S的金属齿轮虽然比塑料齿轮耐用但也不是无敌的。如果机械结构卡死舵机会一直堵转电流飙升很快发热甚至烧毁。所以机械装配时一定要留有余量不要让舵机在行程末端硬顶。我通常会在代码里把角度限制在5度到175度避免舵机撞到机械限位。这个小小的改动能显著延长舵机寿命。最后分享一个校准小技巧如果你觉得舵机的中位不准可以在上电后先发送1.5ms脉宽然后观察舵机臂的位置。如果不在正中间可以拆下舵机臂重新安装到正中间位置。这比在代码里加偏移量更直接也更可靠。因为代码偏移只对当前舵机有效换一个舵机又得重新调。机械中位调好了代码里就用标准的500到2500省心很多。这个内容后续还可以这样扩展比如用PID算法让舵机运动更平滑或者用CAN总线控制多个舵机节点或者把舵机反馈电位器的电压读出来做闭环位置检测。但那是更进阶的玩法了对于大多数应用把50Hz PWM打稳、供电做扎实就已经能解决90%的问题。

相关新闻

LIDC肺结节数据解析:从XML标注到深度学习标签生成全指南

LIDC肺结节数据解析:从XML标注到深度学习标签生成全指南

简介:面向肺部CT影像分析与Python开发者的LIDC数据说明与标签资源,用于解决LIDC-IDRI数据集中标注文件格式多样、字段含义不清、难以直接用于建模的问题,适合在肺结节检测、分割以及机器学习项目前期做数据梳理和预处理时参考。压缩包内共有1…

2026/10/12 23:34:28 阅读更多 →
JDK1.8 ArrayList默认容量与扩容机制源码解析

JDK1.8 ArrayList默认容量与扩容机制源码解析

1. 从一个面试翻车现场说起前几年带过一个新人,简历上写着"精通Java集合框架",结果面试官问了一句"ArrayList不指定初始容量的时候,底层数组一开始是多大",他脱口而出"10"。面试官接着问"那第…

2026/10/12 23:33:27 阅读更多 →
C++课设实战:车票预订系统完整设计与实现

C++课设实战:车票预订系统完整设计与实现

1. 项目缘起与整体设计思路1.1 为什么“车票预订系统”是C课设的经典选题做C课程设计,选题这件事本身就挺有讲究。太简单的,比如写个计算器、通讯录,老师看一眼就知道你花了多少功夫;太偏门的,比如搞个编译器前端&…

2026/10/12 23:33:27 阅读更多 →

最新新闻

小白程序员必备:收藏!从零开始掌握 Codex 大模型核心技术

小白程序员必备:收藏!从零开始掌握 Codex 大模型核心技术

本文深入解析 Codex 大模型的六层架构,涵盖模型、Runtime、Context、Tool、Sandbox 和 Environment 的功能与关系。通过分析 Agent Loop 的工作原理,揭示 Token 的计量方式以及 Context Window 与 Memory 的关联。文章还探讨了长任务中出现的“忘记”现象…

2026/10/13 3:18:47 阅读更多 →
小白程序员也能逆袭!75天零基础拿下字节大模型Agent实习Offer,附学习路线+面试秘籍

小白程序员也能逆袭!75天零基础拿下字节大模型Agent实习Offer,附学习路线+面试秘籍

本文分享作者从零基础转行大模型Agent方向的75天经验,涵盖LLM基础学习、Agent框架掌握、项目实战和面试技巧。强调Agent方向的优势和字节等大厂的招聘需求,提供详细学习时间线和核心知识点清单。 双非硕从零转行大模型Agent方向,75天拿下字节…

2026/10/13 3:18:47 阅读更多 →
标准引领,信任赋能:SGS以权威认证审核铸就高质量发展基石

标准引领,信任赋能:SGS以权威认证审核铸就高质量发展基石

在全球化竞争日益激烈、监管要求日趋严格的今天,“认证”已成为企业进入市场的“通行证”、赢得客户信任的“信用证”以及实现可持续发展的“导航仪”。作为国际公认的测试、检验和认证机构,SGS凭借其跨越145年的卓越经验与瑞士公司特有的精准度&#xf…

2026/10/13 3:18:47 阅读更多 →
31岁在职备考软考高项经验分享:白天上班夜里刷题,二战三科50+的逆袭之路

31岁在职备考软考高项经验分享:白天上班夜里刷题,二战三科50+的逆袭之路

我31岁,做项目管理,白天上班,晚上等孩子睡了才能翻开书。第一次考高项,案例38分,没过。第二次调整方法,案例52分,三科一次过。 在职备考最大的痛就三个:时间碎、资料乱、案例论文不会…

2026/10/13 3:18:47 阅读更多 →
SpringBoot+Vue小区购物系统毕设:从架构设计到部署答辩全攻略

SpringBoot+Vue小区购物系统毕设:从架构设计到部署答辩全攻略

直接说结论:这个题目选得聪明。SpringBoot Vue 是目前 Java Web 方向使用频率最高的前后端分离组合,而"小区购物系统"又是一个业务逻辑非常完整、功能边界清晰的场景——有用户、有商品、有订单、有配送、有权限管理。对毕设来说,…

2026/10/13 3:18:47 阅读更多 →
小白程序员必备:从概念到实践,打造你的第一个 Agent 系统

小白程序员必备:从概念到实践,打造你的第一个 Agent 系统

本文深入浅出地介绍了 Agent 系统的概念、运行机制以及如何将其转化为可靠的系统。通过实际案例分析,详细阐述了 Agent Loop 的运行过程,以及模型、Runtime 和工具在其中的角色和职责。文章还探讨了如何避免 Agent 原地打转的问题,并简要介绍…

2026/10/13 3:17:47 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →