你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32G474 HRTIM无法正常触发ADC

[复制链接]
AlanCui 提问时间:2024-11-2 02:15 / 已解决

Hi,

我在用G474 HRTIM驱动BLDC电机,尝试使用ADC trigger在下管导通时(CMP2作为reset source)去触发低侧电流感应。现在的问题是即使CMP2中断回调可以被正常调用,PWM波形也正常,ADC依然没被触发。

因为没有使用CubeMX生成代码,是对着Cube包内的Example抄的,所以我想可能是某些信号配置在硬件上不可实现。但是我检查了Datasheet和用Cube生成的代码,我的配置是可以实现的。

ADC和HRTIM配置如下:

    __HAL_RCC_ADC12_CLK_ENABLE();

    this->adc1_handle.Instance                   = ADC1;
    this->adc1_handle.Init.ClockPrescaler        = ADC_CLOCK_SYNC_PCLK_DIV4;
    this->adc1_handle.Init.Resolution            = ADC_RESOLUTION_12B;
    this->adc1_handle.Init.DataAlign             = ADC_DATAALIGN_RIGHT;
    this->adc1_handle.Init.GainCompensation      = 0;
    this->adc1_handle.Init.ScanConvMode          = ADC_SCAN_DISABLE;
    this->adc1_handle.Init.EOCSelection          = ADC_EOC_SINGLE_CONV;
    this->adc1_handle.Init.LowPowerAutoWait      = DISABLE;
    this->adc1_handle.Init.ContinuousConvMode    = DISABLE;
    this->adc1_handle.Init.NbrOfConversion       = 1;
    this->adc1_handle.Init.DiscontinuousConvMode = DISABLE;
    this->adc1_handle.Init.ExternalTrigConv      = ADC_EXTERNALTRIG_HRTIM_TRG6;
    // this->adc1_handle.Init.ExternalTrigConv      = ADC_SOFTWARE_START;
    this->adc1_handle.Init.ExternalTrigConvEdge  = ADC_EXTERNALTRIGCONVEDGE_RISING;
    this->adc1_handle.Init.DMAContinuousRequests = DISABLE;
    this->adc1_handle.Init.Overrun               = ADC_OVR_DATA_OVERWRITTEN;
    this->adc1_handle.Init.OversamplingMode      = DISABLE;

    auto result = HAL_ADC_Init(&(this->adc1_handle));
    if (result != HAL_OK)
        throw hardware_error(result, "HAL_ADC_Init ADC1");

    ADC_MultiModeTypeDef multimode1 = {};
    multimode1.Mode                 = ADC_MODE_INDEPENDENT;

    result = HAL_ADCEx_MultiModeConfigChannel(&(this->adc1_handle), &multimode1);
    if (result != HAL_OK)
        throw hardware_error(result, "HAL_ADCEx_MultiModeConfigChannel ADC1");

    this->vopamp1_handle.Channel      = ADC_CHANNEL_VOPAMP1;
    this->vopamp1_handle.Rank         = ADC_REGULAR_RANK_1;
    this->vopamp1_handle.SamplingTime = ADC_SAMPLETIME_640CYCLES_5;
    this->vopamp1_handle.SingleDiff   = ADC_SINGLE_ENDED;
    this->vopamp1_handle.OffsetNumber = ADC_OFFSET_NONE;
    this->vopamp1_handle.Offset       = 0;

    result = HAL_ADC_ConfigChannel(&(this->adc1_handle), &(this->vopamp1_handle));
    if (result != HAL_OK)
        throw hardware_error(result, "HAL_ADC_ConfigChannel VOPAMP1");
    result = HAL_ADCEx_Calibration_Start(&(this->adc1_handle), ADC_SINGLE_ENDED);
    if (result != HAL_OK)
        throw hardware_error(result, "HAL_ADCEx_Calibration_Start ADC1");
    HAL_NVIC_SetPriority(ADC1_2_IRQn, 7, 0);
    HAL_NVIC_EnableIRQ(ADC1_2_IRQn);
    result = HAL_ADC_Start_IT(&(this->adc1_handle));
    if (result != HAL_OK)
        throw hardware_error(result, "HAL_ADC_Start ADC1");
__HAL_RCC_HRTIM1_CLK_ENABLE();

    gpio_hrtim_u_p.Pin       = GPIO_PIN_8;
    gpio_hrtim_u_p.Mode      = GPIO_MODE_AF_PP;
    gpio_hrtim_u_p.Pull      = GPIO_PULLDOWN;
    gpio_hrtim_u_p.Speed     = GPIO_SPEED_FREQ_VERY_HIGH;
    gpio_hrtim_u_p.Alternate = GPIO_AF13_HRTIM1;
    HAL_GPIO_Init(GPIOA, &gpio_hrtim_u_p);

    gpio_hrtim_u_n.Pin       = GPIO_PIN_9;
    gpio_hrtim_u_n.Mode      = GPIO_MODE_AF_PP;
    gpio_hrtim_u_n.Pull      = GPIO_PULLDOWN;
    gpio_hrtim_u_n.Speed     = GPIO_SPEED_FREQ_VERY_HIGH;
    gpio_hrtim_u_n.Alternate = GPIO_AF13_HRTIM1;
    HAL_GPIO_Init(GPIOA, &gpio_hrtim_u_n);

    gpio_hrtim_v_p.Pin       = GPIO_PIN_12;
    gpio_hrtim_v_p.Mode      = GPIO_MODE_AF_PP;
    gpio_hrtim_v_p.Pull      = GPIO_PULLDOWN;
    gpio_hrtim_v_p.Speed     = GPIO_SPEED_FREQ_VERY_HIGH;
    gpio_hrtim_v_p.Alternate = GPIO_AF13_HRTIM1;
    HAL_GPIO_Init(GPIOB, &gpio_hrtim_v_p);

    gpio_hrtim_v_n.Pin       = GPIO_PIN_13;
    gpio_hrtim_v_n.Mode      = GPIO_MODE_AF_PP;
    gpio_hrtim_v_n.Pull      = GPIO_PULLDOWN;
    gpio_hrtim_v_n.Speed     = GPIO_SPEED_FREQ_VERY_HIGH;
    gpio_hrtim_v_n.Alternate = GPIO_AF13_HRTIM1;
    HAL_GPIO_Init(GPIOB, &gpio_hrtim_v_n);

    gpio_hrtim_w_p.Pin       = GPIO_PIN_14;
    gpio_hrtim_w_p.Mode      = GPIO_MODE_AF_PP;
    gpio_hrtim_w_p.Pull      = GPIO_PULLDOWN;
    gpio_hrtim_w_p.Speed     = GPIO_SPEED_FREQ_VERY_HIGH;
    gpio_hrtim_w_p.Alternate = GPIO_AF13_HRTIM1;
    HAL_GPIO_Init(GPIOB, &gpio_hrtim_w_p);

    gpio_hrtim_w_n.Pin       = GPIO_PIN_15;
    gpio_hrtim_w_n.Mode      = GPIO_MODE_AF_PP;
    gpio_hrtim_w_n.Pull      = GPIO_PULLDOWN;
    gpio_hrtim_w_n.Speed     = GPIO_SPEED_FREQ_VERY_HIGH;
    gpio_hrtim_w_n.Alternate = GPIO_AF13_HRTIM1;
    HAL_GPIO_Init(GPIOB, &gpio_hrtim_w_n);

    HRTIM_TimeBaseCfgTypeDef   hrtim_timebase_cfg;
    HRTIM_TimerCtlTypeDef      hrtim_timer_ctl;
    HRTIM_TimerCfgTypeDef      hrtim_timer_cfg;
    HRTIM_CompareCfgTypeDef    hrtim_compare_cfg;
    HRTIM_OutputCfgTypeDef     hrtim_output_cfg;
    HRTIM_DeadTimeCfgTypeDef   hrtim_deadtime_cfg;
    HRTIM_ADCTriggerCfgTypeDef hrtim_adctrig_cfg;

    this->hrtim_handle.Instance                     = HRTIM1;
    this->hrtim_handle.Init.HRTIMInterruptResquests = HRTIM_IT_NONE;
    this->hrtim_handle.Init.SyncOptions             = HRTIM_SYNCOPTION_NONE;

    auto result = HAL_HRTIM_Init(&(this->hrtim_handle));
    if (result != HAL_OK)
        throw hardware_error(result, "HAL_HRTIM_Init");

    std::printf("hrtim: configured, no IT\n");

    result = HAL_HRTIM_DLLCalibrationStart(&(this->hrtim_handle), HRTIM_CALIBRATIONRATE_1);
    if (result != HAL_OK)
        throw hardware_error(result, "HAL_HRTIM_DLLCalibrationStart");

    result = HAL_HRTIM_PollForDLLCalibration(&(this->hrtim_handle), 10);
    if (result != HAL_OK)
        throw hardware_error(result, "HAL_HRTIM_PollForDLLCalibration");

    std::printf("hrtim: calibrated, period: HRTIM_CALIBRATIONRATE_1 (0.7ms)\n");

    timebase_period = (HAL_RCC_GetSysClockFreq() * (32 / this->prescaler_radio)) / this->desired_frequency;

    hrtim_timebase_cfg.Mode              = HRTIM_MODE_CONTINUOUS;
    hrtim_timebase_cfg.Period            = timebase_period;
    hrtim_timebase_cfg.PrescalerRatio    = HRTIM_PRESCALERRATIO_MUL4;
    hrtim_timebase_cfg.RepetitionCounter = 0;

    result = HAL_HRTIM_TimeBaseConfig(&(this->hrtim_handle), HRTIM_TIMERINDEX_MASTER, &hrtim_timebase_cfg);
    if (result != HAL_OK)
        throw hardware_error(result, "HAL_HRTIM_TimeBaseConfig Master");

    std::printf("hrtim: master timebase mode: HRTIM_MODE_CONTINUOUS, prescaler: HRTIM_PRESCALERRATIO_MUL4\n");
    std::printf("hrtim: master timebase period: %llu\n", (unsigned long long)timebase_period);

    result = HAL_HRTIM_TimeBaseConfig(&(this->hrtim_handle), HRTIM_TIMERINDEX_TIMER_A, &hrtim_timebase_cfg);
    if (result != HAL_OK)
        throw hardware_error(result, "HAL_HRTIM_TimeBaseConfig CHA");
    result = HAL_HRTIM_TimeBaseConfig(&(this->hrtim_handle), HRTIM_TIMERINDEX_TIMER_C, &hrtim_timebase_cfg);
    if (result != HAL_OK)
        throw hardware_error(result, "HAL_HRTIM_TimeBaseConfig CHC");
    result = HAL_HRTIM_TimeBaseConfig(&(this->hrtim_handle), HRTIM_TIMERINDEX_TIMER_D, &hrtim_timebase_cfg);
    if (result != HAL_OK)
        throw hardware_error(result, "HAL_HRTIM_TimeBaseConfig CHD");

    std::printf("hrtim: timebase mode: HRTIM_MODE_CONTINUOUS, prescaler: HRTIM_PRESCALERRATIO_MUL4\n");
    std::printf("hrtim: timebase period: %llu\n", (unsigned long long)timebase_period);

    hrtim_timer_ctl.DualChannelDacEnable = HRTIM_TIMER_DCDE_DISABLED;
    hrtim_timer_ctl.GreaterCMP1          = HRTIM_TIMERGTCMP1_EQUAL;
    hrtim_timer_ctl.GreaterCMP3          = HRTIM_TIMERGTCMP3_EQUAL;
    hrtim_timer_ctl.TrigHalf             = HRTIM_TIMERTRIGHALF_DISABLED;
    hrtim_timer_ctl.UpDownMode           = HRTIM_TIMERUPDOWNMODE_UP;

    result = HAL_HRTIM_WaveformTimerControl(&(this->hrtim_handle), HRTIM_TIMERINDEX_MASTER, &hrtim_timer_ctl);
    if (result != HAL_OK)
        throw hardware_error(result, "HAL_HRTIM_WaveformTimerControl Master");

    std::printf("hrtim: master timecontrol mode: up, HRTIM_TIMERGTCMP1_EQUAL, HRTIM_TIMERGTCMP3_EQUAL\n");

    result = HAL_HRTIM_WaveformTimerControl(&(this->hrtim_handle), HRTIM_TIMERINDEX_TIMER_A, &hrtim_timer_ctl);
    if (result != HAL_OK)
        throw hardware_error(result, "HAL_HRTIM_WaveformTimerControl CHA");
    result = HAL_HRTIM_WaveformTimerControl(&(this->hrtim_handle), HRTIM_TIMERINDEX_TIMER_C, &hrtim_timer_ctl);
    if (result != HAL_OK)
        throw hardware_error(result, "HAL_HRTIM_WaveformTimerControl CHC");
    result = HAL_HRTIM_WaveformTimerControl(&(this->hrtim_handle), HRTIM_TIMERINDEX_TIMER_D, &hrtim_timer_ctl);
    if (result != HAL_OK)
        throw hardware_error(result, "HAL_HRTIM_WaveformTimerControl CHD");

    std::printf("hrtim: timecontrol mode: up, HRTIM_TIMERGTCMP1_EQUAL, HRTIM_TIMERGTCMP3_EQUAL\n");

    hrtim_timer_cfg.InterruptRequests     = HRTIM_TIM_IT_REP;
    hrtim_timer_cfg.DMARequests           = HRTIM_TIM_DMA_NONE;
    hrtim_timer_cfg.DMASrcAddress         = 0x0000;
    hrtim_timer_cfg.DMADstAddress         = 0x0000;
    hrtim_timer_cfg.DMASize               = 0x1;
    hrtim_timer_cfg.HalfModeEnable        = HRTIM_HALFMODE_DISABLED;
    hrtim_timer_cfg.InterleavedMode       = HRTIM_INTERLEAVED_MODE_DISABLED;
    hrtim_timer_cfg.StartOnSync           = HRTIM_SYNCSTART_DISABLED;
    hrtim_timer_cfg.ResetOnSync           = HRTIM_SYNCRESET_DISABLED;
    hrtim_timer_cfg.DACSynchro            = HRTIM_DACSYNC_NONE;
    hrtim_timer_cfg.PreloadEnable         = HRTIM_PRELOAD_ENABLED;
    hrtim_timer_cfg.UpdateGating          = HRTIM_UPDATEGATING_INDEPENDENT;
    hrtim_timer_cfg.BurstMode             = HRTIM_TIMERBURSTMODE_MAINTAINCLOCK;
    hrtim_timer_cfg.RepetitionUpdate      = HRTIM_UPDATEONREPETITION_ENABLED;
    hrtim_timer_cfg.PushPull              = HRTIM_TIMPUSHPULLMODE_DISABLED;
    hrtim_timer_cfg.FaultEnable           = HRTIM_TIMFAULTENABLE_NONE;
    hrtim_timer_cfg.FaultLock             = HRTIM_TIMFAULTLOCK_READWRITE;
    hrtim_timer_cfg.DeadTimeInsertion     = HRTIM_TIMDEADTIMEINSERTION_DISABLED;
    hrtim_timer_cfg.DelayedProtectionMode = HRTIM_TIMER_A_B_C_DELAYEDPROTECTION_DISABLED;
    hrtim_timer_cfg.UpdateTrigger         = HRTIM_TIMUPDATETRIGGER_NONE;
    hrtim_timer_cfg.ResetTrigger          = HRTIM_TIMRESETTRIGGER_NONE;
    hrtim_timer_cfg.ResetUpdate           = HRTIM_TIMUPDATEONRESET_DISABLED;
    hrtim_timer_cfg.ReSyncUpdate          = HRTIM_TIMERESYNC_UPDATE_UNCONDITIONAL;

    result = HAL_HRTIM_WaveformTimerConfig(&(this->hrtim_handle), HRTIM_TIMERINDEX_MASTER, &hrtim_timer_cfg);
    if (result != HAL_OK)
        throw hardware_error(result, "HAL_HRTIM_WaveformTimerConfig CHA");

    std::printf(
        "hrtim: master timebase config: independent, repetition IT, no DMA, no reset, dead time insertion "
        "disabled\n");

    hrtim_timer_cfg.InterruptRequests     = HRTIM_TIM_IT_NONE;
    hrtim_timer_cfg.DMARequests           = HRTIM_TIM_DMA_NONE;
    hrtim_timer_cfg.DMASrcAddress         = 0x0000;
    hrtim_timer_cfg.DMADstAddress         = 0x0000;
    hrtim_timer_cfg.DMASize               = 0x1;
    hrtim_timer_cfg.HalfModeEnable        = HRTIM_HALFMODE_DISABLED;
    hrtim_timer_cfg.InterleavedMode       = HRTIM_INTERLEAVED_MODE_DISABLED;
    hrtim_timer_cfg.StartOnSync           = HRTIM_SYNCSTART_DISABLED;
    hrtim_timer_cfg.ResetOnSync           = HRTIM_SYNCRESET_DISABLED;
    hrtim_timer_cfg.DACSynchro            = HRTIM_DACSYNC_NONE;
    hrtim_timer_cfg.PreloadEnable         = HRTIM_PRELOAD_ENABLED;
    hrtim_timer_cfg.UpdateGating          = HRTIM_UPDATEGATING_INDEPENDENT;
    hrtim_timer_cfg.BurstMode             = HRTIM_TIMERBURSTMODE_MAINTAINCLOCK;
    hrtim_timer_cfg.RepetitionUpdate      = HRTIM_UPDATEONREPETITION_ENABLED;
    hrtim_timer_cfg.PushPull              = HRTIM_TIMPUSHPULLMODE_DISABLED;
    hrtim_timer_cfg.FaultEnable           = HRTIM_TIMFAULTENABLE_NONE;
    hrtim_timer_cfg.FaultLock             = HRTIM_TIMFAULTLOCK_READWRITE;
    hrtim_timer_cfg.DeadTimeInsertion     = HRTIM_TIMDEADTIMEINSERTION_ENABLED;
    hrtim_timer_cfg.DelayedProtectionMode = HRTIM_TIMER_A_B_C_DELAYEDPROTECTION_DISABLED;
    hrtim_timer_cfg.UpdateTrigger         = HRTIM_TIMUPDATETRIGGER_NONE;
    hrtim_timer_cfg.ResetTrigger          = HRTIM_TIMRESETTRIGGER_MASTER_PER;
    hrtim_timer_cfg.ResetUpdate           = HRTIM_TIMUPDATEONRESET_ENABLED;
    hrtim_timer_cfg.ReSyncUpdate          = HRTIM_TIMERESYNC_UPDATE_UNCONDITIONAL;

    result = HAL_HRTIM_WaveformTimerConfig(&(this->hrtim_handle), HRTIM_TIMERINDEX_TIMER_A, &hrtim_timer_cfg);
    if (result != HAL_OK)
        throw hardware_error(result, "HAL_HRTIM_WaveformTimerConfig CHA");
    result = HAL_HRTIM_WaveformTimerConfig(&(this->hrtim_handle), HRTIM_TIMERINDEX_TIMER_C, &hrtim_timer_cfg);
    if (result != HAL_OK)
        throw hardware_error(result, "HAL_HRTIM_WaveformTimerConfig CHC");

    hrtim_timer_cfg.DelayedProtectionMode = HRTIM_TIMER_D_E_DELAYEDPROTECTION_DISABLED;
    result = HAL_HRTIM_WaveformTimerConfig(&(this->hrtim_handle), HRTIM_TIMERINDEX_TIMER_D, &hrtim_timer_cfg);
    if (result != HAL_OK)
        throw hardware_error(result, "HAL_HRTIM_WaveformTimerConfig CHD");

    std::printf(
        "hrtim: timebase config: independent, no IT, no DMA, reset on master PER, dead time insertion enabled\n");

    // hrtim_compare_cfg.CompareValue       = -1;
    // hrtim_compare_cfg.AutoDelayedMode    = HRTIM_AUTODELAYEDMODE_REGULAR;
    // hrtim_compare_cfg.AutoDelayedTimeout = 0;

    // result = HAL_HRTIM_WaveformCompareConfig(
    //     &(this->hrtim_handle), HRTIM_TIMERINDEX_TIMER_A, HRTIM_COMPAREUNIT_1, &hrtim_compare_cfg);
    // if (result != HAL_OK)
    //     throw hardware_error(result, "HAL_HRTIM_WaveformCompareConfig CHA");
    // result = HAL_HRTIM_WaveformCompareConfig(
    //     &(this->hrtim_handle), HRTIM_TIMERINDEX_TIMER_A, HRTIM_COMPAREUNIT_2, &hrtim_compare_cfg);
    // if (result != HAL_OK)
    //     throw hardware_error(result, "HAL_HRTIM_WaveformCompareConfig CHA");
    // result = HAL_HRTIM_WaveformCompareConfig(
    //     &(this->hrtim_handle), HRTIM_TIMERINDEX_TIMER_A, HRTIM_COMPAREUNIT_3, &hrtim_compare_cfg);
    // if (result != HAL_OK)
    //     throw hardware_error(result, "HAL_HRTIM_WaveformCompareConfig CHA");
    // result = HAL_HRTIM_WaveformCompareConfig(
    //     &(this->hrtim_handle), HRTIM_TIMERINDEX_TIMER_C, HRTIM_COMPAREUNIT_1, &hrtim_compare_cfg);
    // if (result != HAL_OK)
    //     throw hardware_error(result, "HAL_HRTIM_WaveformCompareConfig CHC");
    // result = HAL_HRTIM_WaveformCompareConfig(
    //     &(this->hrtim_handle), HRTIM_TIMERINDEX_TIMER_C, HRTIM_COMPAREUNIT_2, &hrtim_compare_cfg);
    // if (result != HAL_OK)
    //     throw hardware_error(result, "HAL_HRTIM_WaveformCompareConfig CHC");
    // result = HAL_HRTIM_WaveformCompareConfig(
    //     &(this->hrtim_handle), HRTIM_TIMERINDEX_TIMER_C, HRTIM_COMPAREUNIT_3, &hrtim_compare_cfg);
    // if (result != HAL_OK)
    //     throw hardware_error(result, "HAL_HRTIM_WaveformCompareConfig CHC");
    // result = HAL_HRTIM_WaveformCompareConfig(
    //     &(this->hrtim_handle), HRTIM_TIMERINDEX_TIMER_D, HRTIM_COMPAREUNIT_1, &hrtim_compare_cfg);
    // if (result != HAL_OK)
    //     throw hardware_error(result, "HAL_HRTIM_WaveformCompareConfig CHD");
    // result = HAL_HRTIM_WaveformCompareConfig(
    //     &(this->hrtim_handle), HRTIM_TIMERINDEX_TIMER_D, HRTIM_COMPAREUNIT_2, &hrtim_compare_cfg);
    // if (result != HAL_OK)
    //     throw hardware_error(result, "HAL_HRTIM_WaveformCompareConfig CHD");
    // result = HAL_HRTIM_WaveformCompareConfig(
    //     &(this->hrtim_handle), HRTIM_TIMERINDEX_TIMER_D, HRTIM_COMPAREUNIT_3, &hrtim_compare_cfg);
    // if (result != HAL_OK)
    //     throw hardware_error(result, "HAL_HRTIM_WaveformCompareConfig CHD");

    std::printf("hrtim: compare config: not touch on all channels\n");

    hrtim_output_cfg.Polarity              = HRTIM_OUTPUTPOLARITY_HIGH;
    hrtim_output_cfg.SetSource             = HRTIM_OUTPUTSET_TIMCMP1;
    hrtim_output_cfg.ResetSource           = HRTIM_OUTPUTSET_TIMCMP2;
    hrtim_output_cfg.IdleMode              = HRTIM_OUTPUTIDLEMODE_NONE;
    hrtim_output_cfg.IdleLevel             = HRTIM_OUTPUTIDLELEVEL_INACTIVE;
    hrtim_output_cfg.FaultLevel            = HRTIM_OUTPUTFAULTLEVEL_NONE;
    hrtim_output_cfg.ChopperModeEnable     = HRTIM_OUTPUTCHOPPERMODE_DISABLED;
    hrtim_output_cfg.BurstModeEntryDelayed = HRTIM_OUTPUTBURSTMODEENTRY_REGULAR;

    result = HAL_HRTIM_WaveformOutputConfig(
        &(this->hrtim_handle), HRTIM_TIMERINDEX_TIMER_A, HRTIM_OUTPUT_TA1, &hrtim_output_cfg);
    if (result != HAL_OK)
        throw hardware_error(result, "HAL_HRTIM_WaveformCompareConfig TA1");
    result = HAL_HRTIM_WaveformOutputConfig(
        &(this->hrtim_handle), HRTIM_TIMERINDEX_TIMER_C, HRTIM_OUTPUT_TC1, &hrtim_output_cfg);
    if (result != HAL_OK)
        throw hardware_error(result, "HAL_HRTIM_WaveformCompareConfig TC1");
    result = HAL_HRTIM_WaveformOutputConfig(
        &(this->hrtim_handle), HRTIM_TIMERINDEX_TIMER_D, HRTIM_OUTPUT_TD1, &hrtim_output_cfg);
    if (result != HAL_OK)
        throw hardware_error(result, "HAL_HRTIM_WaveformCompareConfig TD1");

    hrtim_output_cfg.Polarity    = HRTIM_OUTPUTPOLARITY_HIGH;
    hrtim_output_cfg.SetSource   = HRTIM_OUTPUTSET_TIMCMP2;
    hrtim_output_cfg.ResetSource = HRTIM_OUTPUTSET_TIMCMP1;

    result = HAL_HRTIM_WaveformOutputConfig(
        &(this->hrtim_handle), HRTIM_TIMERINDEX_TIMER_A, HRTIM_OUTPUT_TA2, &hrtim_output_cfg);
    if (result != HAL_OK)
        throw hardware_error(result, "HAL_HRTIM_WaveformCompareConfig TA2");
    result = HAL_HRTIM_WaveformOutputConfig(
        &(this->hrtim_handle), HRTIM_TIMERINDEX_TIMER_C, HRTIM_OUTPUT_TC2, &hrtim_output_cfg);
    if (result != HAL_OK)
        throw hardware_error(result, "HAL_HRTIM_WaveformCompareConfig TC2");
    result = HAL_HRTIM_WaveformOutputConfig(
        &(this->hrtim_handle), HRTIM_TIMERINDEX_TIMER_D, HRTIM_OUTPUT_TD2, &hrtim_output_cfg);
    if (result != HAL_OK)
        throw hardware_error(result, "HAL_HRTIM_WaveformCompareConfig TD2");

    std::printf("hrtim: output config: Tx1 up at TIMPER and down at CMP1, Tx2 up at CMP1 and down at TIMPER\n");

    auto deadtime_period_rise = (unsigned int)(((unsigned long long)HAL_RCC_GetSysClockFreq() *
                                                (32 / this->prescaler_radio) * this->desired_deadtime_rise) /
                                               1000000000);
    auto deadtime_period_fall = (unsigned int)(((unsigned long long)HAL_RCC_GetSysClockFreq() *
                                                (32 / this->prescaler_radio) * this->desired_deadtime_fall) /
                                               1000000000);

    hrtim_deadtime_cfg.Prescaler       = HRTIM_TIMDEADTIME_PRESCALERRATIO_MUL4; // 1.73ns per step
    hrtim_deadtime_cfg.RisingValue     = deadtime_period_rise;
    hrtim_deadtime_cfg.RisingSign      = HRTIM_TIMDEADTIME_RISINGSIGN_POSITIVE;
    hrtim_deadtime_cfg.RisingLock      = HRTIM_TIMDEADTIME_RISINGLOCK_READONLY;
    hrtim_deadtime_cfg.RisingSignLock  = HRTIM_TIMDEADTIME_RISINGSIGNLOCK_READONLY;
    hrtim_deadtime_cfg.FallingValue    = deadtime_period_fall;
    hrtim_deadtime_cfg.FallingSign     = HRTIM_TIMDEADTIME_FALLINGSIGN_POSITIVE;
    hrtim_deadtime_cfg.FallingLock     = HRTIM_TIMDEADTIME_FALLINGLOCK_READONLY;
    hrtim_deadtime_cfg.FallingSignLock = HRTIM_TIMDEADTIME_FALLINGSIGNLOCK_READONLY;

    result = HAL_HRTIM_DeadTimeConfig(&(this->hrtim_handle), HRTIM_TIMERINDEX_TIMER_A, &hrtim_deadtime_cfg);
    if (result != HAL_OK)
        throw hardware_error(result, "HAL_HRTIM_DeadTimeConfig CHA");
    result = HAL_HRTIM_DeadTimeConfig(&(this->hrtim_handle), HRTIM_TIMERINDEX_TIMER_C, &hrtim_deadtime_cfg);
    if (result != HAL_OK)
        throw hardware_error(result, "HAL_HRTIM_DeadTimeConfig CHC");
    result = HAL_HRTIM_DeadTimeConfig(&(this->hrtim_handle), HRTIM_TIMERINDEX_TIMER_D, &hrtim_deadtime_cfg);
    if (result != HAL_OK)
        throw hardware_error(result, "HAL_HRTIM_DeadTimeConfig CHD");

    std::printf(
        "hrtim: deadtime config: rising %dns, falling %dns, period: rising %u, falling %u\n",
        (unsigned int)this->desired_deadtime_rise,
        (unsigned int)this->desired_deadtime_fall,
        (unsigned int)deadtime_period_rise,
        (unsigned int)deadtime_period_fall);

    hrtim_adctrig_cfg.Trigger      = HRTIM_ADCTRIGGERUPDATE_TIMER_A;
    hrtim_adctrig_cfg.UpdateSource = HRTIM_ADCTRIGGEREVENT6810_TIMERA_CMP2;
    result = HAL_HRTIM_ADCTriggerConfig(&(this->hrtim_handle), HRTIM_ADCTRIGGER_6, &hrtim_adctrig_cfg);
    if (result != HAL_OK)
        throw hardware_error(result, "HAL_HRTIM_ADCTriggerConfig CHA");
    result = HAL_HRTIM_ADCPostScalerConfig(&(this->hrtim_handle), HRTIM_ADCTRIGGER_6, 0x0);
    if (result != HAL_OK)
        throw hardware_error(result, "HAL_HRTIM_ADCPostScalerConfig CHA");
    std::printf("hrtim: adc trigger 6: Timer A, CMP2\n");

    hrtim_adctrig_cfg.Trigger      = HRTIM_ADCTRIGGERUPDATE_TIMER_C;
    hrtim_adctrig_cfg.UpdateSource = HRTIM_ADCTRIGGEREVENT6810_TIMERC_CMP2;
    result = HAL_HRTIM_ADCTriggerConfig(&(this->hrtim_handle), HRTIM_ADCTRIGGER_8, &hrtim_adctrig_cfg);
    if (result != HAL_OK)
        throw hardware_error(result, "HAL_HRTIM_ADCTriggerConfig CHC");
    result = HAL_HRTIM_ADCPostScalerConfig(&(this->hrtim_handle), HRTIM_ADCTRIGGER_8, 0x0);
    if (result != HAL_OK)
        throw hardware_error(result, "HAL_HRTIM_ADCPostScalerConfig CHC");
    std::printf("hrtim: adc trigger 8: Timer C, CMP2\n");

    hrtim_adctrig_cfg.Trigger      = HRTIM_ADCTRIGGERUPDATE_TIMER_D;
    hrtim_adctrig_cfg.UpdateSource = HRTIM_ADCTRIGGEREVENT6810_TIMERD_CMP2;
    result = HAL_HRTIM_ADCTriggerConfig(&(this->hrtim_handle), HRTIM_ADCTRIGGER_10, &hrtim_adctrig_cfg);
    if (result != HAL_OK)
        throw hardware_error(result, "HAL_HRTIM_ADCTriggerConfig CHD");
    result = HAL_HRTIM_ADCPostScalerConfig(&(this->hrtim_handle), HRTIM_ADCTRIGGER_10, 0x0);
    if (result != HAL_OK)
        throw hardware_error(result, "HAL_HRTIM_ADCPostScalerConfig CHD");
    std::printf("hrtim: adc trigger 10: Timer D, CMP2\n");

    __arisa_hrtim_handle = &(this->hrtim_handle);

    result = HAL_HRTIM_WaveformOutputStart(&(this->hrtim_handle), HRTIM_OUTPUT_TA1 | HRTIM_OUTPUT_TA2);
    if (result != HAL_OK)
        throw hardware_error(result, "HAL_HRTIM_WaveformOutputStart CHA");

    std::printf("hrtim: U phase started\n");

    result = HAL_HRTIM_WaveformOutputStart(&(this->hrtim_handle), HRTIM_OUTPUT_TC1 | HRTIM_OUTPUT_TC2);
    if (result != HAL_OK)
        throw hardware_error(result, "HAL_HRTIM_WaveformOutputStart CHC");

    std::printf("hrtim: V phase started\n");

    result = HAL_HRTIM_WaveformOutputStart(&(this->hrtim_handle), HRTIM_OUTPUT_TD1 | HRTIM_OUTPUT_TD2);
    if (result != HAL_OK)
        throw hardware_error(result, "HAL_HRTIM_WaveformOutputStart CHD");

    std::printf("hrtim: W phase started\n");

    result = HAL_HRTIM_WaveformCountStart(
        &(this->hrtim_handle),
        HRTIM_TIMERID_MASTER | HRTIM_TIMERID_TIMER_A | HRTIM_TIMERID_TIMER_C | HRTIM_TIMERID_TIMER_D);
    if (result != HAL_OK)
        throw hardware_error(result, "HAL_HRTIM_WaveformCountStart Master");

    __HAL_HRTIM_MASTER_ENABLE_IT(&(this->hrtim_handle), HRTIM_MASTER_IT_MREP);
    HAL_NVIC_SetPriority(HRTIM1_Master_IRQn, 6, 0);
    HAL_NVIC_EnableIRQ(HRTIM1_Master_IRQn);

    // __HAL_HRTIM_TIMER_ENABLE_IT(&(this->hrtim_handle), HRTIM_TIMERINDEX_TIMER_A, HRTIM_TIM_IT_CMP2);
    // HAL_NVIC_SetPriority(HRTIM1_TIMA_IRQn, 6, 1);
    // HAL_NVIC_EnableIRQ(HRTIM1_TIMA_IRQn);

    // __HAL_HRTIM_TIMER_ENABLE_IT(&(this->hrtim_handle), HRTIM_TIMERINDEX_TIMER_C, HRTIM_TIM_IT_CMP2);
    // HAL_NVIC_SetPriority(HRTIM1_TIMC_IRQn, 6, 2);
    // HAL_NVIC_EnableIRQ(HRTIM1_TIMC_IRQn);

    // __HAL_HRTIM_TIMER_ENABLE_IT(&(this->hrtim_handle), HRTIM_TIMERINDEX_TIMER_D, HRTIM_TIM_IT_CMP2);
    // HAL_NVIC_SetPriority(HRTIM1_TIMD_IRQn, 6, 3);
    // HAL_NVIC_EnableIRQ(HRTIM1_TIMD_IRQn);

感谢

Alan.

收藏 评论9 发布时间:2024-11-2 02:15

举报

9个回答
AlanCui 最优答案 回答时间:2024-11-5 13:46:09

AlanCui 发表于 2024-11-5 11:39</p>
<p>[md]我这里用CubeMX生成代码 Trigger6+TIMA CMP2触发,是可以正常转换的,您再确定一下?

[md]Hi,

最后确认问题在

hrtim_adctrig_cfg.Trigger      = HRTIM_ADCTRIGGERUPDATE_TIMER_A;
hrtim_adctrig_cfg.UpdateSource = HRTIM_ADCTRIGGEREVENT579_TIMERA_CMP3;

其中Tigger和UpdateSource设置错误的被对调了,交换就可以正常触发。

感谢您的帮助

xmshao 回答时间:2024-11-5 13:51:46

AlanCui 发表于 2024-11-5 11:39</p>
<p>[md]我这里用CubeMX生成代码 Trigger6+TIMA CMP2触发,是可以正常转换的,您再确定一下?

[md]哦,可以了。

我这边找到原因了,之前认为CMP2事件不可以,是因为我代码方面的原因。

之前 我针对HRTIM做了其它测试,对CMP2的比较值做了特别处理。 我屏蔽相关代码后,

Trigger 6/on tima cmp2也是可以的。

xmshao 回答时间:2024-11-4 18:13:10

AlanCui 发表于 2024-11-4 14:44
Hi,</p>
<p>感谢你的回复,我试图改用了CMP3触发,依然是<code>HAL_HRTIM_Compare3EventCallback</code> 可被观察到调 ...

[md]哦,HRTIM作为ADC的trigger可以有很多个,我刚好是基于 ADC Trigger 1做的测试,它刚好不支持TIMA CMP2事件作为触发源,没有进一步看其它的Trigger。

所以,我那里只是针对 ADC Trigger 1所言的。TIMA CMP2事件其实可以作为其它trigger源的,谢谢指正。

另外,我觉得ADC能否触发和数据的提取是基于中断还是DMA方式没有什么关系。 至少先要被触发启动。

xmshao 回答时间:2024-11-4 11:20:01
就你的问题,这边查看了相关手册并基于STM32G4开发板做了验证测试。


TIMA的CMP1和CMP2事件没法做ADC1的启动触发源,我们可以尝试使用其它hrtim事件,比方


CMP3、CMP4事件。


下面就是我基于CMP3事件来触发ADC,DMA搬运转换结果的截图。
rrr.png
AlanCui 回答时间:2024-11-4 14:44:41

xmshao 发表于 2024-11-4 11:20
就你的问题,这边查看了相关手册并基于STM32G4开发板做了验证测试。</p>
<p>

Hi,

感谢你的回复,我试图改用了CMP3触发,依然是HAL_HRTIM_Compare3EventCallback 可被观察到调用,ADC仍无法触发。值得注意的是,我使用的是ADC中断模式,这是否会造成问题?我在继续尝试其他组合。

另,我觉得你说的没有道理,请问CMP1/CMP2不能触发ADC1是实测出来的吗?但是,参照RM0440,p.382:e72071aa347a375b947211980dd6f7af.png

ADC1可以连接到TRG6,而TRG6显然可以由CMP2触发(p.924,RM0440):

image.png

且该组合在CubeMX6.12.0可以正常生成代码不报错:86e6df8176227da1bea25d798c502d3c.png

11a68d6b9d72248de423b8d5474f9ee9.png

同时 我的NUCLEO版本是C04,其上搭载的芯片是rev.X,我未在勘误表中找到关于该问题的描述,请问这是否是一个芯片缺陷?

86e6df8176227da1bea25d798c502d3c.png
AlanCui 回答时间:2024-11-5 08:29:43

Hi,

再三确认,ADC_HandleTypeDef的State成员为0x100,HAL_ADC_STATE_REG_BUSY ,这指示ADC就绪且准备触发,因此可以确定不是数据获取的问题,也不是ADC发生了什么错误。

令人疑惑的是HRTIM的波形输出依然正常,若通过软件触发ADC也正常,不像是什么配置错误。

我试着用CubeMX生成代码试试

请问STM32提供监听event的调试功能吗?

xmshao 回答时间:2024-11-5 11:36:32

AlanCui 发表于 2024-11-5 08:29
Hi,</p>
<p>再三确认,<code>ADC_HandleTypeDef</code>的State成员为0x100,<code>HAL_ADC_STATE_REG_BUSY</code> ,这指示ADC就绪且 ...

[md]后来,我使用你配置做了验证测试,即Trigger 6/ on TIMA cmp2来触发ADC,失败了。

若换成PER事件是可以的。后来,我尝试换成TIMA cmp4事件,也是可以的。不论中断还是DMA方式获取数据都可以。

image.png

你可以考虑换用别的CMP事件,至于为什么选择TIMA/CMP2做Trigger不行,一时半会还无法定论,得慢慢找原因。

AlanCui 回答时间:2024-11-5 11:39:23

xmshao 发表于 2024-11-5 11:36
后来,我使用你配置做了验证测试,即Trigger 6/ on TIMA cmp2来触发ADC,失败了。</p>
<p>若换成PER事件是 ...

[md]我这里用CubeMX生成代码 Trigger6+TIMA CMP2触发,是可以正常转换的,您再确定一下?

image.png

image.png

image.png

image.png

image.png
xmshao 回答时间:2024-11-5 14:27:43

AlanCui 发表于 2024-11-5 13:46
Hi,</p>
<p>最后确认问题在

[md]我更多地是给你些确认和协助,搞定就好,这里细节太多了~!

所属标签

相似问题

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版