亲爱的社区,
一段时间以来,我尝试设置 STM32F429ZI 的硬件以定期触发具有 2 个通道的不连续 ADC 转换。
我在 PWM 模式下使用 tiM1 通过 TIM CH3 生成 CC 中断。定时器以中心模式运行,依次向上和向下计数。TIM1 CC3 中断应该在每个 PWM 周期触发一次 ADC 转换(当计数器向上计数时)。
使用 NVIC ISR 和 Osci 测试 CC3 中断生成显示了预期的行为。
使用 ADC_IRQHandler 测试 ADC 转换时序显示在一个 PWM 周期内有 2 次调用此 ISR。当我更改 CH3 的捕获比较值时,两个 ADC_IRQHanlder 调用对称地偏移 PWM 周期的中心。因此,我认为 ADC 在 CH3 的两次捕获比较匹配时都被触发。我希望它只在第一次捕获比较事件时被触发。
我是不是在某个地方错误地配置了定时器或 adc 触发器设置?
定时器配置如下:
- /**
- ******************************************************************************
- * Configure project specific GPIO Pins to be used as output with the TIM1 PWM.
- ******************************************************************************
- * TIM1_CH1 -> PE9
- * TIM1_CH1N -> PE8
- * TIM1_CH2 -> PE11
- * TIM1_CH2N -> PE10
- */
- GPIO_InitStruct.Pin = LL_GPIO_PIN_8 | LL_GPIO_PIN_9
- | LL_GPIO_PIN_10 | LL_GPIO_PIN_11
- | LL_GPIO_PIN_12 | LL_GPIO_PIN_13;
- GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
- GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
- GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
- GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
- GPIO_InitStruct.Alternate = LL_GPIO_AF_1;
- LL_GPIO_Init(GPIOE, &GPIO_InitStruct);
- LL_TIM_DisableCounter(TIM1);
- LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM1);
- /* Timer initialization */
- TIM_InitStruct.Prescaler = TIM_CLOCKPRESCALER_DIV1;
- TIM_InitStruct.CounterMode = PWM1_COUNTERMODE;
- TIM_InitStruct.Autoreload = PWM_ARR;
- TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
- TIM_InitStruct.RepetitionCounter = CTRL_LOOP_PRESCALER - 1;
- LL_TIM_Init(TIM1, &TIM_InitStruct);
- /*
- ******************************************************************************
- * Channel Configuration
- ******************************************************************************
- */
- TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_PWM1;
- TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_ENABLE;
- TIM_OC_InitStruct.OCNState = LL_TIM_OCSTATE_ENABLE;
- TIM_OC_InitStruct.CompareValue = TIM1->ARR*3/4; // initial duty cycle
- TIM_OC_InitStruct.OCPolarity = LL_TIM_OCPOLARITY_HIGH;
- TIM_OC_InitStruct.OCNPolarity = LL_TIM_OCPOLARITY_LOW;
- TIM_OC_InitStruct.OCIdleState = LL_TIM_OCIDLESTATE_LOW;
- TIM_OC_InitStruct.OCNIdleState = LL_TIM_OCIDLESTATE_LOW;
- LL_TIM_OC_Init(TIM1, LL_TIM_CHANNEL_CH1, &TIM_OC_InitStruct);
- LL_TIM_OC_Init(TIM1, LL_TIM_CHANNEL_CH2, &TIM_OC_InitStruct);
- TIM_OC_InitStruct.CompareValue = (TIM1->ARR*3/4 - PWM_CCR_MIN); // initial duty cycle
- LL_TIM_OC_Init(TIM1, LL_TIM_CHANNEL_CH3, &TIM_OC_InitStruct);
- LL_TIM_OC_DisableFast(TIM1, LL_TIM_CHANNEL_CH1 | LL_TIM_CHANNEL_CH2 | LL_TIM_CHANNEL_CH3);
- /* Break and Dead Time options */
- TIM_BDTRInitStruct.OSSRState = LL_TIM_OSSR_DISABLE;
- TIM_BDTRInitStruct.OSSIState = LL_TIM_OSSI_DISABLE;
- TIM_BDTRInitStruct.LockLevel = LL_TIM_LOCKLEVEL_OFF;
- TIM_BDTRInitStruct.DeadTime = PWM_DEAD_TIME;
- TIM_BDTRInitStruct.BreakState = LL_TIM_BREAK_DISABLE;
- TIM_BDTRInitStruct.BreakPolarity = LL_TIM_BREAK_POLARITY_HIGH;
- TIM_BDTRInitStruct.AutomaticOutput = LL_TIM_AUTOMATICOUTPUT_DISABLE;
- LL_TIM_BDTR_Init(TIM1, &TIM_BDTRInitStruct);
- LL_TIM_OC_EnablePreload(TIM1, LL_TIM_CHANNEL_CH1);
- LL_TIM_OC_EnablePreload(TIM1, LL_TIM_CHANNEL_CH2);
- LL_TIM_OC_EnablePreload(TIM1, LL_TIM_CHANNEL_CH3);
- TIM1->DIER |= TIM_DIER_CC3IE;
- NVIC_EnableIRQ(TIM1_CC_IRQn);
- NVIC_SetPriority(TIM1_CC_IRQn,
- NVIC_EncodePriority(NVIC_GetPriorityGrouping(),
- NVIC_TIM1CC_PRE_PRIO,
- NVIC_TIM1CC_SUB_PRIO));
- LL_TIM_EnableAllOutputs(TIM1);
- LL_TIM_EnableCounter(TIM1);
ADC 配置为:
- /**
- ******************************************************************************
- * Configure the GPIO Pin used as analog input for ADC3 on Channel 10.
- ******************************************************************************
- * ADC2_IN10 -> PC0 (Channel 10)
- * ADC2_IN11 -> PC1 (Channel 11)
- */
- GPIO_AnalogInput_InitStruct.Pin = LL_GPIO_PIN_0;
- LL_GPIO_Init(GPIOC, &GPIO_AnalogInput_InitStruct);
- GPIO_AnalogInput_InitStruct.Pin = LL_GPIO_PIN_1;
- LL_GPIO_Init(GPIOC, &GPIO_AnalogInput_InitStruct);
- ADC_InitStruct.Resolution = ADC2_RESOLUTION;
- ADC_InitStruct.DataAlignment = LL_ADC_DATA_ALIGN_RIGHT;
- ADC_InitStruct.SequencersScanMode = LL_ADC_SEQ_SCAN_DISABLE;
- LL_ADC_Init(ADC2, &ADC_InitStruct);
- LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_ADC2);
- ADC_REG_InitStruct.TriggerSource = LL_ADC_REG_TRIG_SOFTWARE;
- ADC_REG_InitStruct.SequencerLength = LL_ADC_REG_SEQ_SCAN_DISABLE;
- ADC_REG_InitStruct.SequencerDiscont = LL_ADC_REG_SEQ_DISCONT_DISABLE;
- ADC_REG_InitStruct.ContinuousMode = LL_ADC_REG_CONV_SINGLE;
- ADC_REG_InitStruct.DMATransfer = LL_ADC_REG_DMA_TRANSFER_NONE; // None to use ADC without DMA
- LL_ADC_REG_Init(ADC2, &ADC_REG_InitStruct);
- LL_ADC_REG_SetFlagEndOfConversion(ADC2, LL_ADC_REG_FLAG_EOC_SEQUENCE_CONV);
- ADC_CommonInitStruct.CommonClock = LL_ADC_CLOCK_SYNC_PCLK_DIV2;
- ADC_CommonInitStruct.Multimode = LL_ADC_MULTI_INDEPENDENT;
- LL_ADC_CommonInit(__LL_ADC_COMMON_INSTANCE(ADC2), &ADC_CommonInitStruct);
- LL_ADC_SetChannelSamplingTime(ADC2, LL_ADC_CHANNEL_10, CONF_ADC_SYMPLING_CYCLES);
- LL_ADC_SetChannelSamplingTime(ADC2, LL_ADC_CHANNEL_11, CONF_ADC_SYMPLING_CYCLES);
- ADC2->CR1 |= (ADC2->CR1 & ~ADC_CR1_DISCNUM_Msk) | ( 1UL << ADC_CR1_DISCNUM_Pos);
- ADC2->CR1 |= ADC_CR1_DISCEN;
- LL_ADC_SetSequencersScanMode(ADC2, LL_ADC_SEQ_SCAN_ENABLE);
- // Set channel conversion number and sequence
- LL_ADC_REG_SetSequencerLength(ADC2, LL_ADC_REG_SEQ_SCAN_ENABLE_2RANKS);
- LL_ADC_REG_SetSequencerRanks(ADC2, LL_ADC_REG_RANK_1, LL_ADC_CHANNEL_10);
- LL_ADC_REG_SetSequencerRanks(ADC2, LL_ADC_REG_RANK_2, LL_ADC_CHANNEL_11);
- // Enable external trigger
- LL_ADC_REG_StartConversionExtTrig(ADC2, ADC_CR2_EXTEN);
- // Select external trigger (RM0090 p. 418)
- LL_ADC_REG_SetTriggerSource(ADC2, LL_ADC_REG_TRIG_EXT_TIM1_CH3);
- LL_ADC_EnableIT_EOCS(ADC2); // set EOCIE in CR1
- NVIC_EnableIRQ(ADC_IRQn);
- NVIC_SetPriority(ADC_IRQn,
- NVIC_EncodePriority(NVIC_GetPriorityGrouping(),
- NVIC_ADC2_PRE_PRIO,
- NVIC_ADC2_SUB_PRIO+1));
- LL_ADC_Enable(ADC2);
ISR 仅为调试目的切换 GPIO 引脚。
0
|
1个回答
|
|
|