STM32F3 使用 HRTIM 与 ADC实现精准BOOST转换

硬件环境

芯片 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窗口,可以看到数据,测试成功
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • 8
    点赞
  • 68
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值