前言
完成的板子还没到,先用了灯哥的驱动模块测试了。驱动板上驱动自带了mos和死去控制,所以暂时不用互补的PWM(cubemx上已完成互补配置,此篇文章里的驱动并未使用到)。先发一张马鞍波:)
软件设置
- 1、TIM PWM设置
- PWM配置了3组互补PWM和一个用于采样ADC的PWM. CCR为4800/2,RCR设置为1. TRGO设置为OC4REF。前3组PWM模式为mode1,PWM4模式为mode2。
-
-
-
-
-
-
-
- 2、ADC配置
- ADC配置比较简单,使能DMA循环采样,设置PWM4过来的触发源。
-
-
-
- 3、NVIC
- 使能TIM1中断
-
- 4、时钟树配置
5、初始化顺序
要保证DMA在ADC初始化之前,这里可以调整顺序。
之后便可以生成文件。
驱动代码
这里使用Matlab生成的代码,稍微修改了点。以下是svpwm代码。
#include "foc.h"
ExtU rtU;
ExtY rtY;
/* Model step function */
void foc_step(void) {
int sector;
float T1;
float rtb_ualpha;
float rtb_ubeta;
T1 = sinf(rtU.theta);
rtb_ubeta = cosf(rtU.theta);
rtb_ualpha = (float) rtU.ud * rtb_ubeta - (float) rtU.uq * T1;
rtb_ubeta = (float) rtU.ud * T1 + (float) rtU.uq * rtb_ubeta;
sector = 0;
if (rtb_ubeta > 0.0F) {
sector = 1;
}
if ((1.73205078F * rtb_ualpha - rtb_ubeta) / 2.0F > 0.0F) {
sector += 2;
}
if ((-1.73205078F * rtb_ualpha - rtb_ubeta) / 2.0F > 0.0F) {
sector += 4;
}
switch (sector) {
case 1:
T1 = (-1.5F * rtb_ualpha + 0.866025388F * rtb_ubeta) * (rtU.Tpwm / rtU.udc);
rtb_ualpha = (1.5F * rtb_ualpha + 0.866025388F * rtb_ubeta) * (rtU.Tpwm / rtU.udc);
break;
case 2:
T1 = (1.5F * rtb_ualpha + 0.866025388F * rtb_ubeta) * (rtU.Tpwm / rtU.udc);
rtb_ualpha = -(1.73205078F * rtb_ubeta * rtU.Tpwm / rtU.udc);
break;
case 3:
T1 = -((-1.5F * rtb_ualpha + 0.866025388F * rtb_ubeta) * (rtU.Tpwm / rtU.udc));
rtb_ualpha = 1.73205078F * rtb_ubeta * rtU.Tpwm / rtU.udc;
break;
case 4:
T1 = -(1.73205078F * rtb_ubeta * rtU.Tpwm / rtU.udc);
rtb_ualpha = (-1.5F * rtb_ualpha + 0.866025388F * rtb_ubeta) * (rtU.Tpwm / rtU.udc);
break;
case 5:
T1 = 1.73205078F * rtb_ubeta * rtU.Tpwm / rtU.udc;
rtb_ualpha = -((1.5F * rtb_ualpha + 0.866025388F * rtb_ubeta) * (rtU.Tpwm / rtU.udc));
break;
default:
T1 = -((1.5F * rtb_ualpha + 0.866025388F * rtb_ubeta) * (rtU.Tpwm / rtU.udc));
rtb_ualpha = -((-1.5F * rtb_ualpha + 0.866025388F * rtb_ubeta) * (rtU.Tpwm /
rtU.udc));
break;
}
rtb_ubeta = T1 + rtb_ualpha;
if (rtb_ubeta > rtU.Tpwm) {
T1 /= rtb_ubeta;
rtb_ualpha /= T1 + rtb_ualpha;
}
rtb_ubeta = (rtU.Tpwm - (T1 + rtb_ualpha)) / 4.0F;
T1 = T1 / 2.0F + rtb_ubeta;
switch (sector) {
case 1:
rtY.Tcmp1 = T1;
rtY.Tcmp2 = rtb_ubeta;
rtY.Tcmp3 = rtb_ualpha / 2.0F + T1;
break;
case 2:
rtY.Tcmp1 = rtb_ubeta;
rtY.Tcmp2 = rtb_ualpha / 2.0F + T1;
rtY.Tcmp3 = T1;
break;
case 3:
rtY.Tcmp1 = rtb_ubeta;
rtY.Tcmp2 = T1;
rtY.Tcmp3 = rtb_ualpha / 2.0F + T1;
break;
case 4:
rtY.Tcmp1 = rtb_ualpha / 2.0F + T1;
rtY.Tcmp2 = T1;
rtY.Tcmp3 = rtb_ubeta;
break;
case 5:
rtY.Tcmp1 = rtb_ualpha / 2.0F + T1;
rtY.Tcmp2 = rtb_ubeta;
rtY.Tcmp3 = T1;
break;
case 6:
rtY.Tcmp1 = T1;
rtY.Tcmp2 = rtb_ualpha / 2.0F + T1;
rtY.Tcmp3 = rtb_ubeta;
break;
}
rtY.sector = (float) sector;
}
#ifndef RTW_HEADER_foc_h_
#define RTW_HEADER_foc_h_
#include <math.h>
typedef struct {
double ud,uq;
float theta, udc,Tpwm;
} ExtU;
typedef struct {
float Tcmp1,Tcmp2,Tcmp3;
float sector;
} ExtY;
extern ExtU rtU;
extern ExtY rtY;
extern void foc_step(void);
#endif /* RTW_HEADER_foc_h_ */
.....
/* USER CODE BEGIN Includes */
#include "foc.h"
/* USER CODE END Includes */
.....
/* USER CODE BEGIN PV */
#define PI 3.1415926
uint16_t adc1_val_buf1[4] = {0};
extern ExtU rtU;
extern ExtY rtY;
extern DMA_HandleTypeDef hdma_adc1;
void dmaAdcCallback(struct __DMA_HandleTypeDef *hdma);
/* USER CODE END PV */
.....
int main(void)
{
....
/* USER CODE BEGIN Init */
rtU.ud = 0;
rtU.uq = 2;
rtU.Tpwm = 4800;
rtU.udc = 12;
....
/* USER CODE BEGIN 2 */
HAL_ADC_Start_DMA(&hadc1,(uint32_t*)&adc1_val_buf1,2);
hdma_adc1.XferCpltCallback = dmaAdcCallback;
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);
/* USER CODE END 2 */
....
}
....
/* USER CODE BEGIN 4 */
void dmaAdcCallback(struct __DMA_HandleTypeDef *hdma) {
rtU.theta += 0.01;
if (rtU.theta >= 2.0f * PI) {
rtU.theta -= 2.0f * PI;
}
foc_step();
htim1.Instance->CCR1 = (uint16_t) rtY.Tcmp3;
htim1.Instance->CCR2 = (uint16_t) rtY.Tcmp2;
htim1.Instance->CCR3 = (uint16_t) rtY.Tcmp1;
}
/* USER CODE END 4 */
....
调试
使用STM32CubeMonitor,观察输出的PWM。
至此电机已经旋转起来了^^
存在的问题
不知道是什么问题,cmake设置是默认的设置。写完这些板子flash就快满了,设置加不下一个串口的功能。。。。不知道是否有大佬知道是什么问题? |