ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

ST电机库学习记录——配置MC—WorkBench + CuBeMX配置MT6701磁位置传感器

ST电机库学习记录——配置MC—WorkBench + CuBeMX配置MT6701磁位置传感器

选择板卡和驱动电机(电机参数需要自行对照调节)

配置一览

为了方便测试配置开环调试 串口波特率选择115200

配置CuBeMX

配置spi读取mt6701

配置MISO和CLK

配置FOC_L_CS引脚

配置LED灯与电机控制引脚(个人配置)

Keil5代码移植

mian.c/.h中

//-------------main.c--------------------- /* USER CODE BEGIN PFP */ MCI_State_t state; //电机状态机全局变量 float angle_f;//获取的实际角度 int16_t angle; float use_angle_f; /*串口重映射(还需要修改对应函数) stm32_mc_common_it.c 中的 USART1_IRQHandler 函数 */ int fputc(int ch, FILE *f) { // 通过串口1发送一个字符 // 这里的 &huart1 是你已经初始化好的串口句柄 HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY); return ch; } //mt6701驱动 void mt6701_spi_read_L(unsigned char* buf, unsigned short len) { HAL_SPI_Receive(&hspi1, buf, len, MT6701_Timeout); } // 14Bit角度信息,存储在0x03[13:6]、0x04[5:0]两个寄存器中,高位在前,原始读数0~16383,对应0-360° void mt6701_spi_get_L_angle(int16_t *angle, float *angle_f) { uint8_t temp[3]; SPI_L_CS_Enable(); mt6701_spi_read_L(temp, 3); //HAL_SPI_TransmitReceive(&hspi2, tx, temp, 3, MT6701_Timeout); SPI_L_CS_Disable(); *angle = ((int16_t)temp[0] << 6) | (temp[1] >> 2); *angle_f = (float)*angle * 360 / 16384.0f; } float getAngle_Without_track(void)//绝对角度(角度制) { mt6701_spi_get_L_angle(&angle, &angle_f); return angle_f; } //闪灯小代码 void shan() { HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET); HAL_Delay(300); HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET); HAL_Delay(300); } /* USER CODE END PFP */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ //是否上电自动启动电机 // MC_StartMotor1(); state = MC_GetSTMStateMotor1(); if(state==RUN) { //MC_ProgramSpeedRampMotor1(500, 500); //HAL_Delay (5000); } shan(); // 将控制模式设置为开环电压模式 // MCI_SetOpenLoopVoltageMode(&Mci[M1]); // 设定电压为 10% 的满量程 // OL_UpdateVoltage(&OpenLoop_ParamsM1, ((10 * 32767) / 100)); //触发保护自救 // if(state==11) // { // MC_AcknowledgeFaultMotor1(); //清除报错 // MC_StartMotor1(); // } } /* USER CODE END 3 */ //-------------main.h--------------------- /* USER CODE BEGIN Includes */ #include <stdio.h> /* USER CODE END Includes */ /* USER CODE BEGIN Private defines */ #define SPI_L_CS_Enable() FOC_L_CS_GPIO_Port->BSRR=(uint32_t)FOC_L_CS_Pin<<16U #define SPI_L_CS_Disable() FOC_L_CS_GPIO_Port->BSRR=FOC_L_CS_Pin #define MT6701_Timeout 50 extern int16_t anglee; extern float angle_f;//获取的实际角度 void mt6701_spi_get_L_angle(int16_t *angle, float *angle_f); float getAngle_Without_track(void);//绝对角度(角度制) /* USER CODE END Private defines */

stm32_mc_common_it.c

//文件开头 /* USER CODE BEGIN Includes */ #include "main.h" extern UART_HandleTypeDef huart1; /* USER CODE END Includes */ //USART1_IRQHandler函数 /* USER CODE BEGIN USART1_IRQHandler 1 */ HAL_UART_IRQHandler(&huart1); /* USER CODE END USART1_IRQHandler 1 */

修改启动参数:drive_parameters.h

/* Phase 1 */ #define PHASE1_DURATION 50 /*milliseconds */ #define PHASE1_FINAL_SPEED_UNIT (0*SPEED_UNIT/U_RPM) #define PHASE1_FINAL_CURRENT_A 7 /* Phase 2 */ #define PHASE2_DURATION 300 /*milliseconds */ #define PHASE2_FINAL_SPEED_UNIT (1000*SPEED_UNIT/U_RPM) #define PHASE2_FINAL_CURRENT_A 7 /* Phase 3 */ #define PHASE3_DURATION 700 /*milliseconds */ #define PHASE3_FINAL_SPEED_UNIT (3333*SPEED_UNIT/U_RPM) #define PHASE3_FINAL_CURRENT_A 7 /* Phase 4 */ #define PHASE4_DURATION 0 /*milliseconds */ #define PHASE4_FINAL_SPEED_UNIT (3333*SPEED_UNIT/U_RPM) #define PHASE4_FINAL_CURRENT_A 5 /* Phase 5 */ #define PHASE5_DURATION 0 /* milliseconds */ #define PHASE5_FINAL_SPEED_UNIT (3333*SPEED_UNIT/U_RPM) #define PHASE5_FINAL_CURRENT_A 5

补充任务:mc_tasks.c/.h

MC_RunMotorControlTasks

//mc_tasks.h中 #include "main.h" //设定停止时间为2ms #define STOPPERMANENCY_MS ((uint16_t)2) //mc_tasks.c中 /* USER CODE BEGIN Private Variables */ extern UART_HandleTypeDef huart1; char g_debug_buf[512]; static uint16_t printCounter = 0; const uint16_t PRINT_INTERVAL = 50; // ?次中频任务 int ctrluser = 0; int ctrlkeep = 0; // 电流基值 #define CURRENT_SCALE (ADC_REFERENCE_VOLTAGE / (RSHUNT * AMPLIFICATION_GAIN)) // = 16.5A // 电压基值 (相电压峰值) #define VOLTAGE_SCALE (NOMINAL_BUS_VOLTAGE_V / 1.73205f) // = 6.93V /* USER CODE END Private Variables */ /* USER CODE BEGIN MC_Scheduler 2 */ printCounter++; if (printCounter >= PRINT_INTERVAL) { printCounter = 0; // 读取故障 uint16_t occurredFaults = MC_GetOccurredFaultsMotor1(); // 读取速度 int16_t speed_internal = MC_GetMecSpeedAverageMotor1(); float_t speed_rpm = MC_GetAverageMecSpeedMotor1_F(); // 读取状态 MCI_State_t state = MC_GetSTMStateMotor1(); // 读取电流(旋转坐标系) qd_t iqd = MC_GetIqdMotor1(); qd_t vqd = MC_GetVqdMotor1(); // 读取原始三相电流 Ia, Ib ab_t iab = MC_GetIabMotor1(); float use_angle_f = getAngle_Without_track(); // 换算为实际值 float iq = (float)iqd.q * CURRENT_SCALE / 32767.0f; float id = (float)iqd.d * CURRENT_SCALE / 32767.0f; float vq = (float)vqd.q * VOLTAGE_SCALE / 32767.0f; float vd = (float)vqd.d * VOLTAGE_SCALE / 32767.0f; // Ia, Ib 换算为实际安培值 float ia = (float)iab.a * CURRENT_SCALE / 32767.0f; float ib = (float)iab.b * CURRENT_SCALE / 32767.0f; // 格式化为 CSV 行(VOFA+ FireWater 模式) int len = sprintf(g_debug_buf, "data: %d, %.2f, %d, %.3f, %.3f, %.2f, %.2f, %.3f, %.3f, %f, 0x%04X\n", speed_internal, // col1: 实际速度(内部值) speed_rpm, // col2: 实际速度 (RPM) state, // col3: 状态 iq, // col4: 实际 Iq (A) id, // col5: 实际 Id (A) vq, // col6: Vq (V) vd, // col7: Vd (V) ia, // ★col8: A相电流 (A) ib, // ★col9: B相电流 (A) use_angle_f, // ★col10: occurredFaults // ★col11: 历史故障 (0x0000 表示无故障) ); if (len > 0) { for (int i = 0; i < len; i++) { while (!(USART1->ISR & USART_ISR_TXE)) {} USART1->TDR = g_debug_buf[i]; } } if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_11)==SET) { ctrluser = 1; } if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_12)==SET) { ctrlkeep = 1; } if(ctrluser == 1) { if(ctrlkeep == 0) { if(use_angle_f >= 40&&use_angle_f < 50) { if(state!=STOP) { if(state==RUN||state==START) { MC_StopMotor1(); } } } // else if(use_angle_f > 310||use_angle_f < 40) // { // MC_StartMotor1(); // MC_ProgramSpeedRampMotor1(-800, 500); // } else { MC_StartMotor1(); MC_ProgramSpeedRampMotor1(-600, 500); } } else if(ctrlkeep == 1) { if(use_angle_f >= 290&&use_angle_f < 300) { if(state!=STOP) { if(state==RUN||state==START) { MC_StopMotor1(); } } } // else if(use_angle_f < 50||use_angle_f > 320) // { // MC_StartMotor1(); // MC_ProgramSpeedRampMotor1(-800, 500); // } else { MC_StartMotor1(); MC_ProgramSpeedRampMotor1(600, 500); } } } ctrluser = 0; ctrlkeep = 0; } /* USER CODE END MC_Scheduler 2 */

硬件补丁:

如果因为硬件设计导致电源电压不稳定可以将STSPIN32G4_setVCC改为8V

位于mc_tasks.c

/*************************************************/ /* STSPIN32G4 driver component initialization */ /*************************************************/ STSPIN32G4_init(&HdlSTSPING4); STSPIN32G4_reset(&HdlSTSPING4); STSPIN32G4_setVCC(&HdlSTSPING4, (STSPIN32G4_confVCC){.voltage = _8V, .useNFAULT = true, .useREADY = false }); STSPIN32G4_setVDSP(&HdlSTSPING4, (STSPIN32G4_confVDSP){.deglitchTime = _4us, .useNFAULT = true }); STSPIN32G4_clearFaults(&HdlSTSPING4);
返回列表