硬件环境
芯片 STM32F334C8Tx
开发板 STM32F3348-Discovery
升降压电路
试验目的
输入电压范围2-5V,恒定升压到10V输出
实现原理
根据原理图得知,要实现BOOST功能,需要控制PA8恒为高电平
然后控制PA10为高电平,PA11低电平时为电感L3充电。
再控制PA11为高电平,PA10低电平,让电感与输入电压一起放电,达到升压的目的
软件配置
1、ADC采样
因为BOOST电路有纹波,为了实现ADC的精准采样,需要在纹波上升沿中间的瞬间进行准确采样
需要将ADC配置为HRTIM触发采样
首先进行ADC基本配置
hadc1.Instance = ADC1; //OK
hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;//OK
hadc1.Init.Resolution = ADC_RESOLUTION_12B;//OK
hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;//OK
hadc1.Init.ContinuousConvMode = DISABLE; //OK
hadc1.Init.DiscontinuousConvMode = DISABLE;//OK
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;//OK
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; //OK
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;//OK
hadc1.Init.NbrOfConversion = 1;//OK
hadc1.Init.DMAContinuousRequests = DISABLE;//OK
hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;//OK
hadc1.Init.LowPowerAutoWait = DISABLE; //OK
hadc1.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;//OK
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}
然后配置ADC为HRTIM触发采样
/** Configure Injected Channel
*/
sConfigInjected.InjectedChannel = ADC_CHANNEL_2; //OK
sConfigInjected.InjectedRank = ADC_INJECTED_RANK_1; //OK
sConfigInjected.InjectedSingleDiff = ADC_SINGLE_ENDED;//OK
sConfigInjected.InjectedNbrOfConversion = 2;//OK
sConfigInjected.InjectedSamplingTime = ADC_SAMPLETIME_7CYCLES_5;//OK
sConfigInjected.ExternalTrigInjecConvEdge = ADC_EXTERNALTRIGINJECCONV_EDGE_RISING;//OK
sConfigInjected.ExternalTrigInjecConv = ADC_EXTERNALTRIGINJECCONV_HRTIM_TRG2;//OK
sConfigInjected.AutoInjectedConv = DISABLE;//OK
sConfigInjected.InjectedDiscontinuousConvMode = DISABLE;//OK
sConfigInjected.QueueInjectedContext = DISABLE;//OK
sConfigInjected.InjectedOffset = 0;//OK
sConfigInjected.InjectedOffsetNumber = ADC_OFFSET_NONE;//OK
if (HAL_ADCEx_InjectedConfigChannel(&hadc1, &sConfigInjected) != HAL_OK)
{
Error_Handler();
}
/** Configure Injected Channel
*/
sConfigInjected.InjectedChannel = ADC_CHANNEL_4;//OK
sConfigInjected.InjectedRank = ADC_INJECTED_RANK_2;//OK
sConfigInjected.InjectedSamplingTime = ADC_SAMPLETIME_19CYCLES_5;//OK
if (HAL_ADCEx_InjectedConfigChannel(&hadc1, &sConfigInjected) != HAL_OK)
{
Error_Handler();
}
最后启动ADC
/* Run the ADC calibration in single-ended mode */
HAL_ADCEx_Calibration_Start(&hadc1, ADC_SINGLE_ENDED);
/* Start ADC1 Injected Conversions */
HAL_ADCEx_InjectedStart(&hadc1);
2、HRTIM配置
HRTIM需要配置的东西很多,需要对以下结构体进行初始化并调用库函数进行配置
HRTIM_TimeBaseCfgTypeDef timebase_config;
HRTIM_TimerCfgTypeDef timer_config;
HRTIM_OutputCfgTypeDef output_config;
HRTIM_CompareCfgTypeDef compare_config;
HRTIM_DeadTimeCfgTypeDef HRTIM_TIM_DeadTimeConfig;
HRTIM_ADCTriggerCfgTypeDef adc_trigger_config;
HRTIM_FaultCfgTypeDef fault_config;
首先是HRTIM的基本配置
/* ----------------------------*/
/* HRTIM Global initialization */
/* ----------------------------*/
/* Initialize the HRTIM handle (and clear it before for greater portability) */
hhrtim.Instance = HRTIM1; //OK
hhrtim.Init.HRTIMInterruptResquests = HRTIM_IT_NONE; //OK
hhrtim.Init.SyncOptions = HRTIM_SYNCOPTION_NONE; //OK
/* Initialize HRTIM */
HAL_HRTIM_Init(&hhrtim); //OK
/* HRTIM DLL calibration: periodic calibration, set period to 14祍 */
HAL_HRTIM_DLLCalibrationStart(&hhrtim, HRTIM_CALIBRATIONRATE_14); //OK
/* Wait calibration completion*/
if (HAL_HRTIM_PollForDLLCalibration(&hhrtim, 100) != HAL_OK) //OK
{
Error_Handler(); /* if DLL or clock is not correctly set */
}
再配置HRTIM的频率为250KHZ
timebase_config.Period = BUCK_PWM_PERIOD; /* 250kHz switching frequency */ //OK
timebase_config.RepetitionCounter = 31; /* 1 ISR every 32 PWM periods */ //OK
timebase_config.PrescalerRatio = HRTIM_PRESCALERRATIO_MUL32; //OK
timebase_config.Mode = HRTIM_MODE_CONTINUOUS; //OK
HAL_HRTIM_TimeBaseConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_A, &timebase_config);
HAL_HRTIM_TimeBaseConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_B, &timebase_config);
再对TIMERA和TIMEB的一些参数进行配置
timer_config.DMARequests = HRTIM_TIM_DMA_NONE;//OK
timer_config.DMASrcAddress = 0x0;//OK
timer_config.DMADstAddress = 0x0;//OK
timer_config.DMASize = 0x0;//OK
timer_config.HalfModeEnable = HRTIM_HALFMODE_DISABLED;//OK
timer_config.StartOnSync = HRTIM_SYNCSTART_DISABLED;//OK
timer_config.ResetOnSync = HRTIM_SYNCRESET_DISABLED;//OK
timer_config.DACSynchro = HRTIM_DACSYNC_NONE;//OK
timer_config.PreloadEnable = HRTIM_PRELOAD_ENABLED;//OK
timer_config.UpdateGating = HRTIM_UPDATEGATING_INDEPENDENT;//OK
timer_config.BurstMode = HRTIM_TIMERBURSTMODE_MAINTAINCLOCK;//OK
timer_config.RepetitionUpdate = HRTIM_UPDATEONREPETITION_ENABLED;//OK
timer_config.ResetUpdate = HRTIM_TIMUPDATEONRESET_DISABLED; //OK
timer_config.InterruptRequests = HRTIM_TIM_IT_REP; //OK
timer_config.PushPull = HRTIM_TIMPUSHPULLMODE_DISABLED;//OK
timer_config.FaultEnable = HRTIM_TIMFAULTENABLE_FAULT1;//OK
timer_config.FaultLock = HRTIM_TIMFAULTLOCK_READWRITE;//OK
timer_config.DeadTimeInsertion = HRTIM_TIMDEADTIMEINSERTION_ENABLED;//OK
timer_config.DelayedProtectionMode = HRTIM_TIMER_A_B_C_DELAYEDPROTECTION_DISABLED;//OK
timer_config.UpdateTrigger= HRTIM_TIMUPDATETRIGGER_NONE;//OK
timer_config.ResetTrigger = HRTIM_TIMRESETTRIGGER_NONE;//OK
HAL_HRTIM_WaveformTimerConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_A, &timer_config);
HAL_HRTIM_WaveformTimerConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_B, &timer_config);
对 TA1 TA2 TB1 and TB2 的波形进行配置
output_config.Polarity = HRTIM_OUTPUTPOLARITY_HIGH; //OK
output_config.SetSource = HRTIM_OUTPUTSET_TIMCMP1;//OK
output_config.ResetSource = HRTIM_OUTPUTRESET_TIMPER;
output_config.IdleMode = HRTIM_OUTPUTIDLEMODE_NONE;//OK
output_config.IdleLevel = HRTIM_OUTPUTIDLELEVEL_INACTIVE;//OK
output_config.FaultLevel = HRTIM_OUTPUTFAULTLEVEL_INACTIVE;
output_config.ChopperModeEnable = HRTIM_OUTPUTCHOPPERMODE_DISABLED;//OK
output_config.BurstModeEntryDelayed = HRTIM_OUTPUTBURSTMODEENTRY_REGULAR;//OK
HAL_HRTIM_WaveformOutputConfig(&hhrtim,
HRTIM_TIMERINDEX_TIMER_A,
HRTIM_OUTPUT_TA1,
&output_config);
HAL_HRTIM_WaveformOutputConfig(&hhrtim,
HRTIM_TIMERINDEX_TIMER_A,
HRTIM_OUTPUT_TA2,
&output_config);
/* Set compare registers for duty cycle on TA1 在TA1上设置占空比寄存器*/
compare_config.AutoDelayedMode = HRTIM_AUTODELAYEDMODE_REGULAR;
compare_config.AutoDelayedTimeout = 0;
compare_config.CompareValue = BUCK_PWM_PERIOD - 0x60; /* Start with minimal duty cycle */
HAL_HRTIM_WaveformCompareConfig(&hhrtim,
HRTIM_TIMERINDEX_TIMER_A,
HRTIM_COMPAREUNIT_1,
&compare_config);
output_config.Polarity = HRTIM_OUTPUTPOLARITY_HIGH;
output_config.SetSource = HRTIM_OUTPUTSET_TIMCMP1;
output_config.ResetSource = HRTIM_OUTPUTRESET_TIMPER;
output_config.IdleMode = HRTIM_OUTPUTIDLEMODE_NONE;
output_config.IdleLevel = HRTIM_OUTPUTIDLELEVEL_INACTIVE;
output_config.FaultLevel = HRTIM_OUTPUTFAULTLEVEL_INACTIVE;
output_config.ChopperModeEnable = HRTIM_OUTPUTCHOPPERMODE_DISABLED;
output_config.BurstModeEntryDelayed = HRTIM_OUTPUTBURSTMODEENTRY_REGULAR;
HAL_HRTIM_WaveformOutputConfig(&hhrtim,
HRTIM_TIMERINDEX_TIMER_B,
HRTIM_OUTPUT_TB1,
&output_config);
HAL_HRTIM_WaveformOutputConfig(&hhrtim,
HRTIM_TIMERINDEX_TIMER_B,
HRTIM_OUTPUT_TB2,
&output_config);
/* Set compare registers for duty cycle on TB1 */
compare_config.AutoDelayedMode = HRTIM_AUTODELAYEDMODE_REGULAR;
compare_config.AutoDelayedTimeout = 0;
compare_config.CompareValue = BUCK_PWM_PERIOD+1; /* 0% duty cycle */
HAL_HRTIM_WaveformCompareConfig(&hhrtim,
HRTIM_TIMERINDEX_TIMER_B,
HRTIM_COMPAREUNIT_1,
&compare_config);
死区时间配置,这一步配置完后,PA10和PA11高低电平不会完全重叠,将留一小段时间同时为低电平,如果不这样做的话,输入电源将存在短路现象
HRTIM_TIM_DeadTimeConfig.FallingLock = HRTIM_TIMDEADTIME_FALLINGLOCK_WRITE;//OK
HRTIM_TIM_DeadTimeConfig.FallingSign = HRTIM_TIMDEADTIME_FALLINGSIGN_POSITIVE; //OK
HRTIM_TIM_DeadTimeConfig.FallingSignLock = HRTIM_TIMDEADTIME_FALLINGSIGNLOCK_READONLY; //OK
HRTIM_TIM_DeadTimeConfig.FallingValue = DT_FALLING; //OK
HRTIM_TIM_DeadTimeConfig.Prescaler = HRTIM_TIMDEADTIME_PRESCALERRATIO_MUL8;
HRTIM_TIM_DeadTimeConfig.RisingLock = HRTIM_TIMDEADTIME_RISINGLOCK_WRITE; //OK
HRTIM_TIM_DeadTimeConfig.RisingSign = HRTIM_TIMDEADTIME_RISINGSIGN_POSITIVE; //OK
HRTIM_TIM_DeadTimeConfig.RisingSignLock = HRTIM_TIMDEADTIME_RISINGSIGNLOCK_READONLY; //OK
HRTIM_TIM_DeadTimeConfig.RisingValue = DT_RISING; //OK
HAL_HRTIM_DeadTimeConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_A, &HRTIM_TIM_DeadTimeConfig);
/* Same parameters for Timer B */
HAL_HRTIM_DeadTimeConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_B, &HRTIM_TIM_DeadTimeConfig);
配置之后的波形:
将ADC与HRTIM关联起来,让HRTIM触发ADC采样
compare_config.AutoDelayedMode = HRTIM_AUTODELAYEDMODE_REGULAR;
compare_config.CompareValue = BUCK_PWM_PERIOD/2; /* Samples at 50% of period */
compare_config.AutoDelayedTimeout = 0;
HAL_HRTIM_WaveformCompareConfig(&hhrtim,
HRTIM_TIMERINDEX_TIMER_A,
HRTIM_COMPAREUNIT_2,
&compare_config);
adc_trigger_config.Trigger = HRTIM_ADCTRIGGEREVENT24_TIMERA_CMP2;
adc_trigger_config.UpdateSource = HRTIM_ADCTRIGGERUPDATE_TIMER_A;
HAL_HRTIM_ADCTriggerConfig(&hhrtim,
HRTIM_ADCTRIGGER_2,
&adc_trigger_config);
故障模式配置,故障输入时(PA12为低电平认为),将不输出PWM
/* ---------------------*/
/* FAULT initialization */
/* ---------------------*/
fault_config.Filter = HRTIM_FAULTFILTER_NONE;//OK
fault_config.Lock = HRTIM_FAULTLOCK_READWRITE;//OK
fault_config.Polarity = HRTIM_FAULTPOLARITY_LOW;//OK
fault_config.Source = HRTIM_FAULTSOURCE_DIGITALINPUT; //OK
HAL_HRTIM_FaultConfig(&hhrtim,
HRTIM_FAULT_1,
&fault_config);
HAL_HRTIM_FaultModeCtl(&hhrtim,
HRTIM_FAULT_1,
HRTIM_FAULTMODECTL_ENABLED);
ADC采样数据的读取
根据原理图的分压电阻,来读取ADC并计算电压
/* -------------------------------------------------------------------------*/
/* Input and output voltages measures (can be displayed in a watch window) */
/* -------------------------------------------------------------------------*/
Vin = (HAL_ADCEx_InjectedGetValue(&AdcHandle, ADC_INJECTED_RANK_1) * 3300)/0xFFF;
/* VIN bridge conversion is 4.97 (6.8K / 6.8K + 27K) */
Vin = (497 * Vin )/100; /* Values in mV (for debug convenience) */
Vout = (HAL_ADCEx_InjectedGetValue(&AdcHandle, ADC_INJECTED_RANK_2) * 3300)/0xFFF;
/* VOUT bridge conversion is 5.03 (3.3K / 3.3K + 13.3K) */
Vout = (503 * Vout)/100; /* Values in mV (for debug convenience) */
BOOST自动升压
首先永久开启PA8为高电平
/* BUCK side PMOS turned ON permanently BUCK侧PMOS永久开启 */
__HAL_HRTIM_SETCOMPARE(&hhrtim, HRTIM_TIMERINDEX_TIMER_A, HRTIM_COMPAREUNIT_1, BUCK_PWM_PERIOD);
读取当前占空比
CurrentDuty = __HAL_HRTIM_GETCOMPARE(&hhrtim, HRTIM_TIMERINDEX_TIMER_B, HRTIM_COMPAREUNIT_1);
根据电压来自动调节占空比大小,boost_cnt的作用是,让调节慢一些,否则调节太快了可能不稳定
if(Vout <= 1000)
{
if(CurrentDuty > (BUCK_PWM_PERIOD / 4))
CurrentDuty -= 2;
}
else if(Vout <= 9000)
{
if(CurrentDuty > (BUCK_PWM_PERIOD / 4))
CurrentDuty -= 1;
}
else if(Vout <= 9980)
{
boost_cnt ++;
if(boost_cnt >= 10)
{
if(CurrentDuty > (BUCK_PWM_PERIOD / 4))
CurrentDuty -= 1;
boost_cnt = 0;
}
}
if(Vout >= 10020)
{
boost_cnt ++;
if(boost_cnt >= 10)
{
if(CurrentDuty < BUCK_PWM_PERIOD - 1)
CurrentDuty += 1;
boost_cnt = 0;
}
}
else if(Vout >= 15000)
{
if(CurrentDuty < BUCK_PWM_PERIOD - 2)
CurrentDuty += 2;
}
重新配置占空比
if(Vout <= 9900)
{
__HAL_HRTIM_SETCOMPARE(&hhrtim, HRTIM_TIMERINDEX_TIMER_B, HRTIM_COMPAREUNIT_1, CurrentDuty);
}
if(Vout >= 10100)
{
__HAL_HRTIM_SETCOMPARE(&hhrtim, HRTIM_TIMERINDEX_TIMER_B, HRTIM_COMPAREUNIT_1, CurrentDuty);
}
结果
根据KEIL的WATCH窗口,可以看到数据,测试成功