Skip to content

Repository files navigation

FOC标准库_手写

STM32F103VET6 无刷电机 FOC 控制工程(标准外设库,手写实现)

一、工程概述

项目 配置
芯片 STM32F103VET6 (HD, LQFP100)
外部晶振 HSE = 8MHz
系统时钟 SYSCLK = 72MHz (APB1=36MHz, APB2=72MHz)
开发环境 Keil v5 (ARMCC V5.06)
外设库 STM32 Standard Peripheral Library V3.5
调试器 CMSIS-DAP
驱动板 LKS560 栅极驱动器 EVB 板
波形调试 VOFA+ (JustFloat 协议, 115200bps)
版本管理 Git

当前阶段:SVPWM 开环控制已实现,电机可启转运行。


二、PWM 架构 — TIM1 上管 + TIM8 下管

三相半桥由两组高级定时器独立驱动:

上管(高边) 下管(低边)
A相 TIM1_CH1 → PE9 TIM8_CH1 → PC6
B相 TIM1_CH2 → PE11 TIM8_CH2 → PC7
C相 TIM1_CH3 → PE13 TIM8_CH3 → PC8

定时器配置:

  • 模式:中心对齐模式1(仅下溢产生更新中断)
  • PWM 频率:20kHz
  • ARR:1799(72MHz / (2 × 20kHz) - 1)
  • PSC:0(72MHz 不分频)
  • 启动方式:TIM_Cmd() 同时使能 TIM1 和 TIM8
  • 死区方式:软件偏移 CCR(无硬件死区)
  • NVIC 分组:NVIC_PriorityGroup_2
  • 中断优先级:抢占1 / 子0(TIM1 与 TIM8 相同)

三、目录结构

FOC标准库_手写/
├── Doc/
│   └── readme.txt            ← 详细技术文档
├── Libraries/
│   ├── CMSIS/                ← Cortex-M3 内核 + 启动文件
│   │   ├── core_cm3.c/h
│   │   ├── stm32f10x.h
│   │   ├── system_stm32f10x.c/h
│   │   └── startup/          ← startup_stm32f10x_hd.s
│   └── FWlib/                ← STM32 标准外设库 V3.5
│       ├── inc/              ← 库头文件
│       └── src/              ← 库源文件
├── Project/
│   └── RVMDK(uv5)/
│       └── BH-STM32.uvprojx ← Keil 工程文件
├── User/
│   ├── main.c               ← 主程序(SVPWM 开环测试入口)
│   ├── bsp_pwm.c/h          ← PWM 驱动 (TIM1上管 + TIM8下管)
│   ├── FOC.c/h              ← FOC 算法模块(浮点版)
│   ├── adc.c/h              ← ADC 电流采样(开发中)
│   ├── vofa_uart.c/h        ← VOFA+ JustFloat 串口波形输出
│   ├── stm32f10x_it.c/h     ← 中断服务函数
│   └── stm32f10x_conf.h     ← 外设库配置
├── Output/                  ← Keil 编译输出
├── Listing/                 ← Keil 链接输出
├── keilkill.bat             ← Keil 编译中间文件清理脚本
└── README.md               ← 本文件

四、API 接口

PWM 驱动(bsp_pwm.h)

void BSP_PWM_Init(void);

/* 上管占空比设置(duty 范围:0 ~ 1799)*/
void BSP_PWM_SetDutyHighA(uint16_t duty);   // A相上管 PE9
void BSP_PWM_SetDutyHighB(uint16_t duty);   // B相上管 PE11
void BSP_PWM_SetDutyHighC(uint16_t duty);   // C相上管 PE13

/* 下管占空比设置(duty 范围:0 ~ 1799)*/
void BSP_PWM_SetDutyLowA(uint16_t duty);    // A相下管 PC6
void BSP_PWM_SetDutyLowB(uint16_t duty);    // B相下管 PC7
void BSP_PWM_SetDutyLowC(uint16_t duty);    // C相下管 PC8

/* 批量更新六路 PWM */
void BSP_PWM_Set(int* PWM_SetDutyHighA, int* PWM_SetDutyLowA,
                 int* PWM_SetDutyHighB, int* PWM_SetDutyLowB,
                 int* PWM_SetDutyHighC, int* PWM_SetDutyLowC);

FOC 算法(FOC.h)

/* Clarke 变换(三相静止 → 两相静止,等幅值)*/
void Clarke(float Ia, float Ib, float Ic, float *Ialpha, float *Ibeta);

/* Park 变换(两相静止 → 两相旋转)*/
void Park(float Ialpha, float Ibeta, float theta, float *Id, float *Iq);

/* 反 Park 变换(两相旋转 → 两相静止)*/
void InvPark(float Id, float Iq, float theta, float *Ialpha, float *Ibeta);

/* 反 Clarke 变换(两相静止 → 三相静止)*/
void InvClarke(float Ialpha, float Ibeta, float *Ia, float *Ib, float *Ic);

/* 角度制 → 弧度制转换 */
void shift(float theta_degrees, float *theta);

/* SVPWM 算法(6扇区,含过调制保护)*/
void svpwm(float Ts, float Ualpha, float Ubeta, float *Ta, float *Tb, float *Tc);

FOC 算法常量(FOC.h):

宏定义 说明
SQRT3 1.73205080757f √3
ONE_SQRT3 0.577350269f 1/√3
PI 3.14159265358979323846f π
_sqrt3_2 0.8660254037844f √3/2
_1_2 0.5f 1/2

VOFA+ 串口(vofa_uart.h)

void VOFA_Init(void);                              // 初始化(含串口硬件)
void VOFA_SetChannel(uint8_t ch_idx, float value); // 设置单通道值
void VOFA_SendChannels(float ch0, float ch1,       // 设置6通道并发送
                       float ch2, float ch3,
                       float ch4, float ch5);
void VOFA_Send(void);                              // 发送当前帧

五、主循环控制流程(当前实现)

main.c 主循环中,角度逐次递增 1°,执行开环 SVPWM 控制:

  1. theta_degrees 从 0° 递增(步长 1°),≥ 360° 时归零循环
  2. shift() — 角度制 → 弧度制转换
  3. InvPark(D=0, Q=9.0, theta) — 反 Park 变换,得到 Uα/Uβ
  4. svpwm(Ts, Uα, Uβ) — 计算三相占空比 A/B/C
  5. 映射到 CCR:A_num = (int)(A × PWM_DUTY_MAX / Ts),范围 0~1799
  6. BSP_PWM_Set() — 批量更新六路 PWM 占空比
  7. VOFA_SendChannels() — 串口输出波形数据

六、开发状态

  • TIM1 上管 + TIM8 下管 PWM 驱动(中心对齐,20kHz)
  • Clarke / InvClarke 变换
  • Park / InvPark 变换
  • SVPWM 算法实现(开环,6扇区,过调制保护)
  • LKS560 驱动板连接 — 电机已可转动
  • VOFA+ JustFloat 串口波形输出(6通道,115200bps)
  • ADC 三相电流采样(PC0/PC1/PC2, ADC1 IN10/IN11/IN12)
  • TIM6/TIM7 硬件触发 ADC(与 PWM 同步采样)
  • 死区时间软件偏移
  • PI 电流闭环(Id/Iq 闭环控制)
  • 速度闭环
  • FOC_Q15 定点版算法实现

七、注意事项

  1. TIM1 引脚使用全重映射(GPIO_FullRemap_TIM1),PE9/PE11/PE13 为上管 PWM 输出。

  2. 上下管分属不同定时器,死区需在 SVPWM 算法中通过偏移 CCR 值实现。

  3. 高级定时器必须调用 TIM_CtrlPWMOutputs() 使能主输出 MOE,否则 PWM 引脚无波形输出。

  4. 编译宏定义:STM32F10X_HD, USE_STDPERIPH_DRIVER, HSE_VALUE=8000000

  5. VOFA+ 串口使用 USART1(PA9 TX),115200bps,JustFloat 协议,帧尾 0x00 0x00 0x80 0x7F

  6. 当前版本不再使用 TIM1 TRGO → TIM8 ITR0 主从同步机制,改为 BSP_PWM_Init() 末尾直接同时使能两个定时器。


八、编译与下载

  1. 打开 Project/RVMDK(uv5)/BH-STM32.uvprojx
  2. 选择目标芯片:STM32F103VE
  3. 编译:点击 Build(或 F7)
  4. 下载:连接 CMSIS-DAP 调试器,点击 Download(或 F8)
  5. 运行:复位后自动运行

最后更新:2026-06-21

About

一个用于学习FOC的库,并使用STM32(野火指南者stm32f103ve)和电机驱动板(LKS_EVB_MVPOWPRE_V1.0)()

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages