手写STM32 FOC记录-----pwm触发adc电流采样
2025-10-15 来源:bilibili
PWM的配置详见上一章节。
ADC配置需要使用 PWM 和 ADC 的同步机制,ADC 的采样由 TIM1 的 CCR4在 0 矢量中心附近触发:

首先配置三相电流和母线电压的ADC通道,此处根据硬件平台原理图去配置


然后是ADC基本配置


全部默认即可,说明一下,使用CubeMX配置ADC,使用注入组就用不到规则组。


这里配置比较关键,重点是以下几项,详细说明下:
Number Of Conversions :使用到注入组的通道个数3
External Trigger Source :外部触发源,使用前边说的定时器1的通道四作为触发源。
External Trigger Edge :外部触发极性,选择下降沿
Injected Rank :这个就是注入序列,一旦ADC开始注入转换,就会按照Rank1-2-3-4的顺序依次进行采样,每个rank只能选择一个对应的通道。每个通道对应ADC输入引脚
Sampling Time :采样时间,因为foc电流采样是一个分秒必争的过程,所以采样时间尽可能的要短。
其他配置均默认即可。
最后配置一个测试IO口,每次AD采集就翻转一下IO状态,便于使用示波器测试ADC的采样时间点。CubeMX生成代码。

还是跟上一章节一样,做一个测试文件,将要测试的模块都在测试文件中实现,在主函数中调用需要测试的模块即可。在测试文件中添加test_PWM_ADC_init,主函数调用

void test_PWM_ADC_init(void)
{
HAL_TIM_Base_Start(&htim1);
HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_2);
HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_3);
HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_4);
HAL_TIMEx_PWMN_Start(&htim1,TIM_CHANNEL_1);
HAL_TIMEx_PWMN_Start(&htim1,TIM_CHANNEL_2);
HAL_TIMEx_PWMN_Start(&htim1,TIM_CHANNEL_3);
__HAL_TIM_SetCompare(&htim1,TIM_CHANNEL_1,0.2*PWM_PERIOD);
__HAL_TIM_SetCompare(&htim1,TIM_CHANNEL_2,0.2*PWM_PERIOD);
__HAL_TIM_SetCompare(&htim1,TIM_CHANNEL_3,0);
HAL_ADCEx_InjectedStart(&hadc1);
HAL_ADCEx_InjectedStart(&hadc2);
__HAL_ADC_ENABLE_IT(&hadc1, ADC_IT_JEOC);
__HAL_ADC_ENABLE_IT(&hadc2, ADC_IT_JEOC);
__HAL_TIM_ENABLE_IT(&htim1, TIM_IT_UPDATE);
__HAL_TIM_SetCompare(&htim1,TIM_CHANNEL_4,PWM_PERIOD-1); //TIM1通道4的PWM配置 关联ADC采样时间 // 在PWM波的正中间采样
}

在中断文件stm32g4xx_it.c中ADC1_2_IRQHandler处添加测试引脚翻转函数,测试ADC的采样时间点

完成以上操作之后,就可以下载到板子中测试了。测试方法是,使用三根示波器表笔,分别接一路PWM,PWMN,TEST_PIN,波形显示如下图:

上图中,黄线是PWM,蓝线为PWMN,紫线为测试引脚波形。可以看出,ADC 中断采样周期和 PWM 周期一致。
最后一步就是测试ADC是否配置成功,看看ADC能否采集到数据。

uint16_t PA1_adc_value,PB11_adc_value,PA0_adc_value,PA7_adc_value;
void test_get_ADC_value(void)
{
PA1_adc_value = HAL_ADCEx_InjectedGetValue(&hadc1,ADC_INJECTED_RANK_1);
PB11_adc_value = HAL_ADCEx_InjectedGetValue(&hadc1,ADC_INJECTED_RANK_2);
PA0_adc_value = HAL_ADCEx_InjectedGetValue(&hadc1,ADC_INJECTED_RANK_3);
PA7_adc_value = HAL_ADCEx_InjectedGetValue(&hadc2,ADC_INJECTED_RANK_1);
}
编写测试接口函数test_get_ADC_value,将其放到中断文件stm32g4xx_it.c中ADC1_2_IRQHandler处调用。

仿真看看读取到的变量结果,如果我们将这个通道连接到VCC,数据会变成0x0FFF左右,接到GND,数据变成0x0000。

- 意法半导体中国本地造STM32微控制器启动规模量产
- 意法半导体全新STM32C5系列,重新定义入门级微控制器性能与价值,赋能万千智能设备
- 使用 Keil Studio for Visual Studio Code开发 STM32 设备
- 基于机智云与STM32的智能拐杖安全监测系统在养老物联网中的应用
- 内置全栈安全,一站式满足CRA法案与IEC 62443标准——米尔STM32MP257核心板
- 如何用 STM32 FLASH 实现等效 100 万次擦写的 EEPROM 功能?
- 实战解析:通过一个小项目掌握STM32所有外设
- STM32学了两年半,却还是不会做项目
- 意法半导体推出最新STM32MP21微处理器,兼具高性价比、低功耗、高灵活性
- 基于STM32的矿井作业环境监测系统设计与实现
- 六大全新产品系列推出,MCX A微控制器家族迎来创新
- 意法半导体全新STM32C5系列,重新定义入门级微控制器性能与价值,赋能万千智能设备
- 从控制到系统:TI利用边缘AI重塑嵌入式MCU的边界
- 模组复用与整机重测在SRRC、CCC、CTA/NAL认证中的实践操作指南
- 有源晶振与无源晶振的六大区别详解
- 英飞凌持续巩固全球微控制器市场领导地位
- 使用 Keil Studio for Visual Studio Code开发 STM32 设备
- 蓝牙信道探测技术原理与开发套件实践
- LoRa、LoRaWAN、NB-IoT与4G DTU技术对比及工业无线方案选型分析
- Microchip 推出生产就绪型全栈边缘 AI 解决方案,赋能MCU和MPU实现 智能实时决策




