目錄
- 一、STM32G4 電流環閉環(二) 霍爾有感運行
- 2. 霍爾有感運行
- 附學習參考網址
- 歡迎大家有問題評論交流 (* ^ ω ^)
一、STM32G4 電流環閉環(二) 霍爾有感運行
2. 霍爾有感運行
- 文章使用的BLDC在定子側以互差120°電角度的位置安裝三個霍爾元件Ha,Hb,Hc。當轉子轉動的時候霍爾元件會產生三個相位差120°電角度的高低電平信號。霍爾信號會將一個電周期劃分為6個扇區,每個扇區60°電角度,通過單片機的定時器捕獲可以獲得每個扇區的運行時間t。為了獲取準確的轉子角度,點擊繞組A相接電源正極,BC兩相接電源負極,電子磁場與轉子磁場共同作用,最終定位到轉子零位點,也就是A相繞組的軸線位置。確定零點位置后,根據霍爾的信號順序,可以得到霍爾信號與轉子位置的對應關系,如下表所示:
-
首先配置STM32G4的Hall接口;打開STM32CUBEMX;使能TIM4,選擇內部時鐘,在組合通道中選擇XOR ON/ HALL Sensor mode;
-
配置定時器參數;16分頻后,TIM4的時鐘為10M;
-
生成代碼并打開Keil工程
-
在TIM輸入捕獲回調函數中添加如下代碼,積分時間是10k;
-
其中HALL角速度計算公式:
HallSpeed=PI3?HallTempHallSpeed = \frac{PI}{3 * HallTemp} HallSpeed=3?HallTempPI?
HallTheta=∫0HallTempHallSpeedHallTheta = \int^{HallTemp}_{0}HallSpeed HallTheta=∫0HallTemp?HallSpeed -
在ADC注入組中斷回調函數中輸入,HALL傳感器得到的速度和角度;在頂部添加的變量和ADC的代碼修改如下
/* USER CODE BEGIN PV */
#define PI 3.14159265358979f
#define PHASE_SHIFT_ANGLE (float)(220.0f/360.0f*2.0f*PI)extern DMA_HandleTypeDef hdma_usart3_tx;
uint8_t DataB1[32] = "LED1 Toggle\r\n";
uint8_t DataB2[32] = "LED2 Toggle\r\n";
uint8_t DataB3[32] = "LED1 and LED2 Open\r\n";#define RXBUFFERSIZE 256
char RxBuffer[RXBUFFERSIZE];
uint8_t aRxBuffer;
uint8_t Uart1_Rx_Cnt = 0; float load_data[5];
static uint8_t tempData[24] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x80,0x7F};uint16_t DAC_temp = 0;float Vbus,Ia,Ib,Ic;
uint8_t Motor_state = 0;
uint16_t IA_Offset,IB_Offset,IC_Offset;
uint16_t adc1_in1, adc1_in2, adc1_in3, Vpoten, adc_vbus;
uint8_t ADC_offset = 0;FDCAN_RxHeaderTypeDef RxHeader;
FDCAN_TxHeaderTypeDef TxHeader;
uint8_t RxData[8]={NULL};
uint8_t TxData[8] = {NULL};float HallTemp = 0;
float HallThetaAdd = 0;
float HallTheta = 0;
float HallSpeed = 0;
float HallSpeedLast = 0;
float HallSpeedtest = 0;
float alpha = 0.3;
uint8_t HallReadTemp = 0;
/* USER CODE END PV */void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef *hadc)
{static uint8_t cnt;/* Prevent unused 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{HallTheta = HallTheta + HallThetaAdd;if(HallTheta<0.0f){HallTheta += 2.0f*PI;}else if(HallTheta>(2.0f*PI)){HallTheta -= 2.0f*PI;}rtU.theta = HallTheta;rtU.SpeedFd = HallSpeed;adc1_in1 = hadc1.Instance->JDR1;adc1_in3 = hadc1.Instance->JDR2;adc1_in2 = hadc2.Instance->JDR1;Ia = (adc1_in1 - IA_Offset)*0.02197265625f;Ib = (adc1_in2 - IB_Offset)*0.02197265625f;Ic = (adc1_in3 - IC_Offset)*0.02197265625f;rtU.ia = Ia;rtU.ib = Ib;rtU.ic = Ic;FOC_Model_step();TIM1->CCR1 = rtY.tABC[0];TIM1->CCR2 = rtY.tABC[1];TIM1->CCR3 = rtY.tABC[2];load_data[0] = Ia;load_data[1] = HallTemp;load_data[2] = HallTheta;load_data[3] = rtU.SpeedRef;load_data[4] = HallSpeed;memcpy(tempData, (uint8_t *)&load_data, sizeof(load_data));HAL_UART_Transmit_DMA(&huart3,(uint8_t *)tempData,6*4);}}/* NOTE : This function should not be modified. When the callback is needed,function HAL_ADCEx_InjectedConvCpltCallback must be implemented in the user file.*/
}
- 編譯代碼,連接設備
- 打開Keil的debug模式,可以試試修改速度,同時啟動vofa上位機觀察電流和Hall數據
- 低速的時候跟蹤的不是很好
附學習參考網址
- STM32G4 FOC開發實戰