stm32控制电机电流采样问题

2019-03-23 20:12发布

我用stm32F103vb控制同步电机进行电流采样,可以生成SVPWM波,也能采到AB两相的电流,但总感觉电流采样值不是在PWM波的有效期间采样的,也就是说TIM1触发AD的采样时刻不是在PWM波的有效期间,想问一下各位大侠,怎么通过软件设置TIM1定时器的上溢或下溢?采样AB相电流我用两路AD,采用的是同时注入模式,为的是保证同时采样(感觉TIM1触发AD的规则模式不能在SVPWM的有效期间采样,不知道对否),也请帮忙看一下这样设置正确吗?程序如下:

void imeas_Init(imeas *v){  ADC_InitTypeDef ADC_InitStructure;  GPIO_InitTypeDef GPIO_InitStructure;  DMA_InitTypeDef DMA_InitStructure;    //----------------------test-----------------------------------    GPIO_InitStructure.GPIO_Pin = Test_PIN;  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  GPIO_Init(GPIOB, &GPIO_InitStructure);    // adc1 & adc2 pins //////////////////////////////////////////////////////////  GPIO_StructInit(&GPIO_InitStructure);  // phase_A  GPIO_InitStructure.GPIO_Pin = PHASE_A_GPIO_PIN;    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;  GPIO_Init(PHASE_A_GPIO_PORT, &GPIO_InitStructure);      // phase_B  GPIO_InitStructure.GPIO_Pin = PHASE_B_GPIO_PIN;    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;  GPIO_Init(PHASE_B_GPIO_PORT, &GPIO_InitStructure);       // reset adc  ADC_DeInit(PHASE_A_ADC); //开启PHASE_A_ADC  ADC_DeInit(PHASE_B_ADC);
    // ENABLE adc  ADC_Cmd(PHASE_A_ADC, ENABLE);  ADC_Cmd(PHASE_B_ADC, ENABLE);      // adc1&2 configuration    ADC_StructInit(&ADC_InitStructure);  ADC_InitStructure.ADC_Mode =ADC_Mode_InjecSimult;   ADC_InitStructure.ADC_ScanConvMode = DISABLE;          ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Left;  ADC_InitStructure.ADC_NbrOfChannel = 1;                  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigInjecConv_T1_TRGO ;

    ADC_Init(PHASE_A_ADC, &ADC_InitStructure);  ADC_Init(PHASE_B_ADC, &ADC_InitStructure);
   /* Set injected sequencer length */  ADC_InjectedSequencerLengthConfig(ADC1, 1);  ADC_InjectedSequencerLengthConfig(ADC2, 1);    /* ADC1 injected channel configuration */   ADC_InjectedChannelConfig(ADC1, PHASE_A_ADC_CHANNEL,1,ADC_SampleTime_55Cycles5);  ADC_InjectedChannelConfig(ADC2, PHASE_B_ADC_CHANNEL,1,ADC_SampleTime_55Cycles5);    /* ADC1 injected external trigger configuration */  ADC_ExternalTrigInjectedConvConfig(ADC1, ADC_ExternalTrigInjecConv_T1_TRGO);  ADC_ExternalTrigInjectedConvConfig(ADC2, ADC_ExternalTrigInjecConv_T1_TRGO);
    /* Enable ADC1 injected external trigger conversion */  ADC_ExternalTrigInjectedConvCmd(ADC1, ENABLE);  ADC_ExternalTrigInjectedConvCmd(ADC2, ENABLE);     //ADC_SetInjectedOffset( PHASE_A_ADC, ADC_InjectedChannel_1,0x0 ); // ADC_SetInjectedOffset( PHASE_B_ADC, ADC_InjectedChannel_2,0x0 );  
  
          // clear pending flag
  ADC_ClearFlag(PHASE_A_ADC, ADC_FLAG_JEOC);  ADC_ClearFlag(PHASE_B_ADC, ADC_FLAG_JEOC);
  
    // 禁止中断
  ADC_ITConfig(PHASE_A_ADC, ADC_IT_JEOC, ENABLE);  ADC_ITConfig(PHASE_B_ADC, ADC_IT_JEOC, ENABLE);    // 打开adc外部触发转换
     /* Enable ADC1 injected external trigger conversion */  ADC_ExternalTrigInjectedConvCmd(PHASE_A_ADC, ENABLE);  ADC_ExternalTrigInjectedConvCmd(PHASE_B_ADC, ENABLE);    // enable adc  ADC_Cmd(PHASE_A_ADC, ENABLE);  ADC_Cmd(PHASE_B_ADC, ENABLE);
    //启动ADC1&ADC3自校准,th  /* Enable ADC1 reset calibaration register */     ADC_ResetCalibration(PHASE_A_ADC);  //重置校准   /* Check the end of ADC1 reset calibration register */  while(ADC_GetResetCalibrationStatus(PHASE_A_ADC)); //等待重置校准完成   /* Start ADC1 calibaration */  ADC_StartCalibration(PHASE_A_ADC);  /* Check the end of ADC1 calibration */  while(ADC_GetCalibrationStatus(PHASE_A_ADC));    /* Enable ADC3 reset calibaration register */      ADC_ResetCalibration(PHASE_B_ADC);  while(ADC_GetResetCalibrationStatus(PHASE_B_ADC));  ADC_StartCalibration(PHASE_B_ADC);  while(ADC_GetCalibrationStatus(PHASE_B_ADC));  
      GPIO_ResetBits(GPIOB, Test_PIN);  }
//--------------------------------------------------------------
void imeas_Calc(imeas *v){  s16 dataQ15;      GPIO_SetBits(GPIOB, Test_PIN);    
  while(!(ADC_GetFlagStatus(PHASE_A_ADC,ADC_FLAG_JEOC) & ADC_GetFlagStatus(PHASE_B_ADC,ADC_FLAG_JEOC))) 
  {     flag1++;   }     flag2++;
  //Ia
  adc1_value_test = ADC_GetInjectedConversionValue(PHASE_A_ADC, ADC_InjectedChannel_1);  adc1_value_test = adc1_value_test *2;  dataQ15 = adc1_value_test^0x8000;  v->ImeasA =  _IQ15toIQ(dataQ15);        //Ib
  adc2_value_test = ADC_GetInjectedConversionValue(PHASE_B_ADC, ADC_InjectedChannel_1);  adc2_value_test = adc2_value_test *2;  dataQ15 = adc2_value_test^0x8000;  v->ImeasB =  _IQ15toIQ(dataQ15);

  ADC_ClearFlag(PHASE_A_ADC, ADC_FLAG_JEOC);       ADC_ClearFlag(PHASE_B_ADC, ADC_FLAG_JEOC);
}
//------------------------------------------------------------------------------------------------------------------------------------------
void  tim_conf(void){  // tim1  //////////////////////////////////////////////////////////////////////////////    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;  TIM_OCInitTypeDef TIM_OCInitStructure;  TIM_BDTRInitTypeDef TIM_BDTRInitStructure;  GPIO_InitTypeDef GPIO_InitStructure;  GPIO_PinRemapConfig(GPIO_FullRemap_TIM1, ENABLE);
    TIM_DeInit(TIM1);    // timebase  设置PWM频率    TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);  TIM_TimeBaseStructure.TIM_Prescaler = PWM_PRSC;    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_CenterAligned1;  TIM_TimeBaseStructure.TIM_Period = T_PERIOD;   ///1800  TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;   TIM_TimeBaseStructure.TIM_RepetitionCounter =REP_RATE;  //1  TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
      // OC1 设置1通道占空比  TIM_OCStructInit(&TIM_OCInitStructure);  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;    // 输出使能  TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;  // 输出使能  TIM_OCInitStructure.TIM_Pulse = 0; // 脉冲宽度  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;     // 高电平有效  TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;   // 高电平有效  TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;  // 空闲状态输出低电平  TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; // 空闲状态输出低电平  TIM_OC1Init(TIM1, &TIM_OCInitStructure);  TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);    // OC2  TIM_OCInitStructure.TIM_Pulse = 0; //dummy value  TIM_OC2Init(TIM1, &TIM_OCInitStructure);  TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);    // OC3  TIM_OCInitStructure.TIM_Pulse = 0; //dummy value  0  TIM_OC3Init(TIM1, &TIM_OCInitStructure);  TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);      GPIO_StructInit(&GPIO_InitStructure);  //-->channel 1,2,3  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 |  GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 |  GPIO_Pin_13;  GPIO_InitStructure.GPIO_Mode =  GPIO_Mode_AF_PP;  //推挽复用输出  ///GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  GPIO_Init(GPIOE, &GPIO_InitStructure);     // BDTR    TIM_BDTRStructInit(&TIM_BDTRInitStructure);  TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;  TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;  TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1;  TIM_BDTRInitStructure.TIM_DeadTime = DT_PERIOD; // 死区时间  TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable; // 禁用刹车  TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High;  // 刹车输入高电平有效  TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Disable;  TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);       TIM_ClearITPendingBit(TIM1, TIM_IT_Update);   TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);     TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_Update);
   pwmgen_parameter.PeriodMax = T_PERIOD;   }被这折磨一周了,还没出来,请各位大侠帮忙看一下啊:怎么通过软件设置TIM1定时器的上溢或下溢?采样AB相电流我用两路AD,采用的是同时注入模式,为的是保证同时采样(感觉TIM1触发AD的规则模式不能在SVPWM的有效期间采样,不知道对否),也请帮忙看一下这样设置正确吗? 此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。