IMXRT学习记录 – ADC家族

/ 1评 / 3

ADC家族分有ADC和ADC_ETC,在很多时候他们是结合一起使用的.ADC就真的只是ADC,除了转换相关的功能以外,其他功能几乎没有.

ADC功能:

ADC_ETC功能:

ADC框图(基本不用怎么去理解他,看得多不代表功能多):

ADC采样时间:
由于ADC模块是通过胶水的方式放在芯片内部的,所有时钟域不太一样,互相呼唤需要一些时间差,具体描述就像下图一样.计算公式有点复杂.根据上面的图来带代入参数.

ADC的配置基本没什么需要做的.

int16_t value = 0;

static void MainTask(void *pvParameters)
{
  adc_config_t adcConfigStrcut;
  adc_channel_config_t adcChannelConfigStruct;
  adc_offest_config_t adcOffsetStrcut;

  /* Set configuration */
  CLOCK_EnableClock(kCLOCK_Adc1);

  IOMUXC_SetPinConfig(
      IOMUXC_GPIO_AD_14_GPIOMUX_IO28, /* GPIO_AD_14 PAD functional properties : */
      0xA0U);                         /* Slew Rate Field: Slow Slew Rate
                                                 Drive Strength Field: R0/4
                                                 Speed Field: fast(150MHz)
                                                 Open Drain Enable Field: Open Drain Disabled
                                                 Pull / Keep Enable Field: Pull/Keeper Disabled
                                                 Pull / Keep Select Field: Keeper
                                                 Pull Up / Down Config. Field: 100K Ohm Pull Down
                                                 Hyst. Enable Field: Hysteresis Disabled */

  /*
     *  config->enableAsynchronousClockOutput = true;
     *  config->enableOverWrite =               false;
     *  config->enableContinuousConversion =    false;
     *  config->enableHighSpeed =               false;
     *  config->enableLowPower =                false;
     *  config->enableLongSample =              false;
     *  config->referenceVoltageSource =        kADC_ReferenceVoltageSourceVref;
     *  config->samplePeriodMode =              kADC_SamplePeriod2or12Clocks;
     *  config->clockSource =                   kADC_ClockSourceAD;
     *  config->clockDriver =                   kADC_ClockDriver1;
     *  config->resolution =                    kADC_Resolution12Bit;
     */
  ADC_GetDefaultConfig(&adcConfigStrcut);
  ADC_Init(ADC1, &adcConfigStrcut);
  ADC_SetHardwareAverageConfig(ADC1, kADC_HardwareAverageCount32);

  adcOffsetStrcut.enableSigned = true;
  adcOffsetStrcut.offsetValue = 2048;
  ADC_SetOffsetConfig(ADC1, &adcOffsetStrcut);
  ADC_DoAutoCalibration(ADC1);

  adcChannelConfigStruct.channelNumber = 14U;
  adcChannelConfigStruct.enableInterruptOnConversionCompleted = false;

  for (;;)
  {
    ADC_SetChannelConfig(ADC1, 0U, &adcChannelConfigStruct);
    while (0U == ADC_GetChannelStatusFlags(ADC1, 0U))
    {
    }
    value = ADC_GetChannelConversionValue(ADC1, 0U);
    if (value == 0)
    {
      vTaskDelay(pdMS_TO_TICKS(1));
    }
  }
}

如果用ADC_ETC则可以配置触发,拿最简单的PIT来说事.

volatile uint32_t g_AdcConversionValue0;
volatile uint32_t g_AdcConversionValue1;

void ADC_ETC_IRQ0_IRQHandler(void)
{
  ADC_ETC_ClearInterruptStatusFlags(ADC_ETC, kADC_ETC_Trg0TriggerSource, kADC_ETC_Done0StatusFlagMask);
  g_AdcConversionValue0 = ADC_ETC_GetADCConversionValue(ADC_ETC, 0U, 0U); /* 通道CH7结果. */
  g_AdcConversionValue1 = ADC_ETC_GetADCConversionValue(ADC_ETC, 0U, 1U); /* 通道CH14结果. */
  __DSB();
}

static void PIT_Configuration()
{
  CLOCK_EnableClock(kCLOCK_Pit);

  PIT->MCR = 0x00;
  PIT->CHANNEL[0].LDVAL = 1499999;
}

void XBARA_Configuration(void)
{
  XBARA_Init(XBARA);
  XBARA_SetSignalsConnection(XBARA, kXBARA1_InputPitTrigger0, kXBARA1_OutputAdcEtcTrig00);
}

void ADC_Configuration(void)
{
  adc_config_t adcConfigStrcut;
  adc_channel_config_t adcChannelConfigStruct;

  CLOCK_EnableClock(kCLOCK_Adc1);

  IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_07_GPIOMUX_IO21, 0xA0U);
  IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_14_GPIOMUX_IO28, 0xA0U);

  ADC_GetDefaultConfig(&adcConfigStrcut);
  ADC_Init(ADC1, &adcConfigStrcut);
  ADC_SetHardwareAverageConfig(ADC1, kADC_HardwareAverageCount32);
  //使用ADC_ETC关键就是加入这一个,使能硬件触发.
  ADC_EnableHardwareTrigger(ADC1, true);

  //使用ADC_ETC时候,采样哪个通道就是ADC_ETC说了算了.
  adcChannelConfigStruct.channelNumber = 16U;
  adcChannelConfigStruct.enableInterruptOnConversionCompleted = false;
  ADC_SetChannelConfig(ADC1, 0, &adcChannelConfigStruct);
  ADC_SetChannelConfig(ADC1, 1, &adcChannelConfigStruct);

  ADC_DoAutoCalibration(ADC1);
}

void ADC_ETC_Configuration(void)
{
  adc_etc_config_t adcEtcConfig;
  adc_etc_trigger_config_t adcEtcTriggerConfig;
  adc_etc_trigger_chain_config_t adcEtcTriggerChainConfig;

  /* 初始化ADC_ETC */
  ADC_ETC_GetDefaultConfig(&adcEtcConfig);
  adcEtcConfig.XBARtriggerMask = 1U; /* 使能 kXBARA1_OutputAdcEtcTrig00 */
  ADC_ETC_Init(ADC_ETC, &adcEtcConfig);

  /* 配置触发动作. */
  adcEtcTriggerConfig.enableSyncMode = false;
  adcEtcTriggerConfig.enableSWTriggerMode = false;
  adcEtcTriggerConfig.triggerChainLength = 1; /* 整条链长度2,填1即表示长度2. */
  adcEtcTriggerConfig.triggerPriority = 0U;
  adcEtcTriggerConfig.sampleIntervalDelay = 0U;
  adcEtcTriggerConfig.initialDelay = 0U;
  ADC_ETC_SetTriggerConfig(ADC_ETC, 0U, &adcEtcTriggerConfig);

  /* 背对背模式,如果是True,不等待延迟,佛祖额等待延迟. */
  adcEtcTriggerChainConfig.enableB2BMode = true;

  /* (Chain 0/Trigger 0)配置ADC_HC0,采样CH7. */
  adcEtcTriggerChainConfig.ADCHCRegisterSelect = 1U << 0;
  adcEtcTriggerChainConfig.ADCChannelSelect = 07;
  ADC_ETC_SetTriggerChainConfig(ADC_ETC, 0U, 0U, &adcEtcTriggerChainConfig);

  /* (Chain 1/Trigger 0)配置ADC_HC1,采样CH14,结束时发起中断,然后可以一次性取出结果. */
  adcEtcTriggerChainConfig.ADCHCRegisterSelect = 1U << 1;
  adcEtcTriggerChainConfig.ADCChannelSelect = 14;
  adcEtcTriggerChainConfig.InterruptEnable = kADC_ETC_Done0InterruptEnable;
  adcEtcTriggerChainConfig.enableIrq = true;
  ADC_ETC_SetTriggerChainConfig(ADC_ETC, 0U, 1U, &adcEtcTriggerChainConfig);

  EnableIRQ(ADC_ETC_IRQ0_IRQn);

  /* Start PIT channel0. */
  PIT->CHANNEL[0].TCTRL |= PIT_TCTRL_TEN(1);
}

static void MainTask(void *pvParameters)
{

  /* Set PERCLK_CLK source to OSC_CLK*/
  CLOCK_SetMux(kCLOCK_PerclkMux, 1U);
  /* Set PERCLK_CLK divider to 1 */
  CLOCK_SetDiv(kCLOCK_PerclkDiv, 0U);

  ADC_Configuration();
  XBARA_Configuration();
  PIT_Configuration();
  ADC_ETC_Configuration();
  for (;;)
  {
    vTaskDelay(pdMS_TO_TICKS(1000));
  }
}

要说明一个概念:

  1. Helo说道:

    发现一个大佬,mark

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注