STM32G4 TIM1触发ADC转换
- ✨继
欧拉电子
无刷电机驱动相关视频学习 -- STM32G4 FOC开发实战---TIM1 ADC COMP DAC级联
STM32G4 FOC开发实战---TIM1 ADC COMP DAC级联
- 🌿相对应的文章:
https://mp.weixin.qq.com/s?__biz=MzkwMDIzNjA1MQ==&mid=2247484140&idx=1&sn=38128f6f5f8b7afc35a9dd191a4718a8&chksm=c0465490f731dd864907d18ec837e37801062578ac0971eed810268a2efccece02990606e874&mpshare=1&scene=23&srcid=03247g3pxdbfnU0CUA8vrM2i&sharer_shareinfo=411eecf8ebc86fc522cf982bb036e8b0&sharer_shareinfo_first=411eecf8ebc86fc522cf982bb036e8b0#rd
✨跟着视频学习过程中,还是出现了不少状况,在实际测试过程中,发现测试结果并不如视频效果预期。于是各种检查和找问题。
- 📌与本篇知识相关内容参考:《手把手移植 simpleFOC (五):电流检测 篇》
- 🧨《手写STM32 FOC记录-----pwm触发adc电流采样》
- 🔖在以上参考内容中,解决了不能进入ADC中断的问题。
⛳注意事项
- 🌿在上面的视频讲解和文章内容中,没有提及在STM32CubeMX软件中对ADC中断的开启。
- 🌿ADC注入转换,需要开启对应的中断。具体参考下面
main
代码初始化配置。
📙本篇工程功能实现概要
- 🌾STM32G4高级定时器1(TIM1)产生3路互补PWM。:PWM互补输出通过调整PWM信号的占空比来控制电机的转速,通过改变信号的极性来控制电机的转向,从而实现精确的电机控制。
- 🌾利用高级定时器1(TIM1)通道4,触发ADC采样。
- 🌾使能ADC1注入通道:ADC1 ->AIN3、ADC1 -> AIN11
- 🌾使能ADC2注入通道:ADC2 ->AIN1
- 配合内部的OPAMP,ADC准确的采样三相电流。
- 🌾使能DAC3 OUT1输出,映射到芯片内部外设。
- 在三相电流过流时及时封波.
- TIM1通道4触发ADC注入转换测试:
🛠代码配置
- 📝main
c
int main(void)
{
/* USER CODE BEGIN 1 */
// float temp[5];
// uint8_t TempData[12];//16 ADC:12;PWM:16 OPM:24
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_TIM1_Init();
MX_USART1_UART_Init();
MX_ADC1_Init();
MX_COMP1_Init();
MX_DAC3_Init();
MX_ADC2_Init();
MX_OPAMP1_Init();
MX_OPAMP2_Init();
MX_OPAMP3_Init();
/* USER CODE BEGIN 2 */
// TIM1->PSC = 30000;//VOFA上位机观测,开启
// TIM1->ARR = 10000;
// TIM1->CCR1 = 2000;
// TIM1->CCR2 = 5000;
// TIM1->CCR3 = 4000;
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_TIMEx_PWMN_Start(&htim1,TIM_CHANNEL_1);
// HAL_TIMEx_PWMN_Start(&htim1,TIM_CHANNEL_2);
// HAL_TIMEx_PWMN_Start(&htim1,TIM_CHANNEL_3);
HAL_OPAMP_Start(&hopamp1);
HAL_OPAMP_Start(&hopamp2);
HAL_OPAMP_Start(&hopamp3);
//HAL_UART_Receive_IT(&huart3,(uint8_t *)&aRxBuffer,1);
HAL_ADCEx_Calibration_Start(&hadc1, ADC_SINGLE_ENDED);//ADC自校验
HAL_ADCEx_Calibration_Start(&hadc2, ADC_SINGLE_ENDED);
TIM1->ARR = 8000 - 1;
TIM1->CCR4 = 8000 - 2;//PWM_F=160MHz/(8000*2)=10KHz
HAL_TIM_Base_Start(&htim1);
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_4);//用于产生ADC触发事件
__HAL_ADC_ENABLE_IT(&hadc1, ADC_IT_JEOC);//需要开启ADC注入中断
__HAL_ADC_ENABLE_IT(&hadc2, ADC_IT_JEOC);
HAL_ADCEx_InjectedStart_IT(&hadc1);
HAL_ADCEx_InjectedStart(&hadc2);
HAL_DAC_Start(&hdac3, DAC_CHANNEL_1);
HAL_DAC_SetValue(&hdac3, DAC_CHANNEL_1, DAC_ALIGN_12B_R, 3000);
HAL_COMP_Start(&hcomp1);//启动比较器
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while(1) {
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_ADC_Start(&hadc1);
HAL_ADC_Start(&hadc2);
Vpoten = HAL_ADC_GetValue(&hadc1);
adc_vbus = HAL_ADC_GetValue(&hadc2);
Vbus = adc_vbus * 3.3f / 4096 * 26;
HAL_Delay(10);
}
/* USER CODE END 3 */
}
- 🌿按键中断
c
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
/*Preventunusedargument(s)compilationwarning */
// UNUSED(GPIO_Pin);
if(KEY1_Pin == GPIO_Pin) {
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_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_1);
HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_2);
HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_3);
HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
}
// if(KEY2_Pin == GPI0_Pin)//没有配置该按键
// {
// HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_1);
// HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_2);
// HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_3);
// HAL_TIMEx_PWMN_Stop(&htim1, TIM_CHANNEL_1);
// HAL_TIMEx_PWMN_Stop(&htim1, TIM_CHANNEL_2);
// HAL_TIMEx_PWMN_Stop(&htim1, TIM_CHANNEL_3);
// }
}
- 🌿ADC注入中断回调
c
void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef *hadc)
{
static uint8_t cnt;
/*Preventunused argument(s)compilation warning */
// UNUSED(hadc);
if(hadc == &hadc1) {
if(ADC_offset == 0) {
cnt++;
adc1_in1 = hadc1.Instance->JDR1;
adc1_in2 = hadc2.Instance->JDR1;
adc1_in3 = hadc1.Instance->JDR2;
IA_Offset += adc1_in1;
IB_Offset += adc1_in2;
IC_Offset += adc1_in3;
}
if(cnt >= 10) {
ADC_offset = 1;
IA_Offset = IA_Offset / 10;
IB_Offset = IB_Offset / 10;
IC_Offset = IC_Offset / 10;
}
} else {
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_4);
adc1_in1 = hadc1.Instance->JDR1;
Ia = (adc1_in1 - IA_Offset) * 0.0193359375f;
adc1_in2 = hadc2.Instance->JDR1;
Ib = (adc1_in2 - IB_Offset) * 0.0193359375f;
adc1_in3 = hadc1.Instance->JDR2;
Ic = (adc1_in3 - IC_Offset) * 0.0193359375f;
TIM1->CCR1 = 2000;
TIM1->CCR2 = 4000;
TIM1->CCR3 = 6000;
load_data[0] = Ia;
load_data[1] = Ib;
load_data[2] = Ic;
load_data[3] = 0;
load_data[4] = 0;
// memcpy(tempData, (uint8_t *)&load_data, sizeof(load_data));
// HAL_UART_Transmit_DMA(&huart1, (uint8_t *)tempData, 6 * 4);
}
}
📚测试工程源码
c
链接:https://pan.baidu.com/s/1eWC-KZDSMnUfOTAn-wMgmg?pwd=s50q
提取码:s50q