Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "mcu_support_package/inc/stm32f10x.h"
- #include "signal.h"
- #include "stdbool.h"
- #include "math.h"
- #define dt 0.005
- #define PI 3.1415926
- #define sqrt_3 1.7320508075688772935274463415059
- int current_A = 0;
- int current_B = 0;
- int current_C = 0;
- int sample_time = 0;
- int PI_current_period_q=0;
- int PI_current_period_d=0;
- int PI_velocity_period=0;
- static int angular_velocity = 0;
- static int desired_velocity = 100;//желаемая скорость
- static int desired_current=0;
- int prev_position = 0;
- int position = 0;
- int desired_voltage = 0;
- int final_position = 0;
- int desired_current_d;
- int desired_current_q;
- int desired_voltage_d = 0;
- int desired_voltage_q = 0;
- int voltage_A =0;
- int voltage_B=0;
- int voltage_C=0;
- int Id=0;
- int Iq=0;
- void TIM1_UP_IRQHandler(void) {
- TIM_ClearFlag(TIM1, TIM_FLAG_Update);
- }
- void TIM3_IRQHandler(void) {
- TIM_ClearFlag(TIM3, TIM_FLAG_Update);
- sample_time++;
- PI_current_period_q++;
- PI_current_period_d++;
- PI_velocity_period++;
- }
- float PI_velocity(const float error, const float Kp, const float Ki){//ПИ регулятор, возвращающий желаемый ток
- float ext_value = 0;
- static float integral = 0;
- integral += error * PI_velocity_period/100000;
- ext_value = Kp * error + Ki * integral;
- //30% от максимального значения на выходе
- if (integral > 60) integral = 60;
- if (integral < -60) integral = -60;
- return ext_value;
- }
- float PI_current_q(const float error, const float Kp, const float Ki ){ //ПИ регулятор, возвращающий желаемое напряжение
- float ext_value = 0;
- static float integral = 0;
- integral += error * PI_current_period_q/100000;
- ext_value= Kp * error + Ki * integral;
- //30% от максимального значения на выходе
- if (integral > 180) integral= 180;
- if (integral < -180) integral = -180;
- return ext_value;
- }
- float PI_current_d(const float error, const float Kp, const float Ki ){ //ПИ регулятор, возвращающий желаемое напряжение
- float ext_value = 0;
- static float integral = 0;
- integral += error * PI_current_period_d/100000;
- ext_value= Kp * error + Ki * integral;
- //30% от максимального значения на выходе
- if (integral > 230) integral= 230;
- if (integral < -230) integral = -230;
- return ext_value;
- }
- void ADC1_2_IRQHandler(void) {//ловим токи инжектированными каналами АЦП
- current_A = ADC_GetInjectedConversionValue(ADC1,ADC_InjectedChannel_1) - 2048;
- current_B = ADC_GetInjectedConversionValue(ADC1,ADC_InjectedChannel_2) - 2048;
- current_C = -current_A - current_B;
- }
- void init_all() {
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
- //настройка TIM1 и TIM3
- GPIO_InitTypeDef GPIOA_pwn;
- GPIOA_pwn.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIOA_pwn.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10;
- GPIOA_pwn.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOA, &GPIOA_pwn);
- TIM_TimeBaseInitTypeDef TIM1_init;
- TIM_TimeBaseStructInit( & TIM1_init);
- TIM1_init.TIM_Prescaler = 72-1;
- TIM1_init.TIM_Period = 500; //2000 раз в секунду
- TIM1_init.TIM_CounterMode = TIM_CounterMode_Up;
- TIM_TimeBaseInit(TIM1, &TIM1_init);
- TIM_CtrlPWMOutputs(TIM1,ENABLE);
- TIM_TimeBaseInitTypeDef TIM3_init;
- TIM_TimeBaseStructInit( & TIM3_init);
- TIM3_init.TIM_Prescaler = 72-1;
- TIM3_init.TIM_Period = 10; //100 000 раз в секунду
- TIM3_init.TIM_CounterMode = TIM_CounterMode_Up;
- TIM_TimeBaseInit(TIM3, & TIM3_init);
- TIM_OCInitTypeDef PA8_channel_pwn;
- TIM_OCStructInit( & PA8_channel_pwn);
- PA8_channel_pwn.TIM_OCMode = TIM_OCMode_PWM1;
- PA8_channel_pwn.TIM_OutputState = TIM_OutputState_Enable;
- TIM_OC1Init(TIM1, &PA8_channel_pwn);
- TIM_OCInitTypeDef PA9_channel_pwn;
- TIM_OCStructInit( & PA9_channel_pwn);
- PA9_channel_pwn.TIM_OCMode = TIM_OCMode_PWM1;
- PA9_channel_pwn.TIM_OutputState = TIM_OutputState_Enable;
- TIM_OC2Init(TIM1, &PA9_channel_pwn);
- TIM_OCInitTypeDef PA10_channel_pwn;
- TIM_OCStructInit( & PA10_channel_pwn);
- PA10_channel_pwn.TIM_OCMode = TIM_OCMode_PWM1;
- PA10_channel_pwn.TIM_OutputState = TIM_OutputState_Enable;
- TIM_OC3Init(TIM1, &PA10_channel_pwn);
- //настройка АЦП
- GPIO_InitTypeDef PortA_adc;
- PortA_adc.GPIO_Mode = GPIO_Mode_AIN;
- PortA_adc.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;
- GPIO_Init(GPIOA, &PortA_adc);
- ADC_InitTypeDef ADC;
- ADC.ADC_Mode = ADC_Mode_Independent;
- ADC.ADC_ScanConvMode = ENABLE;
- ADC.ADC_ContinuousConvMode = ENABLE;
- ADC.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
- ADC.ADC_DataAlign = ADC_DataAlign_Right;
- ADC.ADC_NbrOfChannel = 2;
- ADC_Init(ADC1,&ADC);
- ADC_InjectedSequencerLengthConfig(ADC1,2);
- ADC_InjectedChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_55Cycles5);
- ADC_InjectedChannelConfig(ADC1,ADC_Channel_1,2,ADC_SampleTime_55Cycles5);
- ADC_ExternalTrigInjectedConvConfig( ADC1, ADC_ExternalTrigInjecConv_None );
- //калибровка АЦП
- ADC_ResetCalibration(ADC1);
- while(ADC_GetResetCalibrationStatus(ADC1)){;}
- ADC_StartCalibration(ADC1);
- while(ADC_GetCalibrationStatus(ADC1)){;}
- //включение прерываний
- ADC_ITConfig(ADC1,ADC_IT_EOC,ENABLE);
- TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);
- TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
- NVIC_EnableIRQ(ADC1_2_IRQn);
- NVIC_EnableIRQ(TIM1_UP_IRQn);
- NVIC_EnableIRQ(TIM3_IRQn);
- TIM_Cmd(TIM1, ENABLE);
- TIM_Cmd(TIM3, ENABLE);
- ADC_Cmd(ADC1,ENABLE);
- ADC_AutoInjectedConvCmd(ADC1,ENABLE);
- ADC_SoftwareStartConvCmd(ADC1, ENABLE);
- }
- int main(void){
- init_all();
- while (1) {
- position = TIM2->CNT ; //положение ротора
- int position_difference = position - prev_position;
- if(position_difference > 512){
- final_position -= 1024;
- final_position += position_difference;
- }
- else {
- if (position_difference < -512){
- final_position += 1024;
- final_position += position_difference;
- }
- else final_position += position_difference;
- }
- if(sample_time >= dt * 100000){//срабатывает раз в 0.005 с
- angular_velocity = (int) 2 * PI * 100000 * final_position / (1024 * sample_time);//угловая скорость
- sample_time = 0;
- final_position = 0;
- }
- prev_position = position;
- //переход от 3-х фазной системы к 2-х фазной
- double theta = 2*PI * position / 1024;
- double I_alpha = (double) current_A;//ось A = ось alpha
- double I_beta = (double)((current_B - current_C)/sqrt_3);//ось beta
- //проекции на оси ротора
- //поворот декартовой системы координат
- Id = (int) (I_beta * sin(theta)+ I_alpha * cos(theta));
- Iq = (int) (I_beta * cos(theta)-I_alpha * sin(theta));
- desired_current_q = PI_velocity(desired_velocity - angular_velocity, 1.0, 8.0);//регулировка скорости
- desired_voltage_d = PI_current_d(desired_current_d - Id, 1.0, 3.0);//регулировка тока по оси d
- desired_voltage_q = PI_current_q(desired_current_q - Iq, 5.0, 1.0);//регулировка тока по оси q
- double U_alpha = desired_voltage_d * cos(theta) - desired_voltage_q * sin(theta);
- double U_beta = desired_voltage_q * cos(theta) + desired_voltage_d * sin(theta);
- voltage_A = (int)(250+250 * U_alpha / 12000.0);
- voltage_B = (int)(250+250 * 0.5 * (U_beta * sqrt_3 - U_alpha) / 12000.0);
- voltage_C = (int)(250-0.5 * 250 * (U_alpha + U_beta * sqrt_3) / 12000.0);
- TIM_SetCompare1(TIM1, voltage_A);
- TIM_SetCompare2(TIM1, voltage_B);
- TIM_SetCompare3(TIM1, voltage_C);
- }
- return 0;
- }
- // классический ассерт для STM32
- #ifdef USE_FULL_ASSERT
- void assert_failed(uint8_t * file, uint32_t line)
- {
- /* User can add his own implementation to report the file name and line number,
- ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
- (void)file;
- (void)line;
- while(1){};
- }
- #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement