
简介这是一份面向电子设计竞赛选手与嵌入式控制学习者的自由摆平板控制系统设计文档围绕如何在摆杆摆动过程中保持末端平板水平这一动态控制问题展开。方案以STM32F103VET6为控制核心配合TFT液晶显示、高精度WDD35D4导电塑料角位移传感器与四宏细分驱动器驱动的步进电机通过A/D采样实时获取摆杆与平板角度并闭环调节转向与转角实现硬币相对静止、激光笔命中接收靶等题目要求。文中还完整比较了控制器、角度检测、电机与电源四类模块的备选方案及取舍理由并给出摆架框架、检测系统与控制驱动系统三部分的结构划分。压缩包内为1个docx文档约36KB已积累308人学习下载适合用于课程设计、竞赛复盘或嵌入式动态控制方案参考。1. 需求先立住自由摆平板控制在控制什么、误差窗口有多窄自由摆的控制系统题目念起来一句话做起来是一串连锁反应摆杆靠重力自由摆动末端平板上放一枚硬币要求整个摆动过程硬币不滑落发挥部分还要让平板上的激光笔始终打在接收靶上。控制目标就变成了——摆杆角每变化一度平板都得反向补回去工程上能接受的误差窗口通常只有 ±1.5°再大硬币就开始挪位置了。这套东西适合机电一体化、自动化、嵌入式方向的课程设计和毕业设计因为它把角位移传感器、A/D 采样、步进驱动、机械间隙、闭环控制串成一条完整链路哪一环虚了硬币会当场提醒你。下面按我实际搭的顺序从选型讲到验收。2. 总体架构与选型三层结构、四组方案对比与引脚分配2.1 摆架、检测、驱动三层结构各自负责什么整个系统按物理功能切成三层后面所有代码和接线都挂在这三层上不要混着做。摆架框架层是被控对象本身摆架座、摆杆、轴承、末端电机座平板固定在电机轴上。这一层的机械质量直接决定后面算法的上限——轴承有旷量、平板配重偏心、摆杆刚度不够再好的控制律也压不住抖动通常的做法是先把摆杆摆动一次看自由衰减正常应该平顺衰减如果出现周期性的顿或者异响先修机械再写代码。检测层负责把机械状态变成数字一组 WDD35D4 导电塑料角位移传感器测摆杆角另一组装在平板转轴上测平板相对摆杆的转角两路信号经分压后进 STM32 的 A/D采样值经过滤波和标定换算成角度值。驱动层是执行端STM32 输出脉冲和方向信号经四宏细分驱动器放大后带动步进电机电机轴直接或经一级减速带动平板转动。电源从 12V 电池进来一路走 LM2576 开关降压供大电流负载一路走 L7805 线性稳压供传感器和显示再经 3.3V LDO 给主控。层级组成交付物常见失误摆架框架底座、摆杆、轴承、电机座、平板自由摆动周期、机械零点配重偏心导致静差检测系统WDD35D4 × 2、分压网络、RC 滤波角度值度、采样率采样窗口太短读数跳控制驱动STM32、四宏驱动器、步进电机步数指令、转向细分与电流档位不匹配这个分层的价值在于排查硬币掉了先看角度显示准不准检测层再看电机听不听话驱动层最后才怀疑算法。2.2 四组方案的取舍主控、传感器、执行器、电源主控51 还是 STM32。51 便宜、资料多但运算速度慢、片内资源少跑两路 A/D 加滤波加闭环再加液晶刷新会很吃力。选 STM32F103VET6 的理由很实际Cortex-M3 内核主频够用库函数开发门槛低片内多通道 ADC 配合 DMA 可以直接把采样搬进内存不占 CPU功耗也低。有个细节要澄清——不少资料写它8 通道 10 位 ADC实际 F103 系列是 12 位逐次逼近型配置时按 12 位写需要粗分辨率就右移取高位别被这句话带偏把精度白白丢掉。角度检测电位器、ADXL345 还是 WDD35D4。普通电位器线性度差角度误差太大压不住 ±1.5° 的窗口ADXL345 是基于重力加速度分量算倾角静态测倾没问题但自由摆是动态过程摆杆的切向加速度会直接污染读数摆得越快错得越离谱。WDD35D4 是导电塑料角位移传感器本质是精密电位器输出与转角成线性关系的电阻精度高、响应快、不怕动态加速度代价是需要一个稳定的激励电压和一次认真的标定。执行器伺服还是步进。伺服性能好、能高速制动、惯量小但价格高对课设/毕设预算不友好。步进电机脉冲驱动、开环定位精度够用配合 16 细分能明显减弱低频振动控制逻辑简单。代价是丢步不可自察所以必须靠角度传感器构成半闭环来兜底。电源铅酸直供还是多级变换。铅酸电池电流大但太重整机结构会变笨。最终走 12V 电池 多级变换大电流支路用 LM2576 开关降压效率高、发热小传感器激励和运放用 L7805 线性稳压纹波小、噪声低。这里别图省事全用线性稳压12V 降到 5V 压差 7V几百毫安就是一两瓦的发热夏天能把板子烤到烫手。对比项方案 A方案 B方案 C选择主控51 单片机STM32F103VET6—B角度检测普通电位器ADXL345WDD35D4C执行器伺服电机步进电机 细分驱动—B电源铅酸直供12V L7805/LM2576 多级变换—B2.3 外设资源分配与系统初始化骨架选型定下来之后第一件事是分引脚分完再画板、再写代码避免中途改线。下面这份分配表可以照着改具体以手里板子的实际丝印为准。功能外设资源引脚说明摆杆角采样ADC1_IN0PA0WDD35D4 分压输出平板角采样ADC1_IN1PA1同上电池电压检测ADC1_IN2PA212V 经电阻分压到 3.3V 内步进脉冲 STEPTIM1_CH1PA8每周期翻转一次产生一个脉冲步进方向 DIRGPIO 推挽PB0高电平正转驱动器使能 ENAGPIO 推挽PB1低有效上电先拉高再释放TFT 液晶SPI1PA5/PA6/PA7片选 PA4仅刷数字区域调试串口USART1PA9/PA10上位机看角度曲线初始化顺序有讲究先时钟、再 GPIO、再 ADC 校准、最后开定时器。ADC 校准必须在使能转换之前做否则前几十次采样值整体偏移很多人以为是传感器坏了。/* 系统启动骨架顺序不能乱尤其 ADC 校准要在启动转换之前 */ int main(void) { SystemInit(); /* 72MHz 主频 */ Delay_Init(); /* SysTick 延时基准 */ GPIO_Config(); /* DIR / ENA / LED / 按键 */ USART1_Config(115200); /* 调试串口 */ TFT_Init(); /* 液晶屏先清屏再画框架 */ AngleAdc_Init(); /* 双通道 ADC DMA内部含校准 */ Stepper_Init(); /* TIM1 脉冲定时器先不使能 */ Stepper_Enable(1); /* 释放驱动器电机抱死 */ LCD_DrawFrame(); /* 静态框架只画一次后面只刷数字 */ while (1) { Control_Loop(); /* 5ms 周期控制 */ if (g_lcd_cnt 20) { /* 100ms 刷一次显示别每周期刷 */ g_lcd_cnt 0; LCD_Refresh(); } Delay_ms(5); } }这里有个容易被忽略的点液晶刷新和控制在同一个循环里如果每个控制周期都刷屏SPI 写屏的时间会把控制周期拉长到几十毫秒摆杆动得快的时候补偿就跟不上了。显示只刷变化的数字区域静态框架上电画一次控制周期才能稳住。2.4 控制周期与时间预算控制周期定 5ms对应 200Hz。这个数字不是拍脑袋自由摆的摆动周期一般在 1~2 秒量级按 200Hz 采样一个周期内有几百个采样点相位滞后可以接受再快也没意义因为步进电机的响应跟不到那么细。时间预算要算清楚5ms 里两路 ADC 转换耗时12 位、239.5 周期采样时间单次约 21μs两通道约 42μs可以忽略中值滤波 8 点排序加角度解算大约几十微秒剩下的几乎全留给脉冲输出和液晶。所以液晶必须降频到 100ms串口打印更要压缩调试时只在需要的时候打一次。3. 角度检测与信号链WDD35D4 从分压到角度值的完整换算3.1 接线与分压网络别把 5V 输出直接怼进 3.3V 的 ADCWDD35D4 是三线制两端接激励电压中间抽头输出电压。抽头电压与转角在一定电气角范围内成线性关系。接线要遵守两条第一激励电压必须是稳定的基准不能直接拿电机电源或者电池裸电压当激励。电池从 12.6V 掉到 11V分压比跟着变角度读数就整体漂这属于典型的上电准、跑一会儿不准。第二抽头输出幅度必须落在 0~3.3V 之内。如果激励用 5V满量程输出接近 5V直接进 STM32 的 ADC 会打坏输入保护二极管。通常的做法是激励也用 3.3V或者在抽头后面加一级电阻分压把幅度压到 3.0V 以内再用电压跟随器做阻抗缓冲。传感器输出阻抗不低几 kΩ 量级后面直接接 ADC 采样电容等效就是 RC 充电。所以抽头到 ADC 之间串 1kΩ、对地并 0.1μF构成截止频率约 1.6kHz 的低通既能滤掉电机干扰又不至于把动态信号拖慢。提示分压电阻用 1% 金属膜两个通道用同一批次的电阻否则两路的角度斜率不一致后面对比摆杆角和平板角时会出现固定偏差。3.2 ADC 采样配置与 DMA 双通道循环搬运两路角度必须同步采样否则算绝对倾角 摆杆角 平板相对角时两个角来自不同时刻误差会直接进闭环。用 ADC1 的扫描模式加 DMA 循环搬运两通道在同一个转换序列里连续转完时间差只有二十几微秒可以认为同步。/* 双通道 ADC1 规则组 DMA1 循环搬运CH0 摆杆角CH1 平板角 */ #define ANG_ADC_CH_NUM 2 static volatile uint16_t adc_raw[ANG_ADC_CH_NUM]; void AngleAdc_Init(void) { GPIO_InitTypeDef gpio; ADC_InitTypeDef adc; DMA_InitTypeDef dma; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_ADC1, ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); /* 模拟输入模式禁止上下拉否则外部下拉会把分压比带偏 */ gpio.GPIO_Pin GPIO_Pin_0 | GPIO_Pin_1; gpio.GPIO_Mode GPIO_Mode_AIN; GPIO_Init(GPIOA, gpio); DMA_DeInit(DMA1_Channel1); dma.DMA_PeripheralBaseAddr (uint32_t)ADC1-DR; dma.DMA_MemoryBaseAddr (uint32_t)adc_raw; dma.DMA_DIR DMA_DIR_PeripheralSRC; dma.DMA_BufferSize ANG_ADC_CH_NUM; dma.DMA_PeripheralInc DMA_PeripheralInc_Disable; dma.DMA_MemoryInc DMA_MemoryInc_Enable; dma.DMA_PeripheralDataSize DMA_PeripheralDataSize_HalfWord; dma.DMA_MemoryDataSize DMA_MemoryDataSize_HalfWord; dma.DMA_Mode DMA_Mode_Circular; /* 循环模式CPU 随时取最新值 */ DMA_Init(DMA1_Channel1, dma); DMA_Cmd(DMA1_Channel1, ENABLE); ADC_DeInit(ADC1); adc.ADC_Mode ADC_Mode_Independent; adc.ADC_ScanConvMode ENABLE; /* 双通道扫描 */ adc.ADC_ContinuousConvMode ENABLE; /* 连续转换DMA 自己搬 */ adc.ADC_ExternalTrigConv ADC_ExternalTrigConv_None; adc.ADC_DataAlign ADC_DataAlign_Right; adc.ADC_NbrOfChannel ANG_ADC_CH_NUM; ADC_Init(ADC1, adc); /* 传感器输出阻抗高采样窗口取最长档短窗口必然读不准 */ ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_239Cycles5); ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_239Cycles5); ADC_DMACmd(ADC1, ENABLE); ADC_Cmd(ADC1, ENABLE); /* 上电校准必须在使能转换之前完成否则前若干次采样整体偏移 */ ADC_ResetCalibration(ADC1); while (ADC_GetResetCalibrationStatus(ADC1)); ADC_StartCalibration(ADC1); while (ADC_GetCalibrationStatus(ADC1)); ADC_SoftwareStartConvCmd(ADC1, ENABLE); }采样时间选 239.5 周期不是随手写的ADC 时钟按 12MHz 算一次转换约 (239.512.5)/12MHz ≈ 21μs两通道 42μs相对 5ms 控制周期占比不到 1%。有人为了提高采样率把它改成 1.5 周期结果读数随电机转速乱跳原因就是采样电容还没充到传感器输出电压就关门采样了。3.3 中值滤波、两点标定与角度解算从 ADC 值到角度值要做两件事去野值、建映射。去野值用中值滤波而不是简单平均。电机换向、驱动器斩波会在模拟通道上打出一两个明显偏离的采样点平均值会把这颗老鼠屎摊到整个结果里中值滤波直接把它筛掉。/* 8 点采样排序后取中间 4 点平均既滤脉冲干扰又保留一点平滑 */ static uint16_t Median4(uint16_t *buf, uint8_t n) { uint8_t i, j; uint16_t tmp; for (i 0; i n - 1; i) { /* 冒泡排序n 只有 8开销可忽略 */ for (j 0; j n - 1 - i; j) { if (buf[j] buf[j 1]) { tmp buf[j]; buf[j] buf[j 1]; buf[j 1] tmp; } } } return (uint16_t)((buf[2] buf[3] buf[4] buf[5]) 2); }标定用两点法把机构装好、传感器装好之后再标不要在台面上拿手转着标——装上去之后机械零位就变了。做法是把平板摆到两个已知角度比如 -30° 和 30°用量角器或者水平仪确认分别记录 ADC 值解出斜率和截距。typedef struct { float k; /* 斜率度 / LSB */ float b; /* 截距度 */ float limit_l; /* 机械下限防算出离谱值 */ float limit_h; /* 机械上限 */ } AngleCal_t; static AngleCal_t cal_rod {0.0f, 0.0f, -70.0f, 70.0f}; static AngleCal_t cal_plate {0.0f, 0.0f, -95.0f, 95.0f}; /* 两点标定adc_a/adc_b 是实测 ADC 均值deg_a/deg_b 是对应角度 */ void AngleCal_TwoPoint(AngleCal_t *cal, float adc_a, float deg_a, float adc_b, float deg_b) { cal-k (deg_b - deg_a) / (adc_b - adc_a); cal-b deg_a - cal-k * adc_a; } float Angle_Read(const AngleCal_t *cal, uint16_t raw) { float deg cal-k * (float)raw cal-b; if (deg cal-limit_l) deg cal-limit_l; if (deg cal-limit_h) deg cal-limit_h; return deg; }截距的意义是把机械水平和电信号零点对齐。这两个零点通常不重合传感器装上去必然带几度的安装偏差靠标定吃掉它比在结构上硬调省事得多。斜率的意义是分辨率12 位 ADC、3.3V 基准、传感器电气角 340° 左右理论上每 LSB 约 0.08°比步进电机 16 细分后的 0.1125°/步还细够用。3.4 为什么必须装两个传感器摆杆角和平板角的物理关系这是整套设计里最容易想错的地方。平板转轴上那组传感器测的是平板相对摆杆的转角不是平板相对水平面的倾角。摆杆自己也在转所以平板的绝对倾角等于两者之和绝对倾角 摆杆角 平板相对角题目要求的平板始终保持水平翻译成控制目标就是不管摆杆转到哪让绝对倾角等于 0也就是平板相对角要等于负的摆杆角。发挥部分要求激光打靶靶点位置由绝对倾角决定目标就变成让绝对倾角等于某个固定值。如果只装一组传感器只测平板相对角把目标设成 0看起来平板水平了实际上它只是相对摆杆水平摆杆一歪硬币立刻滑。这是我在调试阶段见过的翻车现场里最典型的一个显示一切正常硬币每次都在摆到最高点时掉下去。4. 执行机构与驱动四宏细分驱动器、脉冲发生与位置环落地4.1 驱动器接线、细分与电流档位四宏细分驱动器一般有六根控制端子PUL、PUL-、DIR、DIR-、ENA、ENA-加上四根电机相线。STM32 是 3.3V 电平直接把脉冲脚接 PUL、PUL- 接单片机地驱动器内部光耦就能正常导通如果现场干扰大脉冲和方向都加一级高速光耦隔离代价是延迟增加几微秒对 2kHz 以内的脉冲完全无影响。细分档位通过拨码设置档位和单步角度的对应关系如下按 1.8° 两相混合式步进电机算细分档位每转脉冲数单步角度适用场景整步2001.8°只做粗定位噪声大半步4000.9°低成本场合4 细分8000.45°中速跟踪8 细分16000.225°常用档位16 细分32000.1125°本项目选择选 16 细分是为了压低频振动——步进电机整步运行在低速段会有明显的咯噔感这个振动会通过摆杆传到传感器上被当成角度波动采进来形成自激。但细分不是越高越好细分越高单脉冲转矩越小电流档位如果还按整步的设电机就会出现听着在转、实际没动的丢步。电流档位按电机铭牌额定电流设宁可比额定略高一档别低。4.2 脉冲发生与梯形加减速脉冲用定时器更新中断翻转 IO 产生比 PWM 方式更灵活因为频率要随剩余步数动态改。定时器预分频到 1MHz 计数ARR 决定脉冲频率ARR499 对应 2kHz约 225°/sARR1999 对应 500Hz约 56°/s作为起步频率。/* TIM2 更新中断每次中断翻转 STEP 引脚ARR 决定当前转速 */ static volatile int32_t step_remain 0; /* 剩余脉冲数正为正向负为反向 */ #define STEP_ARR_FAST 499 /* 高速档约 2kHz */ #define STEP_ARR_SLOW 1999 /* 起步/到位档约 500Hz */ void TIM2_IRQHandler(void) { if (TIM_GetITStatus(TIM2, TIM_IT_Update) ! RESET) { TIM_ClearITPendingBit(TIM2, TIM_IT_Update); if (step_remain 0) { /* 走完就关定时器避免空转发热 */ TIM_Cmd(TIM2, DISABLE); return; } /* 翻转 STEP 引脚一个完整脉冲需要一个高电平加一个低电平 */ GPIO_WriteBit(GPIOA, GPIO_Pin_8, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_8))); if (step_remain 0) step_remain--; else step_remain; /* 简化的梯形策略剩余步数多时提速快到位时降速防止冲过头 */ int32_t abs_remain (step_remain 0) ? step_remain : -step_remain; TIM_SetAutoreload(TIM2, (abs_remain 40) ? STEP_ARR_FAST : STEP_ARR_SLOW); } } /* 上层调用设定方向后启动脉冲非阻塞主循环继续跑 */ void Stepper_Move(int32_t steps) { if (steps 0) return; if (steps 0) GPIO_ResetBits(GPIOB, GPIO_Pin_0); /* DIR 低 正向 */ else GPIO_SetBits(GPIOB, GPIO_Pin_0); TIM_Cmd(TIM2, DISABLE); step_remain (steps 0) ? steps : -steps; TIM_SetAutoreload(TIM2, STEP_ARR_SLOW); /* 一律从慢速起步 */ TIM_SetCounter(TIM2, 0); TIM_Cmd(TIM2, ENABLE); }这段代码的关键在非阻塞三个字设定好剩余步数就返回主循环不用等电机走完5ms 后继续算下一个控制量。如果改成死等走完控制周期会被拉长到几十毫秒摆动过程中补偿就跟不上了。方向脚在启动前设好因为 DIR 信号需要提前脉冲至少几微秒建立中途切换方向容易丢步。4.3 从角度误差到步数的位置环步进电机本身是开环的但有了角度传感器就有了反馈构成一个半闭环位置环。最简的形式是比例控制每个控制周期读一次绝对倾角算出和目标角的误差乘以系数换成步数下发给电机。系数怎么定16 细分下平板直连时每步 0.1125°也就是 1° 误差对应约 8.9 步。如果中间加了 1:3 减速带平板转 1° 电机要转 3°系数就是 26.7。#define PLATE_KP 8.9f /* 步/度直连时约 1/0.1125有减速比要乘 */ #define PLATE_DEAD_ZONE_DEG 0.15f /* 死区小于它不动防止来回点头 */ #define STEP_MAX_PER_CYCLE 10 /* 单周期限幅 5ms × 2kHz */ /* 输入绝对倾角与目标绝对倾角输出本周期要走的步数带方向 */ int32_t Plate_ControlOnce(float abs_plate_deg, float target_deg) { float err target_deg - abs_plate_deg; /* 死区误差极小时不动作机械回差会让它反复来回 */ if (err -PLATE_DEAD_ZONE_DEG err PLATE_DEAD_ZONE_DEG) return 0; int32_t steps (int32_t)(err * PLATE_KP); /* 限幅一个周期内电机最多能走的步数超了也发不出去 */ if (steps STEP_MAX_PER_CYCLE) steps STEP_MAX_PER_CYCLE; if (steps -STEP_MAX_PER_CYCLE) steps -STEP_MAX_PER_CYCLE; return steps; }限幅值不是随便填的控制周期 5ms脉冲频率上限 2kHz5ms 内最多只能发 10 个脉冲所以单周期步数上限就是 10。很多人把 Kp 调得很大算出几十步程序里又照发不误结果定时器队列积压电机一直走停走停看起来像卡顿其实是限幅没做。4.4 软限位、回零与机械回差补偿步进电机是开环的一旦丢步位置就永久偏了所以必须有兜底软限位——角度超出机械安全范围时立即停脉冲并反向。这个判断放在控制周期里比放在中断里安全。回零——上电时先朝一个方向慢速转撞到机械挡块或者触发光电开关就停把当前位置记为零点再反向退回一个小角度。没有回零流程的系统每次上电零点都不一样标定参数就白标了。回差补偿——齿轮或联轴器有间隙正向到位和反向到位差那么一两度。通常的做法是恒定单向逼近无论目标在上还是在下都先多走 2~3 步再反向退回来让齿面始终在同一侧接触。这个技巧很土但极其有效能把到位抖动压掉一大半。5. 常见问题排查采样跳变、电机丢步与到位抖动的五类现场故障5.1 角度读数在静止时上下跳 ±2°现象摆杆不动液晶上的角度值在 ±2° 范围内乱跳电机跟着小幅度来回修正。原因三个常见来源——采样时间设得太短ADC 采样电容没充满、传感器输出没有阻抗缓冲几 kΩ 的输出阻抗直接驱动采样保持电路、模拟地和数字地混在一起电机电流在地线上的压降被采进来了。解决采样时间改到 239.5 周期抽头后加电压跟随器或者至少串 1kΩ 并 0.1μF模拟地单独走一根线回电源地别和电机地共用一段铜皮软件上 8 点中值加均值再上一道。5.2 电机一转角度读数就漂现象电机静止时读数是稳的一旦开始走脉冲角度值立刻抖而且抖的幅度跟转速相关。原因脉冲信号线和传感器信号线捆在一起走驱动器斩波产生的高频干扰通过线间电容耦合进模拟通道或者驱动器与主控共地但接地点选在驱动器侧地电流绕了一大圈回到单片机。解决脉冲线、电机相线走一侧传感器线走另一侧交叉处垂直过脉冲和方向加光耦隔离模拟部分单独 LDO 供电。做完这三条抖动基本能压到 0.2° 以内。5.3 平板到位后来回点头现象误差已经很小了电机还在走两步退两步平板在原地小幅抖动硬币反而更容易滑。原因死区设得太小或者干脆没设比例系数偏大加上机械回差形成极限环。解决先加 0.1~0.2° 死区再把 Kp 降一档观察最后上单向逼近策略多走 2~3 步再倒退到位让齿面始终单侧接触。这三步按顺序做不要一次性全改否则不知道是哪一步起的作用。注意死区不是越大越好。死区太大平板在小角度摆动时会钝硬币在低幅摆动阶段更容易滑通常 0.15° 是个比较平衡的值具体还要按机械刚性微调。5.4 摆动快的时候电机丢步现象慢速摆动时一切正常摆幅加大后平板明显跟不上角度误差越来越大停下来看位置已经偏了。原因起步频率太高直接从 2kHz 起振电机来不及跟上、细分调得太高但电流档位没同步调大、加减速策略缺失。解决一律从 500Hz 起步剩余步数大于 40 时才切高速档电流档位按电机铭牌额定值设置不要为了省电往低调摆动幅度大的场景把单周期限幅适当放大让电机有足够的行程追赶。5.5 上电后零点每次都不同现象同一台设备第一次上电平板是水平的重启之后角度显示偏了好几度前面标定的参数像失效了一样。原因没有回零流程每次上电电机轴停的位置是随机的或者标定时用的是台面手转的角度装机之后机械零位已经变了。解决加上电回零慢速撞挡块或光电开关把回零位置写进零点变量标定必须在整机装配完成后进行标完把 k、b 两个值写进 Flash掉电不丢如果电池电压波动大激励源别用电池裸电压用 LDO 稳压后的 3.3V。6. 验收与答辩指标复现清单和演示脚本的走位验收这一步评委看的不是你讲了多少控制理论而是几个可复现的动作能不能稳定做出来。我一般会提前准备一张指标表每项都写清测试方法和合格判据现场按表走不临场发挥。验收项测试方法合格判据平板水平保持摆杆从 60° 释放全程记录绝对倾角摆动全程偏差 ≤ ±1.5°硬币实验平板上放一枚硬币连续摆动 10 个周期硬币不滑落、不位移超过 5mm阶跃响应目标角从 0° 跳到 20°记录响应曲线300ms 内进入 ±1° 死区超调 ≤ 3°激光打靶目标点固定在 1m 外读光点位置偏移 ≤ 2cm重复 5 次一致回零一致性连续上电 5 次记录回零后角度读数极差 ≤ 0.5°续航满电连续运行满足演示全程无异常复位答辩的演示顺序很关键别一上来就放大招。先做静态平板在静止状态下设定 0°、15°、-15°让评委看清角度显示和执行的一致性再做慢速小摆幅证明闭环是稳的最后才做满幅摆动加硬币。这个顺序的好处是万一满幅阶段出问题前面的基础分已经拿到了。现场还有两个细节值得提前准备。一是把调试串口接出来用上位机实时画角度曲线评委问你怎么知道误差是多少的时候曲线比嘴说有用得多。二是准备一份失败预案如果硬币掉了别急着捡起来重来先说清掉在哪、为什么掉是限幅不够还是死区偏大然后当场改一个参数重做一次——能当场定位并修好比一次成功更能说明你真的懂这套系统。有次调试我把死区从 0.15° 调到 0.05°想着响应更快结果整个演示过程平板一直在原地小幅抖动硬币在第三次摆动时就滑到边上了台下看着像系统不稳定其实是参数自己给自己挖的坑。从那以后我每次改控制参数都强制走一遍静态—小摆幅—满幅三段验证任何一段不过就不往下走。希望帮到你。本文还有配套的精品资源点击获取