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.
[md]Hi,
最后确认问题在
其中Tigger和UpdateSource设置错误的被对调了,交换就可以正常触发。
感谢您的帮助
[md]哦,可以了。
我这边找到原因了,之前认为CMP2事件不可以,是因为我代码方面的原因。
之前 我针对HRTIM做了其它测试,对CMP2的比较值做了特别处理。 我屏蔽相关代码后,
Trigger 6/on tima cmp2也是可以的。
[md]哦,HRTIM作为ADC的trigger可以有很多个,我刚好是基于 ADC Trigger 1做的测试,它刚好不支持TIMA CMP2事件作为触发源,没有进一步看其它的Trigger。
所以,我那里只是针对 ADC Trigger 1所言的。TIMA CMP2事件其实可以作为其它trigger源的,谢谢指正。
另外,我觉得ADC能否触发和数据的提取是基于中断还是DMA方式没有什么关系。 至少先要被触发启动。
TIMA的CMP1和CMP2事件没法做ADC1的启动触发源,我们可以尝试使用其它hrtim事件,比方
CMP3、CMP4事件。
下面就是我基于CMP3事件来触发ADC,DMA搬运转换结果的截图。
Hi,
感谢你的回复,我试图改用了CMP3触发,依然是
HAL_HRTIM_Compare3EventCallback
可被观察到调用,ADC仍无法触发。值得注意的是,我使用的是ADC中断模式,这是否会造成问题?我在继续尝试其他组合。另,我觉得你说的没有道理,请问CMP1/CMP2不能触发ADC1是实测出来的吗?但是,参照RM0440,p.382:
ADC1可以连接到TRG6,而TRG6显然可以由CMP2触发(p.924,RM0440):
且该组合在CubeMX6.12.0可以正常生成代码不报错:
同时 我的NUCLEO版本是C04,其上搭载的芯片是rev.X,我未在勘误表中找到关于该问题的描述,请问这是否是一个芯片缺陷?
Hi,
再三确认,
ADC_HandleTypeDef
的State成员为0x100,HAL_ADC_STATE_REG_BUSY
,这指示ADC就绪且准备触发,因此可以确定不是数据获取的问题,也不是ADC发生了什么错误。令人疑惑的是HRTIM的波形输出依然正常,若通过软件触发ADC也正常,不像是什么配置错误。
我试着用CubeMX生成代码试试
请问STM32提供监听event的调试功能吗?
[md]后来,我使用你配置做了验证测试,即Trigger 6/ on TIMA cmp2来触发ADC,失败了。
若换成PER事件是可以的。后来,我尝试换成TIMA cmp4事件,也是可以的。不论中断还是DMA方式获取数据都可以。
你可以考虑换用别的CMP事件,至于为什么选择TIMA/CMP2做Trigger不行,一时半会还无法定论,得慢慢找原因。
[md]我这里用CubeMX生成代码 Trigger6+TIMA CMP2触发,是可以正常转换的,您再确定一下?
[md]我更多地是给你些确认和协助,搞定就好,这里细节太多了~!