S32 Design Studio PE工具配置ADC

工具配置

我这个K1芯片有两个ADC驱动,也就有两个components,点开之后每个components都有四个选项卡converter转换器、channel通道、compare比较器、average求平均。

配置引脚

配置之前,得先配置好引脚,哪个引脚用来采集ADC。

每个components会生成两个文件,譬如我这里的adConv0会生成一个adConv0.c和一个adConv0.h,adConv1会生成一个adConv1.c和一个adConv1.h。

配置时钟

每个转换器有自己的基础时钟,譬如我们这里配个8M的,到ADC里面会继续分频。

converter转换器

一个转换器生成一个adc_converter_config_t类型的结构体。

/*! adConv0 configuration structure */
const adc_converter_config_t adConv0_ConvConfig0 = {
  .clockDivide = ADC_CLK_DIVIDE_4,
  .sampleTime = 255U,
  .resolution = ADC_RESOLUTION_12BIT,
  .inputClock = ADC_CLK_ALT_1,
  .trigger = ADC_TRIGGER_SOFTWARE,
  .pretriggerSel = ADC_PRETRIGGER_SEL_PDB,
  .triggerSel = ADC_TRIGGER_SEL_PDB,
  .dmaEnable = false,
  .voltageRef = ADC_VOLTAGEREF_VREF,
  .continuousConvEnable = false,
  .supplyMonitoringEnable = false,
};

分频可以选择1/2/4/8分频

/*!
 * @brief Clock Divider selection
 *
 * Implements : adc_clk_divide_t_Class
 */
typedef enum
{
    ADC_CLK_DIVIDE_1 = 0x00U,   /*!< Input clock divided by 1. */
    ADC_CLK_DIVIDE_2 = 0x01U,   /*!< Input clock divided by 2. */
    ADC_CLK_DIVIDE_4 = 0x02U,   /*!< Input clock divided by 4. */
    ADC_CLK_DIVIDE_8 = 0x03U    /*!< Input clock divided by 8. */
} adc_clk_divide_t;

采样时间就是采样周期,有个计数器不断累加,一到达特定次数就进行一次采样,并且将次数清零,最小1最大255。

精度可以选择8/10/12位精度,精度越高,转换时间越长。

/*!
 * @brief Conversion resolution selection
 *
 * Implements : adc_resolution_t_Class
 */
typedef enum
{
    ADC_RESOLUTION_8BIT = 0x00U,    /*!< 8-bit resolution mode */
    ADC_RESOLUTION_12BIT = 0x01U,   /*!< 12-bit resolution mode */
    ADC_RESOLUTION_10BIT = 0x02U    /*!< 10-bit resolution mode */
} adc_resolution_t;

输入时钟是在时钟树里面确定的,我这里只有一个可以选,其他的都只是个标签。

/*!
 * @brief Input clock source selection
 *
 * Implements : adc_input_clock_t_Class
 */
typedef enum
{
    ADC_CLK_ALT_1 = 0x00U,  /*!< Input clock alternative 1. */
    ADC_CLK_ALT_2 = 0x01U,  /*!< Input clock alternative 2. */
    ADC_CLK_ALT_3 = 0x02U,  /*!< Input clock alternative 3. */
    ADC_CLK_ALT_4 = 0x03U   /*!< Input clock alternative 4. */
} adc_input_clock_t;

触发源就是选择软件触发还是硬件触发,硬件触发有电平、边沿,软件有定时器溢出、PWM计数器溢出、ADC采集完毕等等。

前触发选择,也叫预触发,还有触发选择,这两个默认就行。

/*!
 * @brief Pretrigger types selectable from Trigger Latching and Arbitration Unit
 *
 * Implements : adc_pretrigger_sel_t_Class
 */
typedef enum
{
    ADC_PRETRIGGER_SEL_PDB     = 0x00U,   /*!< PDB pretrigger selected. */
    ADC_PRETRIGGER_SEL_TRGMUX  = 0x01U,   /*!< TRGMUX pretrigger selected. */
    ADC_PRETRIGGER_SEL_SW      = 0x02U    /*!< Software pretrigger selected. */
} adc_pretrigger_sel_t;
/*!
 * @brief Trigger source selectable from Trigger Latching and Arbitration Unit
 *
 * Implements : adc_trigger_sel_t_Class
 */
typedef enum
{
    ADC_TRIGGER_SEL_PDB        = 0x00U,   /*!< PDB trigger selected. */
    ADC_TRIGGER_SEL_TRGMUX     = 0x01U    /*!< TRGMUX trigger selected. */
} adc_trigger_sel_t;

参考电压可以选择MCU供电电压还是外部输入的参考电压,默认都是MCU供电电压,也就是第一个。

/*!
 * @brief Voltage reference selection
 *
 * Implements : adc_voltage_reference_t_Class
 */
typedef enum
{
    ADC_VOLTAGEREF_VREF = 0x00U,    /*!< VrefH and VrefL as Voltage reference. */
    ADC_VOLTAGEREF_VALT = 0x01U     /*!< ValtH and ValtL as Voltage reference. */
} adc_voltage_reference_t;

Channel通道

每个ADC转换器都对应好几个通道,自己配置对应到哪个通道就行,每个通道都有自己的引脚。一般都设置为只读,不启动中断。

这里每一个通道就生成一个通道结构体

const adc_chan_config_t adConv0_ChnConfig0 = {
  .interruptEnable = false,
  .channel = ADC_INPUTCHAN_EXT2,
};

const adc_chan_config_t adConv0_ChnConfig1 = {
  .interruptEnable = false,
  .channel = ADC_INPUTCHAN_EXT6,
};

const adc_chan_config_t adConv0_ChnConfig2 = {
  .interruptEnable = false,
  .channel = ADC_INPUTCHAN_EXT8,
};

const adc_chan_config_t adConv0_ChnConfig3 = {
  .interruptEnable = false,
  .channel = ADC_INPUTCHAN_EXT9,
};

const adc_chan_config_t adConv0_ChnConfig4 = {
  .interruptEnable = false,
  .channel = ADC_INPUTCHAN_EXT12,
};

const adc_chan_config_t adConv0_ChnConfig5 = {
  .interruptEnable = false,
  .channel = ADC_INPUTCHAN_EXT13,
};

const adc_chan_config_t adConv0_ChnConfig6 = {
  .interruptEnable = false,
  .channel = ADC_INPUTCHAN_EXT14,
};

const adc_chan_config_t adConv0_ChnConfig7 = {
  .interruptEnable = false,
  .channel = ADC_INPUTCHAN_EXT15,
};

compare对比器

对比器很少用,因为一开就是一整个ADC所有通道都用上,也就是每个通道是或的关系,满足比较条件后,产生中断。具体细节可以看后面的接口使用。

生成代码

const adc_compare_config_t adConv0_HwCompConfig0 = {
  .compareEnable = true,
  .compareGreaterThanEnable = true,
  .compareRangeFuncEnable = true,
  .compVal1 = 10000U,
  .compVal2 = 20000U,
};

average求平均

可以用来硬件滤波,可以

生成代码

const adc_average_config_t adConv0_HwAvgConfig0 = {
  .hwAvgEnable = false,
  .hwAverage = ADC_AVERAGE_4,
};

接口使用

ADC_DRV_InitConverterStruct

初始化转换器

/*FUNCTION**********************************************************************
 *
 * Function Name : ADC_DRV_InitConverterStruct
 * Description   : This function initializes the members of the adc_converter_config_t
 * structure to default values (Reference Manual resets). This function should be called
 * on a structure before using it to configure the converter (ADC_DRV_ConfigConverter), otherwise all members
 * must be written (initialized) by the caller. This function insures that all members are written
 * with safe values, so the user can modify only the desired members.
 *
 * Implements : ADC_DRV_InitConverterStruct_Activity
 *END**************************************************************************/
void ADC_DRV_InitConverterStruct(adc_converter_config_t * const config)
{
    DEV_ASSERT(config != NULL);

    config->clockDivide    = ADC_CLK_DIVIDE_1;
    config->sampleTime     = (uint8_t)ADC_DEFAULT_SAMPLE_TIME;
    config->resolution     = ADC_RESOLUTION_8BIT;
    config->inputClock     = ADC_CLK_ALT_1;
    config->trigger        = ADC_TRIGGER_SOFTWARE;
    config->pretriggerSel  = ADC_PRETRIGGER_SEL_PDB;
    config->triggerSel     = ADC_TRIGGER_SEL_PDB;
    config->dmaEnable      = false;
    config->voltageRef     = ADC_VOLTAGEREF_VREF;
    config->continuousConvEnable   = false;
    config->supplyMonitoringEnable = false;
}

ADC_DRV_ConfigConverter

将转换器配置到ADC

/*FUNCTION**********************************************************************
 *
 * Function Name : ADC_DRV_ConfigConverter
 * Description   : This function configures the ADC converter with the options
 * provided in the configuration structure.
 *
 * Implements : ADC_DRV_ConfigConverter_Activity
 *END**************************************************************************/
void ADC_DRV_ConfigConverter(const uint32_t instance,
                             const adc_converter_config_t * const config)
{
    DEV_ASSERT(instance < ADC_INSTANCE_COUNT);
    DEV_ASSERT(config != NULL);
    /* Some alternative clocks can be unavailable depending on the device */
    DEV_ASSERT(config->inputClock <= NUMBER_OF_ALT_CLOCKS);

    ADC_Type * const base = s_adcBase[instance];
    clock_names_t adc_clocks[ADC_INSTANCE_COUNT] = ADC_CLOCKS;
    uint32_t adc_freq = 0u;
    status_t clk_status = CLOCK_SYS_GetFreq(adc_clocks[instance], &adc_freq);
    DEV_ASSERT(clk_status == STATUS_SUCCESS);
    (void) clk_status;

    adc_freq = adc_freq / (uint32_t)(1UL << ((uint32_t)(config->clockDivide)));
    DEV_ASSERT((adc_freq >= ADC_CLOCK_FREQ_MIN_RUNTIME) && (adc_freq <= ADC_CLOCK_FREQ_MAX_RUNTIME));

    ADC_SetClockDivide(base, config->clockDivide);
    ADC_SetSampleTime(base, config->sampleTime);
    ADC_SetResolution(base, config->resolution);
    ADC_SetInputClock(base, config->inputClock);
    ADC_SetTriggerMode(base, config->trigger);
    ADC_SetPretriggerSelect(instance, config->pretriggerSel);
    ADC_SetTriggerSelect(instance, config->triggerSel);
    ADC_SetDMAEnableFlag(base, config->dmaEnable);
    ADC_SetVoltageReference(base, config->voltageRef);
    ADC_SetContinuousConvFlag(base, config->continuousConvEnable);

    /* Supply monitoring is only available for ADC 0. */
    DEV_ASSERT((config->supplyMonitoringEnable == false) || (instance == 0u));
    if(instance == 0u)
    {
        SIM_Type * const simBase = SIM;
        ADC_SetSupplyMonitoringEnableFlag(simBase, config->supplyMonitoringEnable);
    }
}

ADC_DRV_GetConverterConfig

获取转换器配置

/*FUNCTION**********************************************************************
 *
 * Function Name : ADC_DRV_GetConverterConfig
 * Description   : This functions returns the current converter configuration in
 * the form of a configuration structure.
 *
 * Implements : ADC_DRV_GetConverterConfig_Activity
 *END**************************************************************************/
void ADC_DRV_GetConverterConfig(const uint32_t instance,
                                adc_converter_config_t * const config)
{
    DEV_ASSERT(instance < ADC_INSTANCE_COUNT);
    DEV_ASSERT(config != NULL);

    const ADC_Type * const base = s_adcBase[instance];
    config->clockDivide = ADC_GetClockDivide(base);
    config->sampleTime = ADC_GetSampleTime(base);
    config->resolution = ADC_GetResolution(base);
    config->inputClock = ADC_GetInputClock(base);
    config->trigger = ADC_GetTriggerMode(base);
    config->triggerSel = ADC_GetTriggerSelect(instance);
    config->pretriggerSel = ADC_GetPretriggerSelect(instance);
    config->dmaEnable = ADC_GetDMAEnableFlag(base);
    config->voltageRef = ADC_GetVoltageReference(base);
    config->continuousConvEnable = ADC_GetContinuousConvFlag(base);

    /* Supply monitoring is only available for ADC 0. */
    if(instance == 0u)
    {
        const SIM_Type * const simBase = SIM;
        config->supplyMonitoringEnable = ((simBase->CHIPCTL & SIM_CHIPCTL_ADC_SUPPLYEN_MASK) != 0u) ? true : false;
    }
    else
    {
        config->supplyMonitoringEnable = false;
    }
}

ADC_DRV_Reset

将整个ADC重启和恢复成默认配置,里面会重置所有ADC寄存器。

/*FUNCTION**********************************************************************
 *
 * Function Name : ADC_DRV_Reset
 * Description   : This function writes all the internal ADC registers with
 * their Reference Manual reset values.
 *
 * Implements : ADC_DRV_Reset_Activity
 *END**************************************************************************/
void ADC_DRV_Reset(const uint32_t instance)
{
    DEV_ASSERT(instance < ADC_INSTANCE_COUNT);

    ADC_Type * const baseAddr = s_adcBase[instance];
    uint8_t idx = 0U;

    for(idx = 0U; idx < ADC_SC1_COUNT; idx++)
    {
        baseAddr->SC1[idx] = ADC_SC1_ADCH(ADC_INPUTCHAN_DISABLED) | ADC_SC1_AIEN(0x00U);
    }

    baseAddr->CFG1 = ADC_CFG1_ADICLK(ADC_CLK_ALT_1) | ADC_CFG1_MODE(ADC_RESOLUTION_8BIT) | ADC_CFG1_ADIV(ADC_CLK_DIVIDE_1);
    baseAddr->CFG2 = ADC_CFG2_SMPLTS(ADC_DEFAULT_SAMPLE_TIME);

    for(idx = 0U; idx < ADC_CV_COUNT; idx++)
    {
        baseAddr->CV[idx] = ADC_CV_CV(0U);
    }

    baseAddr->SC2 = ADC_SC2_REFSEL(ADC_VOLTAGEREF_VREF) | ADC_SC2_DMAEN(0x00U) | ADC_SC2_ACREN(0x00U) | ADC_SC2_ACFGT(0x00U) | ADC_SC2_ACFE(0x00U) |
                    ADC_SC2_ADTRG(0x00U);
    baseAddr->SC3 = ADC_SC3_AVGS(ADC_AVERAGE_4) | ADC_SC3_AVGE(0x00U) | ADC_SC3_ADCO(0x00U) | ADC_SC3_CAL(0x00U);
    baseAddr->USR_OFS = ADC_USR_OFS_USR_OFS(0U);
    baseAddr->UG = ADC_UG_UG(ADC_DEFAULT_USER_GAIN);

#if FEATURE_ADC_HAS_EXTRA_NUM_REGS
    for(idx = 0U; idx < ADC_aSC1_COUNT; idx++)
    {
        baseAddr->aSC1[idx] = ADC_aSC1_ADCH(ADC_INPUTCHAN_DISABLED) | ADC_aSC1_AIEN(0x00U);
    }
#endif /* FEATURE_ADC_HAS_EXTRA_NUM_REGS */

    ADC_SetPretriggerSelect(instance, ADC_PRETRIGGER_SEL_PDB);
    ADC_SetTriggerSelect(instance, ADC_TRIGGER_SEL_PDB);
    ADC_DRV_SetSwPretrigger(instance, ADC_SW_PRETRIGGER_DISABLED);

    /* Reset ADC Supply Monitoring - available only for ADC 0 */
    if(instance == 0u)
    {
        SIM_Type * const simBase = SIM;
        ADC_SetSupplyMonitoringEnableFlag(simBase, false);

        simBase->CHIPCTL &= ~SIM_CHIPCTL_ADC_SUPPLY_MASK;
    }
}

ADC_DRV_InitHwCompareStruct

初始化对比器

/*FUNCTION**********************************************************************
 *
 * Function Name : ADC_DRV_InitHwCompareStruct
 * Description   : This function initializes the Hardware Compare configuration
 * structure to default values (Reference Manual resets). This function should be
 * called before configuring the Hardware Compare feature (ADC_DRV_ConfigHwCompare),
 * otherwise all members must be written by the caller. This function insures that all
 * members are written with safe values, so the user can modify the desired members.
 *
 * Implements : ADC_DRV_InitHwCompareStruct_Activity
 *END**************************************************************************/
void ADC_DRV_InitHwCompareStruct(adc_compare_config_t * const config)
{
    DEV_ASSERT(config != NULL);

    config->compareEnable = false;
    config->compareGreaterThanEnable = false;
    config->compareRangeFuncEnable = false;
    config->compVal1 = 0U;
    config->compVal2 = 0U;
}

ADC_DRV_ConfigHwCompare

将对比器配置到ADC里面

/*FUNCTION**********************************************************************
 *
 * Function Name : ADC_DRV_ConfigHwCompare
 * Description   : This functions sets the configuration for the Hardware
 * Compare feature using the configuration structure.
 *
 * Implements : ADC_DRV_ConfigHwCompare_Activity
 *END**************************************************************************/
void ADC_DRV_ConfigHwCompare(const uint32_t instance,
                             const adc_compare_config_t * const config)
{
    DEV_ASSERT(instance < ADC_INSTANCE_COUNT);
    DEV_ASSERT(config != NULL);

    ADC_Type * const base = s_adcBase[instance];
    ADC_SetHwCompareEnableFlag(base, config->compareEnable);
    ADC_SetHwCompareGtEnableFlag(base, config->compareGreaterThanEnable);
    ADC_SetHwCompareRangeEnableFlag(base, config->compareRangeFuncEnable);
    ADC_SetHwCompareComp1Value(base, config->compVal1);
    ADC_SetHwCompareComp2Value(base, config->compVal2);
}

ADC_DRV_GetHwCompareConfig

获取比较器配置

/*FUNCTION**********************************************************************
 *
 * Function Name : ADC_DRV_GetHwCompareConfig
 * Description   : This function returns the configuration for the Hardware
 * Compare feature.
 *
 * Implements : ADC_DRV_GetHwCompareConfig_Activity
 *END**************************************************************************/
void ADC_DRV_GetHwCompareConfig(const uint32_t instance,
                                adc_compare_config_t * const config)
{
    DEV_ASSERT(instance < ADC_INSTANCE_COUNT);
    DEV_ASSERT(config != NULL);

    const ADC_Type * const base = s_adcBase[instance];
    config->compareEnable = ADC_GetHwCompareEnableFlag(base);
    config->compareGreaterThanEnable = ADC_GetHwCompareGtEnableFlag(base);
    config->compareRangeFuncEnable = ADC_GetHwCompareRangeEnableFlag(base);
    config->compVal1 = ADC_GetHwCompareComp1Value(base);
    config->compVal2 = ADC_GetHwCompareComp2Value(base);
}

ADC_DRV_InitHwAverageStruct

求平均器结构体初始化,这个感觉没啥用。

/*FUNCTION**********************************************************************
 *
 * Function Name : ADC_DRV_InitHwAverageStruct
 * Description   : This function initializes the Hardware Average configuration
 * structure to default values (Reference Manual resets). This function should be
 * called before configuring the Hardware Average feature (ADC_DRV_ConfigHwAverage),
 * otherwise all members must be written by the caller. This function insures that all
 * members are written with safe values, so the user can modify the desired members.
 *
 * Implements : ADC_DRV_InitHwAverageStruct_Activity
 *END**************************************************************************/
void ADC_DRV_InitHwAverageStruct(adc_average_config_t * const config)
{
    DEV_ASSERT(config != NULL);

    config->hwAvgEnable = false;
    config->hwAverage = ADC_AVERAGE_4;
}

ADC_DRV_ConfigHwAverage

求平均器配置进ADC里面

/*FUNCTION**********************************************************************
 *
 * Function Name : ADC_DRV_ConfigHwAverage
 * Description   : This function sets the configuration for the Hardware
 * Average feature.
 *
 * Implements : ADC_DRV_ConfigHwAverage_Activity
 *END**************************************************************************/
void ADC_DRV_ConfigHwAverage(const uint32_t instance,
                             const adc_average_config_t * const config)
{
    DEV_ASSERT(instance < ADC_INSTANCE_COUNT);
    DEV_ASSERT(config != NULL);

    ADC_Type * const base = s_adcBase[instance];
    ADC_SetHwAverageEnableFlag(base, config->hwAvgEnable);
    ADC_SetHwAverageMode(base, config->hwAverage);
}

ADC_DRV_GetHwAverageConfig

获取求平均器的配置

/*FUNCTION**********************************************************************
 *
 * Function Name : ADC_DRV_GetHwAverageConfig
 * Description   : This function returns the configuration for the Hardware
 * Average feature.
 *
 * Implements : ADC_DRV_GetHwAverageConfig_Activity
 *END**************************************************************************/
void ADC_DRV_GetHwAverageConfig(const uint32_t instance,
                                adc_average_config_t * const config)
{
    DEV_ASSERT(instance < ADC_INSTANCE_COUNT);
    DEV_ASSERT(config != NULL);

    const ADC_Type * const base = s_adcBase[instance];
    config->hwAvgEnable = ADC_GetHwAverageEnableFlag(base);
    config->hwAverage = ADC_GetHwAverageMode(base);
}

ADC_DRV_InitChanStruct

初始化通道结构体,这个也没啥用。

/*FUNCTION**********************************************************************
 *
 * Function Name : ADC_DRV_InitChanStruct
 * Description   : This function initializes the control channel
 * configuration structure to default values (Reference Manual resets). This function should
 * be called on a structure before using it to configure a channel (ADC_DRV_ConfigChan), otherwise
 * all members must be written by the caller. This function insures that all members are written
 * with safe values, so the user can modify only the desired members.
 *
 * Implements : ADC_DRV_InitChanStruct_Activity
 *END**************************************************************************/
void ADC_DRV_InitChanStruct(adc_chan_config_t * const config)
{
    DEV_ASSERT(config != NULL);

    config->interruptEnable = false;
    config->channel = ADC_INPUTCHAN_DISABLED;
}

ADC_DRV_ConfigChan

转换接口,这个一定会用上,每次转换都得用它。

/*FUNCTION**********************************************************************
 *
 * Function Name : ADC_DRV_ConfigChan
 * Description   : This function sets a control channel configuration.
 *
 * When Software Trigger mode is enabled, configuring control channel index 0,
 * implicitly triggers a new conversion on the selected ADC input channel.
 * Therefore, ADC_DRV_ConfigChan can be used for sw-triggering conversions.
 *
 * Configuring any control channel while it is actively controlling a conversion
 * (sw or hw triggered) will implicitly abort the on-going conversion.
 *
 * Implements : ADC_DRV_ConfigChan_Activity
 *END**************************************************************************/
void ADC_DRV_ConfigChan(const uint32_t instance,
                        const uint8_t chanIndex,
                        const adc_chan_config_t * const config)
{
    DEV_ASSERT(instance < ADC_INSTANCE_COUNT);
    DEV_ASSERT(chanIndex < ADC_CTRL_CHANS_COUNT);
    DEV_ASSERT(config != NULL);

    ADC_Type * const base = s_adcBase[instance];

    /* ADC_INPUTCHAN_SUPPLY_ can only be used with ADC 0,
     * If used, the feature must be enabled separately via supplyMonitoringEnable flag in adc_converter_config_t. */
    DEV_ASSERT((instance == 0u) || ((uint32_t)config->channel < (uint32_t)ADC_INPUTCHAN_SUPPLY_VDD) || \
                                   ((uint32_t)config->channel > (uint32_t)ADC_INPUTCHAN_SUPPLY_VDD_LV));
    ADC_SetInputChannel(base, chanIndex, config->channel, config->interruptEnable);
}

ADC_DRV_GetChanConfig

获取通道配置,也没啥用

/*FUNCTION**********************************************************************
 *
 * Function Name : ADC_DRV_GetChanConfig
 * Description   : This function returns the current configuration for a control
 * channel.
 *
 * Implements : ADC_DRV_GetChanConfig_Activity
 *END**************************************************************************/
void ADC_DRV_GetChanConfig(const uint32_t instance,
                           const uint8_t chanIndex,
                           adc_chan_config_t * const config)
{
    DEV_ASSERT(instance < ADC_INSTANCE_COUNT);
    DEV_ASSERT(chanIndex < ADC_CTRL_CHANS_COUNT);
    DEV_ASSERT(config != NULL);

    const ADC_Type * const base = s_adcBase[instance];
    config->interruptEnable = ADC_GetChanInterruptEnableFlag(base, chanIndex);
    config->channel = ADC_GetInputChannel(base, chanIndex);
}

ADC_DRV_SetSwPretrigger

设置转换器前触发

/*FUNCTION**********************************************************************
 *
 * Function Name : ADC_DRV_SetSwPretrigger
 * Description   : This function sets the software pretrigger - affects only first 4 control channels.
 *
 * Implements : ADC_DRV_SetSwPretrigger_Activity
 *END**************************************************************************/
void ADC_DRV_SetSwPretrigger(const uint32_t instance,
                             const adc_sw_pretrigger_t swPretrigger)
{
    DEV_ASSERT(instance < ADC_INSTANCE_COUNT);
    SIM_Type * const simBase = SIM;
    uint32_t intermValue = 0U;
    uint32_t mask[ADC_INSTANCE_COUNT] = {0U};
#if (ADC_INSTANCE_COUNT == 1U)
    mask[0] = SIM_ADCOPT_ADC0SWPRETRG_MASK;
#elif (ADC_INSTANCE_COUNT == 2U)
    mask[0] = SIM_ADCOPT_ADC0SWPRETRG_MASK;
    mask[1] = SIM_ADCOPT_ADC1SWPRETRG_MASK;
#else
#error "Maximum supported value for ADC_INSTANCE_COUNT is 2."
#endif
    /* If SW Pretrigger Select is not enabled, the SW pretriggers will be ignored by ADC. */
    DEV_ASSERT((ADC_GetPretriggerSelect(instance) == ADC_PRETRIGGER_SEL_SW) || \
               (swPretrigger == ADC_SW_PRETRIGGER_DISABLED));

    intermValue = simBase->ADCOPT & (~ mask[instance]);
    switch(instance)
    {
    case 0:
        intermValue |= SIM_ADCOPT_ADC0SWPRETRG(swPretrigger);
        break;
    case 1:
        intermValue |= SIM_ADCOPT_ADC1SWPRETRG(swPretrigger);
        break;
    default:
        DEV_ASSERT(false);
        break;
    }

    simBase->ADCOPT = intermValue;
}

ADC_DRV_WaitConvDone

等待转换完成,这个也必定用上。

/*FUNCTION**********************************************************************
 *
 * Function Name : ADC_DRV_WaitConvDone
 * Description   : This functions waits for a conversion to complete by
 * continuously polling the Conversion Active Flag.
 *
 * Implements : ADC_DRV_WaitConvDone_Activity
 *END**************************************************************************/
void ADC_DRV_WaitConvDone(const uint32_t instance)
{
    DEV_ASSERT(instance < ADC_INSTANCE_COUNT);

    const ADC_Type * const base = s_adcBase[instance];
    while (ADC_GetConvActiveFlag(base) == true)
    {
        /* Wait for conversion to finish */
    }
}

ADC_DRV_GetConvCompleteFlag

获取转换成功的标志位

/*FUNCTION**********************************************************************
 *
 * Function Name : ADC_DRV_GetConvCompleteFlag
 * Description   : This function returns the state of the Conversion Complete
 * flag for a control channel. This flag is set when a conversion is complete
 * or the condition generated by the Hardware Compare feature is evaluated to true.
 *
 * Implements : ADC_DRV_GetConvCompleteFlag_Activity
 *END**************************************************************************/
bool ADC_DRV_GetConvCompleteFlag(const uint32_t instance,
                                 const uint8_t chanIndex)
{
    DEV_ASSERT(instance < ADC_INSTANCE_COUNT);
    DEV_ASSERT(chanIndex < ADC_CTRL_CHANS_COUNT);

    const ADC_Type * const base = s_adcBase[instance];

#if FEATURE_ADC_HAS_EXTRA_NUM_REGS
    uint32_t tmp = base->aSC1[chanIndex];
    tmp = (tmp & ADC_aSC1_COCO_MASK) >> ADC_aSC1_COCO_SHIFT;
#else
    uint32_t tmp = base->SC1[chanIndex];
    tmp = (tmp & ADC_SC1_COCO_MASK) >> ADC_SC1_COCO_SHIFT;
#endif /* FEATURE_ADC_HAS_EXTRA_NUM_REGS */

    return (tmp != 0u) ? true : false;
}

ADC_DRV_GetChanResult

获取转换成功结果

/*FUNCTION**********************************************************************
 *
 * Function Name : ADC_DRV_GetChanResult
 * Description   : This function returns the conversion result from a
 * control channel.
 *
 * Implements : ADC_DRV_GetChanResult_Activity
 *END**************************************************************************/
void ADC_DRV_GetChanResult(const uint32_t instance,
                           const uint8_t chanIndex,
                           uint16_t * const result)
{
    DEV_ASSERT(instance < ADC_INSTANCE_COUNT);
    DEV_ASSERT(result != NULL);

    const ADC_Type * const base = s_adcBase[instance];

#if FEATURE_ADC_HAS_EXTRA_NUM_REGS

    DEV_ASSERT(chanIndex < ADC_aR_COUNT);

    uint32_t tmp = base->aR[chanIndex];
    tmp = (tmp & ADC_aR_D_MASK) >> ADC_aR_D_SHIFT;
#else

    DEV_ASSERT(chanIndex < ADC_R_COUNT);

    uint32_t tmp = base->R[chanIndex];
    tmp = (tmp & ADC_R_D_MASK) >> ADC_R_D_SHIFT;
#endif /* FEATURE_ADC_HAS_EXTRA_NUM_REGS */

    *result = (uint16_t)tmp;
}

ADC_DRV_AutoCalibration

ADC自动标定

/*FUNCTION**********************************************************************
 *
 * Function Name : ADC_DRV_AutoCalibration
 * Description   : This functions executes an Auto-Calibration sequence. It
 * is recommended to run this sequence before using the ADC converter.
 * this function will check and reset clock divide based the adc frequency.
 * an error will be displayed if adc_freq too big
 * this function will set satisfy clock divide,start calibration.
 * final this function: restore adc clock divide,hardware average and trigger settings.
 *
 * Implements : ADC_DRV_AutoCalibration_Activity
 *END**************************************************************************/
void ADC_DRV_AutoCalibration(const uint32_t instance)
{
    DEV_ASSERT(instance < ADC_INSTANCE_COUNT);

    ADC_Type * const base = s_adcBase[instance];
    /* set hardware average to maximum and set software trigger*/
    bool hwavgen = ADC_GetHwAverageEnableFlag(base);
    adc_average_t hwavg = ADC_GetHwAverageMode(base);
    adc_trigger_t trig = ADC_GetTriggerMode(base);
    uint8_t sampletime = ADC_GetSampleTime(base);
    ADC_SetHwAverageMode(base, ADC_AVERAGE_32);
    ADC_SetHwAverageEnableFlag(base, true);
    ADC_SetTriggerMode(base, ADC_TRIGGER_SOFTWARE);
    /* Set the sample time to the reset value because it affects the
        calibration duration but not the results
     */
    ADC_SetSampleTime(base, ADC_RESET_SAMPLE_TIME_VALUE);

    base->CLPS = 0x00u;
    base->CLP3 = 0x00u;
    base->CLP2 = 0x00u;
    base->CLP1 = 0x00u;
    base->CLP0 = 0x00u;
    base->CLPX = 0x00u;
    base->CLP9 = 0x00u;

    /*Set clock divider */
    clock_names_t adc_clocks[ADC_INSTANCE_COUNT] = ADC_CLOCKS;
    uint32_t adc_freq = 0u;
    adc_clk_divide_t adc_clk_divide_res = ADC_GetClockDivide(base);
    adc_clk_divide_t adc_clk_divide = ADC_CLK_DIVIDE_1;
    status_t clk_status = CLOCK_SYS_GetFreq(adc_clocks[instance], &adc_freq);
    DEV_ASSERT(clk_status == STATUS_SUCCESS);
    (void) clk_status;
    DEV_ASSERT(adc_freq >= ADC_CLOCK_FREQ_MIN_RUNTIME);
    if ((adc_freq / (uint32_t)(1UL << ((uint32_t)(adc_clk_divide_res)))) <= (ADC_CLOCK_FREQ_MAX_RUNTIME / 2U))
    {
        /* no action if adc_freq is satisfy */
    }
    else
    {
        if ((adc_freq / 2U) <= (ADC_CLOCK_FREQ_MAX_RUNTIME / 2U))
        {
            adc_clk_divide = ADC_CLK_DIVIDE_2;
        }
        else if ((adc_freq / 4U) <= (ADC_CLOCK_FREQ_MAX_RUNTIME / 2U))
        {
            adc_clk_divide = ADC_CLK_DIVIDE_4;
        }
        else if ((adc_freq / 8U) <= (ADC_CLOCK_FREQ_MAX_RUNTIME / 2U))
        {
            adc_clk_divide = ADC_CLK_DIVIDE_8;
        }
        else
        {
            /* frequency is greater than required clock for calibration */
            DEV_ASSERT(false);
        }
        ADC_SetClockDivide(base, adc_clk_divide);
    }
    /* start calibration */
    ADC_SetCalibrationActiveFlag(base, true);
    while (ADC_GetCalibrationActiveFlag(base))
    {
        /* Wait for calibration to finish */
    }

    /* restore adc clock divide*/
    ADC_SetClockDivide(base, adc_clk_divide_res);
    /* restore hardware average and trigger settings*/
    ADC_SetHwAverageEnableFlag(base, hwavgen);
    ADC_SetHwAverageMode(base, hwavg);
    ADC_SetTriggerMode(base, trig);
    ADC_SetSampleTime(base, sampletime);
}

ADC_DRV_InitUserCalibrationStruct

初始化自动标定结构体

/*FUNCTION**********************************************************************
 *
 * Function Name : ADC_DRV_InitUserCalibrationStruct
 * Description   : This function initializes the User Calibration configuration
 * structure to default values (Reference Manual resets). This function should be called
 * on a structure before using it to configure the User Calibration feature (ADC_DRV_ConfigUserCalibration),
 * otherwise all members must be written by the caller. This function insures that all members are written
 * with safe values, so the user can modify only the desired members.
 *
 * Implements : ADC_DRV_InitUserCalibrationStruct_Activity
 *END**************************************************************************/
void ADC_DRV_InitUserCalibrationStruct(adc_calibration_t * const config)
{
    DEV_ASSERT(config != NULL);

    config->userGain = (uint16_t)ADC_DEFAULT_USER_GAIN;
    config->userOffset = (uint16_t)0U;
}

ADC_DRV_ConfigUserCalibration

将用户标定结构体配置进ADC里面

/*FUNCTION**********************************************************************
 *
 * Function Name : ADC_DRV_ConfigUserCalibration
 * Description   : This function sets the configuration for the user calibration
 * registers.
 *
 * Implements : ADC_DRV_ConfigUserCalibration_Activity
 *END**************************************************************************/
void ADC_DRV_ConfigUserCalibration(const uint32_t instance,
                                   const adc_calibration_t * const config)
{
    DEV_ASSERT(instance < ADC_INSTANCE_COUNT);
    DEV_ASSERT(config != NULL);

    ADC_Type * const base = s_adcBase[instance];
    ADC_SetUserGainValue(base, config->userGain);
    ADC_SetUserOffsetValue(base, config->userOffset);
}

ADC_DRV_GetUserCalibration

获取用户标定结构体

/*FUNCTION**********************************************************************
 *
 * Function Name : ADC_DRV_GetUserCalibration
 * Description   : This function returns the current user calibration
 * register values.
 *
 * Implements : ADC_DRV_GetUserCalibration_Activity
 *END**************************************************************************/
void ADC_DRV_GetUserCalibration(const uint32_t instance,
                                adc_calibration_t * const config)
{
    DEV_ASSERT(instance < ADC_INSTANCE_COUNT);
    DEV_ASSERT(config != NULL);

    const ADC_Type * const base = s_adcBase[instance];
    config->userGain = ADC_GetUserGainValue(base);
    config->userOffset = ADC_GetUserOffsetValue(base);
}

ADC_DRV_GetInterruptNumber

获取中断号

/*FUNCTION**********************************************************************
 *
 * Function Name : ADC_DRV_GetInterruptNumber
 * Description   : This function returns the interrupt number for the specified ADC instance.
 *
 * Implements : ADC_DRV_GetInterruptNumber_Activity
 *END**************************************************************************/
IRQn_Type ADC_DRV_GetInterruptNumber(const uint32_t instance)
{
    DEV_ASSERT(instance < ADC_INSTANCE_COUNT);

    static const IRQn_Type adcIrqId[ADC_INSTANCE_COUNT] = ADC_IRQS;
    IRQn_Type irqId = adcIrqId[instance];

    return irqId;
}

ADC_DRV_ClearLatchedTriggers

清除触发标志位

/*FUNCTION**********************************************************************
 *
 * Function Name : ADC_DRV_ClearLatchedTriggers
 * Description   : This function clears all trigger latched flags of the ADC instance.
 *
 * Implements : ADC_DRV_ClearLatchedTriggers_Activity
 *END**************************************************************************/
void ADC_DRV_ClearLatchedTriggers(const uint32_t instance,
                                  const adc_latch_clear_t clearMode)
{
    DEV_ASSERT(instance < ADC_INSTANCE_COUNT);
    DEV_ASSERT((clearMode == ADC_LATCH_CLEAR_WAIT) || (clearMode == ADC_LATCH_CLEAR_FORCE));

    ADC_Type * const base = s_adcBase[instance];
    if (clearMode == ADC_LATCH_CLEAR_FORCE)
    {
        ADC_ClearLatchTriggers(base);
    }

    while (ADC_GetTriggerLatchFlags(base) != 0u)
    {
        /* Wait for latched triggers to be processed */
    }
}

ADC_DRV_ClearTriggerErrors

清除触发错误标志位

/*FUNCTION**********************************************************************
 *
 * Function Name : ADC_DRV_ClearTriggerErrors
 * Description   : This function clears all trigger error flags of the ADC instance.
 *
 * Implements : ADC_DRV_ClearTriggerErrors_Activity
 *END**************************************************************************/
void ADC_DRV_ClearTriggerErrors(const uint32_t instance)
{
    DEV_ASSERT(instance < ADC_INSTANCE_COUNT);

    ADC_Type * const base = s_adcBase[instance];

    base->SC2 |= ADC_SC2_TRGSTERR_MASK;
}

ADC_DRV_GetTriggerErrorFlags

获取触发错误标志位

/*FUNCTION**********************************************************************
 *
 * Function Name : ADC_DRV_GetTriggerErrorFlags
 * Description   : This function returns the trigger error flags bits of the ADC instance.
 *
 * Implements : ADC_DRV_GetTriggerErrorFlags_Activity
 *END**************************************************************************/
uint32_t ADC_DRV_GetTriggerErrorFlags(const uint32_t instance)
{
    DEV_ASSERT(instance < ADC_INSTANCE_COUNT);

    const ADC_Type * const base = s_adcBase[instance];

    uint32_t trig_errors = (base->SC2 & ADC_SC2_TRGSTERR_MASK) >> ADC_SC2_TRGSTERR_SHIFT;

    return trig_errors;
}

一般用法

初始化的时候初始化ADC就可以了,顺带自动标定一下。

 void ADC_Init()
{
    ADC_DRV_ConfigConverter(INST_ADCONV0, &adConv0_ConvConfig0);

    ADC_DRV_AutoCalibration(INST_ADCONV0);
}

采集的时候三步走:转换对应通道采集到的值,等待转换完成,获取转换之后的值。

static uint16_t ADC_DRV_GetADCValue(const uint32_t instance,const adc_chan_config_t * const config)
{
    uint16_t adcRawValue;
    /* Configure ADC channel and software trigger a conversion */
    ADC_DRV_ConfigChan(instance, 0U, config);

    /* Wait for the conversion to be done */
    ADC_DRV_WaitConvDone(instance);

    /* Store the channel result into a local variable */
    ADC_DRV_GetChanResult(instance, 0U, &adcRawValue);

    return adcRawValue;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/441968.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LangChain Experssion Language之CookBook(一)

目录 LangChain Experssion Language简介 CookBook示例大赏 Prompt LLM&#xff1a;正经本分事儿 RAG&#xff1a;检索的时候用上用户自己的数据吧 Multiple chains&#xff1a;玩转chain的叠加合并 Querying a SQL DB&#xff1a;根据用户的问题写SQL检索数据库 Agent…

uniapp使用华为云OBS进行上传

前言&#xff1a;无论是使用华为云还是阿里云&#xff0c;使用其产品的时候必须阅读文档 1、以华为云为例&#xff0c;刚接触此功能肯定是无从下手的情况&#xff0c;那么我们需要思考&#xff0c;我们使用该产品所用到的文档是什么 2、我们要使用obs 文件上传&#xff0c;肯…

iOS-系统弹窗调用

代码&#xff1a; UIAlertController *alertViewController [UIAlertController alertControllerWithTitle:"请选择方式" message:nil preferredStyle:UIAlertControllerStyleActionSheet];// style 为 sheet UIAlertAction *cancle [UIAlertAction actionWithTit…

Docker基础教程 - 9 常用容器部署-Tomcat

更好的阅读体验&#xff1a;点这里 &#xff08; www.doubibiji.com &#xff09; 9 常用容器部署-Tomcat 下面介绍一下常用容器的部署。可以先简单了解下&#xff0c;用到再来详细查看。 在 Docker 中部署 Tomcat 容器。 9.1 搜索镜像 首先搜索镜像&#xff0c;命令&…

来说说看到的求职路上可以提高的地方——简历

要进行求职的时候应该遇到的第一件事情就是简历。 随着看到的简历越来越多&#xff0c;也发现了一些问题&#xff0c;来开个帖子来说说这些问题。 格式 让参加面试的人最头疼的地方就是简历格式没有空格。 最近发现好多人的简历格式上都不空格&#xff0c;很多内容完全都在…

植物病虫害:YOLO玉米病虫害识别数据集

玉米病虫害识别数据集&#xff1a;玉米枯萎病&#xff0c;玉米灰斑病&#xff0c;玉米锈病叶&#xff0c;粘虫幼虫&#xff0c;玉米条斑病&#xff0c;黄二化螟&#xff0c;黄二化螟幼虫7类&#xff0c;yolo标注完整&#xff0c;3900多张图像&#xff0c;全部原始数据&#xff…

el-table-column嵌套el-form-item不能进行校验问题解决

项目为vue3elementPlus开发的项目 业务要求&#xff1a;table表格展示数据&#xff0c;其中有一行是ip地址可展示可修改&#xff0c;此处要求增加自定义校验规则 先看一下效果&#xff1a; 此处先描述一下&#xff0c;问题出在了哪里&#xff0c;我将el-table的data,使用一个…

LabVIEW质谱仪开发与升级

LabVIEW质谱仪开发与升级 随着科技的发展和实验要求的提高&#xff0c;传统基于VB的质谱仪系统已经无法满足当前的高精度和高效率需求。这些系统通常存在着功能不全和操作复杂的问题&#xff0c;影响了科研和生产的进度。为了解决这些问题&#xff0c;开发了一套基于LabVIEW开…

考研复习C语言初阶(3)

目录 一.函数是什么? 二.C语言中函数的分类 2.1库函数 2.2自定义函数 三.函数的参数 3.1实际参数&#xff08;实参&#xff09; 3.2 形式参数&#xff08;形参&#xff09; 四.函数的调用 4.1 传值调用 4.2 传址调用 五. 函数的嵌套调用和链式访问 5.1 嵌套调用 5…

Nginx 基础知识及实例解析

一、简介 Nginx (“engine x”) 是一个高性能的 HTTP 和反向代理服务器&#xff0c;特点是占有内存少&#xff0c;并发能力强&#xff0c;目前使用最多的就是负载均衡。Nginx 可以作为静态页面的 web 服务器&#xff0c;同时还支持 CGI 协议的动态语言&#xff0c;比如 perl、…

探索考古文字场景,基于YOLOv5全系列【n/s/m/l/x】参数模型开发构建文本考古场景下的甲骨文字符图像检测识别系统

甲骨文是一种非常历史悠久的古老文字&#xff0c;在前面我们基本上很少有涉及这块的内容&#xff0c;最近正好在做文字相关的项目开发研究&#xff0c;就想着基于甲骨文的场景来开发对应的检测识别系统&#xff0c;在前文中我们基于YOLOv7开发构建了在仿真数据实验场景下的目标…

Mamba-minimal Mamba的最小限度实现 (一)

文章目录 参数和数据尺寸约定class MambaBlockdef forwarddef __ int__def ssmdef selective_scan johnma2006/mamba-minimal: Simple, minimal implementation of the Mamba SSM in one file of PyTorch. (github.com) manba的简单最小限度实现&#xff0c;和原始论文实现stat…

智能音箱技术解析

目录 前言智能音箱执行步骤解析1.1 探测唤醒词或触发词1.2 语音识别1.3 意图识别1.4 执行指令 2 典型的智能音箱2.1 百度小度音响2.2 小米小爱同学2.3 苹果 HomePod 3 功能应用举例3.1 设置计时器3.2 播放音乐 结语 前言 智能音箱已经成为日常生活中不可或缺的一部分&#xff…

亚信安慧AntDB:为数据安全和稳定而生

AntDB充分考虑了用户的需求&#xff0c;将用户体验置于优先位置&#xff0c;通过深入分析用户的使用情况&#xff0c;对数据库的性能和功能进行了全方位的优化。无论是对于小规模应用还是大规模企业级系统&#xff0c;AntDB都能够提供稳定高效的数据库服务&#xff0c;满足不同…

[BUG] docker运行Java程序时配置代理-Dhttp.proxyHost后启动报错

[BUG] docker运行Java程序时配置代理-Dhttp.proxyHost后启动报错 bug现象描述 版本&#xff1a;2.0.4&#xff08;客户端和服务端都是&#xff09; 环境&#xff1a;私有云环境&#xff0c;只有少量跳板机器可以访问公网&#xff0c;其他机器均通过配置代理方式访问公网 bug现…

新一代 Git 工具,AI 赋能!深度集成、简化操作 | 开源日报 No.194

gitbutlerapp/gitbutler Stars: 7.2k License: NOASSERTION gitbutler 是一个基于 Git 的版本控制客户端。旨在为现代工作流程构建一个全新的 Git 分支管理工具。 虚拟分支&#xff1a;可以同时在多个分支上工作&#xff0c;而无需不断切换分支简化提交管理&#xff1a;通过拖…

码垛【FB块】

转载&#xff1a; FUNCTION BLOCK 码垛 VAR INPUT 当前数:INT; 点l:Point; 点2:Point; X行数:REAL; Y列数:REAL; 2层数:REAL; END VAR VAR OUTPUT 目标点:Point; 点数量:INT; END VAR VAR // X差值:点2.x-点1.x; IF X行数>1 AND X差值<>0 THEN X间隔:X差值/(X行数-1)…

07.axios封装实例

一.简易axios封装-获取省份列表 1. 需求&#xff1a;基于 Promise 和 XHR 封装 myAxios 函数&#xff0c;获取省份列表展示到页面 2. 核心语法&#xff1a; function myAxios(config) {return new Promise((resolve, reject) > {// XHR 请求// 调用成功/失败的处理程序}) …

偶极子和环形天线的辐射机理仿真分析

目录 0 引言 1 偶极子天线的辐射因素分析 1.1 偶极子天线模型设计 1.2 谐振点的出现规律 1.3 天线尺寸对辐射的影响 1.4 天线角度对辐射的影响

c++ primer plus 第十五章笔记 友元,异常和其他

友元类&#xff1a; 两个类不存在继承和包含的关系&#xff0c;但是我想通过一个类的成员函数来修改另一个类的私有成员和保护成员的时候&#xff0c;可以使用友元类。 class A {private:int num;//私有成员//...public: //...friend class B;//声明一个友元类 }class…