本次实验我们要实现的功能是用STM32G4电机外设配置-TIM1,OPAMP,ADC,UART以达到测电机静态电流ia,ib,ic
一、cubemx的配置
1.1 RCC和SYS的配置
1.2 配置时钟为170MHZ
1.3 配置UART2通信
因为原理图上使用了usart2,所以这样我使用了usart2
1.4 配置tim1定时器输出三相互补pwm,并用通道4触发ADC转换
使用定时器内部时钟,开启通道1-3的pwm互补输出通道
预分频选择0分频,计数模式选择中心对齐。arr选择170*1000000/16000/2,trgo选择oc4ref
死区自动重载使能,死区时间选择169
通道1-3其他选择照常即可,通道4选择pwm模式2,占空比设置成这样,在蓄流时采集电流
1.5 配置opamp和ADC
使能opamp1和opamp2
并在OPAMP1_VOUT选择ADC1_IN3,OPAMP2_VOUT现在ADC2_IN3
ADC1和ADC2都以上图相同配置,重点是触发方式为timer1通道4硬件触发,注入组使能
使能ADC中断
1.6 生成工程
二、工程代码的编写
2.1 printf重定向
勾选 Use MicroLIB
输入(--no-multibyte-chars)可以防止中文报错
int fputc(int ch,FILE *f) { HAL_UART_Transmit(&huart2,(uint8_t *)&ch,1,HAL_MAX_DELAY); return ch; }2.2 初始化函数
/* USER CODE BEGIN 2 */ HAL_OPAMP_Start(&hopamp1); //使能OPAMP1 HAL_OPAMP_Start(&hopamp2); //使能OPAMP2 HAL_ADCEx_Calibration_Start(&hadc1,ADC_SINGLE_ENDED); //校准ADC1的注入组通道 HAL_ADCEx_Calibration_Start(&hadc2,ADC_SINGLE_ENDED); //校准ADC2的注入组通道 __HAL_ADC_CLEAR_FLAG(&hadc1,ADC_FLAG_JEOC); //清除ADC1的JEOC,cubemx会上点后自动清除可不写 __HAL_ADC_CLEAR_FLAG(&hadc2,ADC_FLAG_JEOC); //清除ADC2的JEOC,cubemx会上点后自动清除可不写 HAL_ADCEx_InjectedStart_IT(&hadc1); //使能ADC1注入组中断 HAL_ADCEx_InjectedStart(&hadc1); //使能ADC2注入组,不用IT的原因:ADC1和ADC2共用一个中断 HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_4); 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_TIM_SetCompare(&htim1,TIM_CHANNEL_1,0.8*5312); __HAL_TIM_SetCompare(&htim1,TIM_CHANNEL_2,0.8*5312); __HAL_TIM_SetCompare(&htim1,TIM_CHANNEL_3,0.8*5312); /* USER CODE END 2 */2.3 中断回调函数编写
/* USER CODE BEGIN PV */ int32_t adc1_in1=0; int32_t adc1_in2=0; float ia=0; float ib=0; float ic=0; /* USER CODE END PV */void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef *hadc) { UNUSED(hadc); //不使用hadc,防止报错 adc1_in1=hadc1.Instance->JDR1; adc1_in2=hadc2.Instance->JDR1; ia=(2048-adc1_in1)*0.02197f; //0.02197=3.3/4095*放大倍速/采样电阻 ib=(2048-adc1_in2)*0.02197f; ic=-ia-ib; }while (1) { printf("ia=%.3f,ib=%.3f,ic=%.3f\r\n",ia,ib,ic); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ }