第 8 章 STM32 工程实战篇:从零新建工程 + 完整可编译 FOC 工程模板
0. 本章目标本章不讲原理只做可直接落地的工程基于 STM32F103 / F407 通用工程模板时钟、GPIO、PWM、ADC、中断完整配置全套 FOC 代码整合Clark/Park/SVPWM/SMO双闭环 启动 保护 串口调试提供清晰工程结构你只需要改电机参数就能跑1. 硬件平台说明MCUSTM32F103C8T6 / STM32F407IGT6通用兼容PWMTIM1 高级定时器中心对齐3 对互补输出ADCPA0 PA1 双电阻电流采样母线电压PB0驱动芯片IR2104 / DRV8301 / EG2131串口USART1 打印调试信息Id/Iq/theta/speedPWM 频率16kHzARR7200-172MHz2. 工程目录结构标准嵌入式结构Project/ ├─ User/ │ ├─ main.c // 主函数、启动逻辑 │ ├─ foc.c/.h // FOC 主流程 │ ├─ transform.c/.h // Clark Park │ ├─ svpwm.c/.h // SVPWM │ ├─ smo.c/.h // SMO观测器 PLL │ ├─ pid.c/.h // PI控制器 │ └─ current.c/.h // 电流采样、校准 ├─ BSP/ │ ├─ bsp_gpio.c/.h │ ├─ bsp_pwm.c/.h │ ├─ bsp_adc.c/.h │ └─ bsp_uart.c/.h └─ Core/ // 标准库/HAL库文件3. 关键外设配置核心代码3.1 PWM 配置TIM1 中心对齐 死区void PWM_Init(void) { GPIO_InitTypeDef GPIO_InitStruct; TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct; TIM_OCInitTypeDef TIM_OCInitStruct; RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE); // PA8 PA9 PA10 → PWM1/2/3 GPIO_InitStruct.GPIO_Mode GPIO_Mode_AF_PP; GPIO_InitStruct.GPIO_Speed GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_Pin GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10; GPIO_Init(GPIOA, GPIO_InitStruct); // 定时器配置中心对齐模式1 TIM_TimeBaseStruct.TIM_Period 7199; // 16kHz TIM_TimeBaseStruct.TIM_Prescaler 0; TIM_TimeBaseStruct.TIM_ClockDivision 0; TIM_TimeBaseStruct.TIM_CounterMode TIM_CounterMode_CenterAligned1; TIM_TimeBaseInit(TIM1, TIM_TimeBaseStruct); // 通道配置 TIM_OCInitStruct.TIM_OCMode TIM_OCMode_PWM1; TIM_OCInitStruct.TIM_OutputState TIM_OutputState_Enable; TIM_OCInitStruct.TIM_OCPolarity TIM_OCPolarity_High; TIM_OC1Init(TIM1, TIM_OCInitStruct); TIM_OC2Init(TIM1, TIM_OCInitStruct); TIM_OC3Init(TIM1, TIM_OCInitStruct); TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable); TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable); TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable); TIM_ARRPreloadConfig(TIM1, ENABLE); TIM_CtrlPWMOutputs(TIM1, ENABLE); // 主输出使能 TIM_Cmd(TIM1, ENABLE); // 中心对齐中断 TIM_ITConfig(TIM1, TIM_IT_CC1, ENABLE); NVIC_EnableIRQ(TIM1_CC_IRQn); }3.2 ADC 双路同步采样配置void ADC_Init(void) { GPIO_InitTypeDef GPIO_InitStruct; ADC_InitTypeDef ADC_InitStruct; RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA, ENABLE); RCC_ADCCLKConfig(RCC_PCLK2_Div6); GPIO_InitStruct.GPIO_Mode GPIO_Mode_AIN; GPIO_InitStruct.GPIO_Pin GPIO_Pin_0 | GPIO_Pin_1; GPIO_Init(GPIOA, GPIO_InitStruct); ADC_InitStruct.ADC_Mode ADC_Mode_Independent; ADC_InitStruct.ADC_ScanConvMode DISABLE; ADC_InitStruct.ADC_ContinuousConvMode DISABLE; ADC_InitStruct.ADC_ExternalTrigConv ADC_ExternalTrigConv_None; ADC_InitStruct.ADC_DataAlign ADC_DataAlign_Right; ADC_InitStruct.ADC_NbrOfChannel 1; ADC_Init(ADC1, ADC_InitStruct); ADC_Cmd(ADC1, ENABLE); ADC_ResetCalibration(ADC1); while(ADC_GetResetCalibrationStatus(ADC1)); ADC_StartCalibration(ADC1); while(ADC_GetCalibrationStatus(ADC1)); } u16 Get_ADC(u8 ch) { ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5); ADC_SoftwareStartConvCmd(ADC1, ENABLE); while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC)); return ADC_GetConversionValue(ADC1); }4. 全局 FOC 变量定义// 电流 float Iu, Iv, Iw; float Ialpha, Ibeta; float Id, Iq; // 电压 float Vd, Vq; float Valpha, Vbeta; // 角度与速度 float theta; float speed_real; float Iq_ref; // 校准 u16 Offset_U, Offset_V; #define CURRENT_GAIN 0.0025f // PID PID_t PID_Id, PID_Iq, PID_Speed, PLL_PID;5. 电流采样与偏置校准void Current_Calib(void) { u32 sumu 0, sumv 0; for(int i0; i1024; i) { sumu Get_ADC(ADC_Channel_0); sumv Get_ADC(ADC_Channel_1); } Offset_U sumu / 1024; Offset_V sumv / 1024; } void Current_Get(void) { float adcu Get_ADC(ADC_Channel_0); float adcv Get_ADC(ADC_Channel_1); Iu (adcu - Offset_U) * CURRENT_GAIN; Iv (adcv - Offset_V) * CURRENT_GAIN; Iw -Iu - Iv; }6. 完整 FOC 中断函数最重要void TIM1_CC_IRQHandler(void) { if(TIM_GetITStatus(TIM1, TIM_IT_CC1) ! RESET) { TIM_ClearITPendingBit(TIM1, TIM_IT_CC1); // 1. 采样电流 Current_Get(); // 2. Clark Clark(Iu, Iv, Iw, Ialpha, Ibeta); // 3. SMO观测 PLL角度 SMO_Calc(Valpha, Vbeta, Ialpha, Ibeta); PLL_Calc(); theta smo.theta_hat; // 4. Park Park(Ialpha, Ibeta, theta, Id, Iq); // 5. 电流环PI Vd PID_Calc(PID_Id, 0.0f, Id); Vq PID_Calc(PID_Iq, Iq_ref, Iq); // 6. 弱磁控制可选 // WeakField_Calc(); 7. 反Park InvPark(Vd, Vq, theta, Valpha, Vbeta); // 8. SVPWM SVPWM_Calc(Valpha, Vbeta); } }7. 启动流程上电直接运行int main(void) { SystemInit(); PWM_Init(); ADC_Init(); UART1_Init(); // 电流校准 Current_Calib(); // PID参数初始化 PID_Init(PID_Id, 2.0f, 0.1f, 0, 10, -10); PID_Init(PID_Iq, 2.0f, 0.1f, 0, 10, -10); PID_Init(PID_Speed, 0.5f, 0.05f,0, 5, -5); PID_Init(PLL_PID, 10.0f, 20.0f,0, 100,-100); // SMO参数 smo.Rs 0.5f; smo.Ls 0.001f; smo.Ts 1.0f/16000.0f; smo.K_smo 0.1f; // 开环拖动 OpenLoop_Drag(); // 主循环 while(1) { if(flag_1ms) { flag_1ms 0; // 速度环 speed_real smo.omega_hat / (2*PI) * 60.0f; Iq_ref PID_Calc(PID_Speed, 2000.0f, speed_real); } // 串口打印调试 printf(Id%.2f, Iq%.2f, speed%.1f\r\n, Id, Iq, speed_real); } }8. 开环拖动 I/F 启动void OpenLoop_Drag(void) { float open_theta 0; int cnt 0; while(cnt 3000) // 拖动约300ms { open_theta 0.005f; if(open_theta 2*PI) open_theta - 2*PI; // 固定Iq开环 Vq 0.5f; Vd 0; InvPark(Vd, Vq, open_theta, Valpha, Vbeta); SVPWM_Calc(Valpha, Vbeta); cnt; Delay_ms(1); } }9. 工程使用说明一步一步跑起来新建 Keil 工程选择对应 MCU添加上述所有 .c 文件根据实际电机修改smo.Rs相电阻smo.Ls相电感CURRENT_GAIN采样放大倍数PWM 频率 ARR下载程序串口看打印Id、Iq、speed 稳定无跳变电机应启动顺滑运行安静调速线性10. 常见调试问题电机抖动不转电流方向反 → Iu -Iu角度方向反 → theta -theta发热大PID 参数过大电流采样不准低速啸叫SMO 增益不合理PLL 参数不对高速上不去未开弱磁母线电压不足

相关新闻

免费游戏汉化工具实测:不会外语,也能轻松玩通全世界的游戏

免费游戏汉化工具实测:不会外语,也能轻松玩通全世界的游戏

免费游戏汉化工具实测:不会外语,也能轻松玩通全世界的游戏 【免费下载链接】LunaTranslator 视觉小说翻译器 / Visual Novel Translator 项目地址: https://gitcode.com/GitHub_Trending/lu/LunaTranslator 为了看懂一款日文 Galgame 的剧情&…

2026/8/20 13:32:48 阅读更多 →
中小企业AI落地:不花一分钱软件授权费,也能拥有专属AI能力

中小企业AI落地:不花一分钱软件授权费,也能拥有专属AI能力

中小企业AI落地:不花一分钱软件授权费,也能拥有专属AI能力212亿市场、54%企业已部署AI、开源方案软件授权费为0——中小企业AI化,现在是最好的时机你是不是也有这种感觉—— 听说过AI很强大,但不知道能帮你解决什么具体问题&#…

2026/8/20 13:32:48 阅读更多 →
9、驱动性能分析与优化--性能数据采集与分析

9、驱动性能分析与优化--性能数据采集与分析

9.1 三种核心采集方法 性能数据采集,业界主流就三招:采样法、追踪法、计数法。各有各的脾气,用对了地方就是神器。 9.1.1 采样法(Sampling) 采样法,说白了就是隔一段时间看一眼CPU在干嘛。比如每秒采样100次,记录当前执行的函数地址。最后统计每个函数出现的次数,就…

2026/8/20 13:32:48 阅读更多 →

最新新闻

JavaCEF跨平台开发实战:三平台浏览器嵌入构建部署终极指南

JavaCEF跨平台开发实战:三平台浏览器嵌入构建部署终极指南

JavaCEF跨平台开发实战:三平台浏览器嵌入构建部署终极指南 【免费下载链接】java-cef Java Chromium Embedded Framework (JCEF). A simple framework for embedding Chromium-based browsers in other applications using the Java programming language. 项目地…

2026/8/21 16:14:28 阅读更多 →
RVC语音变声完整指南:用10分钟语音数据训练专属AI音色的全流程实战

RVC语音变声完整指南:用10分钟语音数据训练专属AI音色的全流程实战

RVC语音变声完整指南&#xff1a;用10分钟语音数据训练专属AI音色的全流程实战 【免费下载链接】Retrieval-based-Voice-Conversion-WebUI Easily train a good VC model with voice data < 10 mins! 项目地址: https://gitcode.com/GitHub_Trending/re/Retrieval-based-V…

2026/8/21 16:14:28 阅读更多 →
如何用AMA Protocol浏览器查询交易与区块?5步新手图解指南

如何用AMA Protocol浏览器查询交易与区块?5步新手图解指南

如何用AMA Protocol浏览器查询交易与区块&#xff1f;5步新手图解指南 【免费下载链接】node 项目地址: https://gitcode.com/GitHub_Trending/node95/node 想知道链上的每一笔转账去了哪里、每一个区块里装着什么&#xff1f;这篇 AMA Protocol浏览器&#xff08;Expl…

2026/8/21 16:14:28 阅读更多 →
IDM下载加速不失效:开源脚本冻结试用期的完整实战指南

IDM下载加速不失效:开源脚本冻结试用期的完整实战指南

IDM下载加速不失效&#xff1a;开源脚本冻结试用期的完整实战指南 【免费下载链接】IDM-Activation-Script IDM Activation & Trail Reset Script 项目地址: https://gitcode.com/gh_mirrors/id/IDM-Activation-Script 你的Internet Download Manager&#xff08;ID…

2026/8/21 16:14:28 阅读更多 →
Vespene自助服务自动化:Launch Questions交互式构建面板入门

Vespene自助服务自动化:Launch Questions交互式构建面板入门

Vespene自助服务自动化&#xff1a;Launch Questions交互式构建面板入门 【免费下载链接】_old_vespene DISCONTINUED: a frozen fork will exist forever at mpdehaan/vespene 项目地址: https://gitcode.com/gh_mirrors/ol/_old_vespene Vespene 是一款开源的构建调度…

2026/8/21 16:14:28 阅读更多 →
Crawl4LLM 断点续爬完全指南:中断后如何无缝恢复?

Crawl4LLM 断点续爬完全指南:中断后如何无缝恢复?

Crawl4LLM 断点续爬完全指南&#xff1a;中断后如何无缝恢复&#xff1f; 【免费下载链接】Crawl4LLM Official repository for "Craw4LLM: Efficient Web Crawling for LLM Pretraining" 项目地址: https://gitcode.com/gh_mirrors/cr/Crawl4LLM Crawl4LLM 是…

2026/8/21 16:13:28 阅读更多 →

日新闻

机场边检旅客定位系统国产化白皮书:算法、硬件、底座平台全程自主

机场边检旅客定位系统国产化白皮书:算法、硬件、底座平台全程自主

前言随着国家数字基础设施信创替代、关键技术自主可控战略持续深化&#xff0c;口岸智慧安防、边检智能管控领域正全面进入国产化、自主化、安全可控升级周期。当前国内机场边检旅客识别与定位体系长期依赖国外商用视觉算法、进口成像硬件、闭源通用计算平台&#xff0c;存在核…

2026/8/21 0:00:42 阅读更多 →
别再把“数字孪生”当空间智能了!镜像视界揭开四维时空的真正面纱

别再把“数字孪生”当空间智能了!镜像视界揭开四维时空的真正面纱

别再把“数字孪生”当空间智能了&#xff01;镜像视界揭开四维时空的真正面纱当下数字化建设浪潮中&#xff0c;很多项目将三维可视化、视频贴图叠加的数字孪生等同于空间智能。传统数字孪生更多停留在三维场景复刻&#xff0c;擅长把物理世界“画出来、展示出来”&#xff0c;…

2026/8/21 0:00:42 阅读更多 →
105、车载温度范围-40°C到85°C的影像质量一致性——ISP参数温漂补偿与产线标定策略

105、车载温度范围-40°C到85°C的影像质量一致性——ISP参数温漂补偿与产线标定策略

105、车载温度范围-40C到85C的影像质量一致性——ISP参数温漂补偿与产线标定策略 去年冬天在北方某车厂做A样评审,凌晨四点的黑河试验场,零下三十三度。客户拿了一台冷启动的车,中控屏上倒车影像全是雪花噪点,暗部细节直接糊成一片。我第一反应是sensor温度没上来,暗电流…

2026/8/21 0:00:42 阅读更多 →

周新闻

基于阿里云与通义千问(Qwen)构建AI应用:从模型调用到生产部署的完整实践指南

基于阿里云与通义千问(Qwen)构建AI应用:从模型调用到生产部署的完整实践指南

如果你是一名开发者&#xff0c;最近可能已经感受到了AI大模型正在从“玩具”变成“生产力工具”的强烈信号。从代码补全到智能Agent&#xff0c;从本地部署到云端API&#xff0c;我们正处在一个技术栈快速重构的节点。然而&#xff0c;面对层出不穷的模型、框架和工具&#xf…

2026/8/21 3:21:33 阅读更多 →
工业通信系统底层逻辑:04 反射——高频能量撞墙之后会发生什么?

工业通信系统底层逻辑:04 反射——高频能量撞墙之后会发生什么?

第四篇:反射——高频能量撞墙之后会发生什么? —— 你以为信号已经过去了,其实它正在回来打你 老Q的现场笔记 第五季,我们正式进入工业神经系统层。这里不再是单个设备的战斗,而是整个工厂“经脉”层面的秩序之战。从这一篇开始,你将第一次看清:看似简单的信号传播,背…

2026/8/21 0:02:09 阅读更多 →
【文章复现】非线性值迭代自适应动态规划(ADP):离散时间非线性系统的策略迭代自适应动态规划算法研究附Matlab代码

【文章复现】非线性值迭代自适应动态规划(ADP):离散时间非线性系统的策略迭代自适应动态规划算法研究附Matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。&#x1f34e; 往期回顾关注个人主页&#xff1a;Matlab科研工作室&#x1f447; 关注我领取海量matlab电子书和…

2026/8/21 6:07:56 阅读更多 →

月新闻

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

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

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

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

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

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

2026/8/20 21:46:49 阅读更多 →
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/21 0:14:22 阅读更多 →