我用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的有效期间采样,不知道对否),也请帮忙看一下这样设置正确吗?
此帖出自
小平头技术问答
一周热门 更多>