尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
STM32 FOC调试记录:从串口无数据到电机闭环
最近在学习无刷电机的FOC控制硬件平台是STM32F103C8T6MT6701磁编码器SPI接口三相全桥驱动双ADC注入组采样电流上位机用VOFA看波形。程序架构参考了一个开源例程ADC中断里执行FOC核心算法Clarke、Park、PID、SVPWM主循环只做printf和LED闪烁。按照例程移植完之后遇到了两个问题在这里记录一下排查过程。问题一串口发不出数据现象程序烧录后LED正常闪烁说明主循环在跑。但VOFA接收区没有任何数据。试了printf和直接调用HAL_UART_Transmit都收不到。先检查了软件层面fputc函数已重定向到USART2Keil里Use MicroLIB已勾选波特率115200COM口选的COM3硬件TX/RX没接反GND也共地了这些看起来都没问题。然后我把while(1)里改成只发一句最裸的测试HAL_UART_Transmit(huart2, (uint8_t*)HELLO\r\n, 7, 100);HAL_Delay(500);结果还是收不到。我做了什么测试把商家提供的能正常运行的例程和自己的工程做了逐文件对比usart.c里的MX_USART2_UART_Init函数——配置完全一样main.c里的SystemClock_Config——看起来也一样但仔细看SystemClock_Config的最后一行PeriphClkInit.AdcClockSelection RCC_ADCPCLK2_DIV2例程里是RCC_ADCPCLK2_DIV6。打开CubeMX的Clock Configuration看了一下ADC预分频选的是/2ADC时钟显示36MHz而且是红色的查到的资料翻STM32F103的数据手册ADC时钟的最大值是14MHz。36MHz超了2.5倍还多。根因ADC时钟超频导致外设时序紊乱USART2的发送被干扰了。解决在CubeMX里把ADC Prescaler从/2改成/6ADC时钟变成12MHz。重新生成代码编译烧录串口立刻正常了。小结CubeMX里红色的配置项不能忽略它是在提示你配置不合法。ADC超频这种问题表面上看和串口无关但实际上会影响整个芯片的外设时序。问题二程序卡死电机发现象串口通了之后把电流模式加进while(1)结果程序卡在这行之后motor_control_context.type control_type_torque;后面的printf不打印了。同时电机开始发烫——PWM还在输出但FOC中断似乎没有更新占空比。我做了什么测试在case control_type_torque:前后加printfcase control_type_torque:printf(T-start\r\n);lib_torque_control(motor_control_context.torque_norm_d, motor_control_context.torque_norm_q);printf(T-end\r\n);break;结果T-start打印了T-end没打印。说明卡在lib_torque_control里。继续往里加void lib_torque_control(float torque_norm_d, float torque_norm_q){printf(L1\r\n);float d torque_d_loop(torque_norm_d);printf(L2\r\n);float q torque_q_loop(torque_norm_q);printf(L3\r\n);foc_forward(d, q, rotor_logic_angle);printf(L4\r\n);}结果打印了L1、L2、L3L4没打印。说明卡在foc_forward。再往里void foc_forward(float d, float q, float rotor_rad){printf(F1\r\n);float d_u 0, d_v 0, d_w 0;svpwm(rotor_rad, d, q, d_u, d_v, d_w);printf(F2\r\n);set_pwm_duty(d_u, d_v, d_w);printf(F3\r\n);}结果打印了4个F1进入函数、三个变量初始化、svpwm完成第5个F1set_pwm_duty之后没打印。卡在set_pwm_duty函数里。查到的资料打开foc.c发现里面有一个weak版本的set_pwm_dutyvoid set_pwm_duty(float d_u, float d_v, float d_w) __attribute__((weak));void set_pwm_duty(float d_u, float d_v, float d_w){while (1);}而我的main.c里也有一个同名的set_pwm_duty是真正写寄存器的版本。我查了一下__attribute__((weak))的机制它表示这是一个“弱符号”如果链接时发现别处有强符号普通函数就用强符号。如果没有才用这个弱符号。按理说我的main.c里有强符号链接器应该用main.c的版本。但实际上链接器选了foc.c里的weak版本导致程序卡在while(1)。关于weak我的理解作者在foc.c里放一个weak版本的set_pwm_duty我理解是为了解耦foc.c只负责FOC的数学计算不应该关心底层硬件是哪个芯片、哪个定时器。它只需要知道调用set_pwm_duty就能输出PWM就够了。所以foc.c里放一个weak版本的占位函数如果你的工程里有实现就用你的如果没有实现就执行这个占位函数。占位函数写成while(1);是故意的如果忘了实现底层驱动程序会卡死在这里让你立刻发现。** 如果占位函数是空的程序会静默地不输出PWM电机不转但你不知道是哪里出了问题更难查。这个设计思路是对的但在我这里翻车了——链接器选了weak版本而不是强符号。我查了一些资料可能和链接顺序、编译器的weak符号处理有关。删掉foc.c里的weak函数定义只保留一行声明void set_pwm_duty(float d_u, float d_v, float d_w);这样链接器只能去main.c里找实现没有选择余地。重新编译烧录程序不再卡死。小结weak符号的机制虽然灵活但调试时容易让人抓狂——链接器选错版本时不会报错运行时才暴露问题。如果是我自己写代码我会在foc.c里只放声明不放定义让链接器在编译期就报未定义符号第一时间暴露问题。总结这两个问题花了我不少时间记录几点心得1. CubeMX里红色的配置项必须处理。ADC时钟超频这种问题表面看和串口无关实际上会影响整个系统2. 调试时按信号链逐层隔离。从主循环→中断→算法函数→底层驱动一层层加printf定位比瞎猜有效得多。3. weak符号有它的设计意图但调试时要小心。链接器的行为依赖于工具链跨编译器可能不一致。更安全的做法是只声明不定义。后续会继续记录PID调参和VOFA在线整定的过程。
RELATED

相关推荐

xp win7 双系统性能优化实战与面试避坑指南

xp win7 双系统性能优化实战与面试避坑指南

xp win7 双系统性能优化实战与面试避坑指南 别再去啃那些长达百页的微软官方部署文档了,根本抓不住重点,看完就忘。面试时问到 XP 和 Win7 双系统的底层逻辑,90% 的人只能背概念,讲不清引导扇区如何影响性能优化。…

📅 2026/9/23 10:07:06
图解原理:rsd刷机工具源码拆解与避坑指南

图解原理:rsd刷机工具源码拆解与避坑指南

图解原理:rsd刷机工具源码拆解与避坑指南 面试被问原理答不上来?别慌,今天用图解原理把 rsd刷机工具 的核心逻辑讲透。很多开发者觉得底层工具离自己远,直到项目里真遇到设备连接失败、驱动冲突,才意识到不懂底层有多被动。我在掘金技术社区…

📅 2026/9/23 10:07:06
灰度运算:数字图像处理的第一道数学阀门

灰度运算:数字图像处理的第一道数学阀门

1. 这不是“调亮度”的简单操作,而是图像底层逻辑的开关你打开手机相册,滑动“亮度”滑块,画面变亮了——这看起来只是个UI交互。但背后真正发生的事,是整张图像每个像素的灰度值被统一加了一个常数。这个动作,就是灰度…

📅 2026/9/23 10:07:06
MORE NEWS

更多资讯

📰

告别官方文档坑:3行代码手写实现免费图高性能渲染

告别官方文档坑:3行代码手写实现免费图高性能渲染 别再去翻那几百页的官方文档了,抓不住重点还容易看晕。很多团队在加载免费图资源时,性能瓶颈往往不在网络,而在解码与重绘。 手写实现 一个轻量级的图片加载与缓存模块,往往比引入重型框架更高效。…

📰

YOLOv9行人检测实战:遮挡/小目标/低光照场景优化指南

简介:本资源是一套基于YOLOv9的行人识别、检测与计数完整实现方案,面向计算机、人工智能、自动化等专业本科生及研究生,适用于毕业设计、课程实践与科研原型开发。资源提供可直接运行的Python源码、详细分步教程、已训练好的YOLOv9-s模型&…

📰

ThinkPHP5架构深度拆解:从自动加载到中间件的核心机制解析

1. TP5 整体架构设计思路聊 TP5(ThinkPHP 5)之前,我翻了翻以前的项目代码,从 TP3.2 一路用到 TP6,中间确实感慨挺多。TP5 这个版本在 ThinkPHP 家族里算是个分水岭,它不像 TP3 那样靠一大堆函数和 import 机…

📰

C# ONNX实现P2PNet人群计数:密度图+点回归+软聚类全链路解析

简介:本资源是基于C#与ONNX Runtime实现的P2PNet人群检测与计数完整工程,面向具备基础C#开发能力及计算机视觉兴趣的中高级开发者,解决安防监控、客流统计、公共空间人流量分析等实际场景中的密集人群定位与精准计数问题。压缩包共77个文件&a…

📰

ETTh1时间序列预测实战:LSTM、Transformer与线性模型全链路复现

简介:本资源是一套面向计算机及相关专业(如人工智能、数据科学、自动化等)在校学生与初阶研究者的ETTh1时间序列预测实践项目,聚焦毕业设计、课程设计与大作业场景,提供LSTM、Transformer及自定义线性模型三种主流方案…

📰

MATLAB随机森林实战:从TreeBagger调参到特征重要性与代码生成

简介:这份资源面向需要在MATLAB环境下实现随机森林算法的开发者与机器学习学习者,提供一套预编译的随机森林Mex独立运行包,可在Windows系统上直接调用,无需依赖MATLAB完整环境即可完成分类与回归预测,适合希望快速部署…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬