fm33lc0xx_fl_adc.c 18.0 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361
/**
  ****************************************************************************************************
  * @file    fm33lc0xx_fl_adc.c
  * @author  FMSH Application Team
  * @brief   Src file of ADC FL Module
  ****************************************************************************************************
  * @attention
  *
  * Copyright (c) [2019] [Fudan Microelectronics]
  * THIS SOFTWARE is licensed under the Mulan PSL v1.
  * can use this software according to the terms and conditions of the Mulan PSL v1.
  * You may obtain a copy of Mulan PSL v1 at:
  * http://license.coscl.org.cn/MulanPSL
  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
  * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
  * PURPOSE.
  * See the Mulan PSL v1 for more details.
  *
  ****************************************************************************************************
  */
/* Includes ------------------------------------------------------------------*/
#include "fm33lc0xx_fl_adc.h"
#include "fm33lc0xx_fl_rcc.h"
#include "fm33lc0xx_fl_rmu.h"
#include "fm33lc0xx_fl_svd.h"
#include "fm33lc0xx_fl_vref.h"
#include "fm33_assert.h"

/** @addtogroup FM33LC0XX_FL_Driver
  * @{
  */

/** @addtogroup ADC
  * @{
  */

/* Private macros ------------------------------------------------------------*/
/** @addtogroup ADC_FL_Private_Macros
  * @{
  */

#define         IS_FL_ADC_INSTANCE(INSTANCE)                ((INSTANCE) == ADC)

#define         IS_FL_ADC_ADCCLK_SOURCE(__VALUE__)          (((__VALUE__) == FL_RCC_ADC_CLK_SOURCE_RCMF_PSC)||\
                                                            ((__VALUE__) == FL_RCC_ADC_CLK_SOURCE_RCHF)||\
                                                            ((__VALUE__) == FL_RCC_ADC_CLK_SOURCE_XTHF)||\
                                                            ((__VALUE__) == FL_RCC_ADC_CLK_SOURCE_PLL))


#define         IS_FL_ADC_ADCCLK_PRESCALER(__VALUE__)       (((__VALUE__) == FL_RCC_ADC_PSC_DIV1)||\
                                                            ((__VALUE__) == FL_RCC_ADC_PSC_DIV2)||\
                                                            ((__VALUE__) == FL_RCC_ADC_PSC_DIV4)||\
                                                            ((__VALUE__) == FL_RCC_ADC_PSC_DIV8)||\
                                                            ((__VALUE__) == FL_RCC_ADC_PSC_DIV16)||\
                                                            ((__VALUE__) == FL_RCC_ADC_PSC_DIV32))


#define         IS_FL_ADC_CONTINUOUSCONVMODE(__VALUE__)     (((__VALUE__) == FL_ADC_CONV_MODE_SINGLE)||\
                                                            ((__VALUE__) == FL_ADC_CONV_MODE_CONTINUOUS))

#define         IS_FL_ADC_AUTO_MODE(__VALUE__)              (((__VALUE__) == FL_ADC_SINGLE_CONV_MODE_AUTO)||\
                                                            ((__VALUE__) == FL_ADC_SINGLE_CONV_MODE_SEMIAUTO))


#define         IS_FL_ADC_SCANDIRECTION(__VALUE__)          (((__VALUE__) == FL_ADC_SEQ_SCAN_DIR_FORWARD)||\
                                                            ((__VALUE__) == FL_ADC_SEQ_SCAN_DIR_BACKWARD))


#define         IS_FL_ADC_EXTERNALTRIGCONV(__VALUE__)       (((__VALUE__) == FL_ADC_TRIGGER_EDGE_NONE)||\
                                                            ((__VALUE__) == FL_ADC_TRIGGER_EDGE_RISING)||\
                                                            ((__VALUE__) == FL_ADC_TRIGGER_EDGE_FALLING)||\
                                                            ((__VALUE__) == FL_ADC_TRIGGER_EDGE_BOTH))

#define         IS_FL_ADC_EXTERNALTRIGSOURCE(__VALUE__)     (((__VALUE__) == FL_ADC_TRGI_PA8)||\
                                                            ((__VALUE__) == FL_ADC_TRGI_PB9)||\
                                                            ((__VALUE__) == FL_ADC_TRGI_ATIM)||\
                                                            ((__VALUE__) == FL_ADC_TRGI_GPTIM0)||\
                                                            ((__VALUE__) == FL_ADC_TRGI_GPTIM1)||\
                                                            ((__VALUE__) == FL_ADC_TRGI_RTC)||\
                                                            ((__VALUE__) == FL_ADC_TRGI_BSTIM1)||\
                                                            ((__VALUE__) == FL_ADC_TRGI_COMP1)||\
                                                            ((__VALUE__) == FL_ADC_TRGI_COMP2))

#define         IS_FL_ADC_CHANNEL_FAST_TIME(__VALUE__)      (((__VALUE__) == FL_ADC_FAST_CH_SAMPLING_TIME_4_ADCCLK)||\
                                                            ((__VALUE__) == FL_ADC_FAST_CH_SAMPLING_TIME_6_ADCCLK)||\
                                                            ((__VALUE__) == FL_ADC_FAST_CH_SAMPLING_TIME_9_ADCCLK)||\
                                                            ((__VALUE__) == FL_ADC_FAST_CH_SAMPLING_TIME_10_ADCCLK)||\
                                                            ((__VALUE__) == FL_ADC_FAST_CH_SAMPLING_TIME_16_ADCCLK)||\
                                                            ((__VALUE__) == FL_ADC_FAST_CH_SAMPLING_TIME_24_ADCCLK)||\
                                                            ((__VALUE__) == FL_ADC_FAST_CH_SAMPLING_TIME_32_ADCCLK)||\
                                                            ((__VALUE__) == FL_ADC_FAST_CH_SAMPLING_TIME_48_ADCCLK)||\
                                                            ((__VALUE__) == FL_ADC_FAST_CH_SAMPLING_TIME_96_ADCCLK)||\
                                                            ((__VALUE__) == FL_ADC_FAST_CH_SAMPLING_TIME_128_ADCCLK)||\
                                                            ((__VALUE__) == FL_ADC_FAST_CH_SAMPLING_TIME_192_ADCCLK)||\
                                                            ((__VALUE__) == FL_ADC_FAST_CH_SAMPLING_TIME_256_ADCCLK)||\
                                                            ((__VALUE__) == FL_ADC_FAST_CH_SAMPLING_TIME_384_ADCCLK)||\
                                                            ((__VALUE__) == FL_ADC_FAST_CH_SAMPLING_TIME_SOFTWARE_CONTROL))

#define         IS_FL_ADC_CHANNEL_SLOW_TIME(__VALUE__)      (((__VALUE__) == FL_ADC_SLOW_CH_SAMPLING_TIME_4_ADCCLK)||\
                                                            ((__VALUE__) == FL_ADC_SLOW_CH_SAMPLING_TIME_6_ADCCLK)||\
                                                            ((__VALUE__) == FL_ADC_SLOW_CH_SAMPLING_TIME_9_ADCCLK)||\
                                                            ((__VALUE__) == FL_ADC_SLOW_CH_SAMPLING_TIME_10_ADCCLK)||\
                                                            ((__VALUE__) == FL_ADC_SLOW_CH_SAMPLING_TIME_16_ADCCLK)||\
                                                            ((__VALUE__) == FL_ADC_SLOW_CH_SAMPLING_TIME_24_ADCCLK)||\
                                                            ((__VALUE__) == FL_ADC_SLOW_CH_SAMPLING_TIME_32_ADCCLK)||\
                                                            ((__VALUE__) == FL_ADC_SLOW_CH_SAMPLING_TIME_48_ADCCLK)||\
                                                            ((__VALUE__) == FL_ADC_SLOW_CH_SAMPLING_TIME_96_ADCCLK)||\
                                                            ((__VALUE__) == FL_ADC_SLOW_CH_SAMPLING_TIME_128_ADCCLK)||\
                                                            ((__VALUE__) == FL_ADC_SLOW_CH_SAMPLING_TIME_192_ADCCLK)||\
                                                            ((__VALUE__) == FL_ADC_SLOW_CH_SAMPLING_TIME_256_ADCCLK)||\
                                                            ((__VALUE__) == FL_ADC_SLOW_CH_SAMPLING_TIME_384_ADCCLK)||\
                                                            ((__VALUE__) == FL_ADC_SLOW_CH_SAMPLING_TIME_SOFTWARE_CONTROL))

#define         IS_FL_ADC_OVERSAMPCOFIG(__VALUE__)          (((__VALUE__) == FL_DISABLE)||\
                                                            ((__VALUE__) == FL_ENABLE))

#define         IS_FL_ADC_OVERSAMPINGRATIO(__VALUE__)       (((__VALUE__) == FL_ADC_OVERSAMPLING_MUL_2X)||\
                                                            ((__VALUE__) == FL_ADC_OVERSAMPLING_MUL_4X)||\
                                                            ((__VALUE__) == FL_ADC_OVERSAMPLING_MUL_8X)||\
                                                            ((__VALUE__) == FL_ADC_OVERSAMPLING_MUL_16X)||\
                                                            ((__VALUE__) == FL_ADC_OVERSAMPLING_MUL_32X)||\
                                                            ((__VALUE__) == FL_ADC_OVERSAMPLING_MUL_64X)||\
                                                            ((__VALUE__) == FL_ADC_OVERSAMPLING_MUL_128X)||\
                                                            ((__VALUE__) == FL_ADC_OVERSAMPLING_MUL_256X))

#define         IS_FL_ADC_OVERSAMPINGSHIFT(__VALUE__)       (((__VALUE__) == FL_ADC_OVERSAMPLING_SHIFT_0B)||\
                                                            ((__VALUE__) == FL_ADC_OVERSAMPLING_SHIFT_1B)||\
                                                            ((__VALUE__) == FL_ADC_OVERSAMPLING_SHIFT_2B)||\
                                                            ((__VALUE__) == FL_ADC_OVERSAMPLING_SHIFT_3B)||\
                                                            ((__VALUE__) == FL_ADC_OVERSAMPLING_SHIFT_4B)||\
                                                            ((__VALUE__) == FL_ADC_OVERSAMPLING_SHIFT_5B)||\
                                                            ((__VALUE__) == FL_ADC_OVERSAMPLING_SHIFT_6B)||\
                                                            ((__VALUE__) == FL_ADC_OVERSAMPLING_SHIFT_7B)||\
                                                            ((__VALUE__) == FL_ADC_OVERSAMPLING_SHIFT_8B))

#define         ADC_CALIBRATIN_TIME_OUT                     (500000)
/**
  * @}
  */

/** @addtogroup ADC_FL_EF_Init
  * @{
  */

/**
  * @brief  ADC外设寄存器值为复位值
  * @param  外设入口地址
  * @retval 返回错误状态,可能值:
  *         -FL_PASS 外设寄存器值恢复复位值
  *         -FL_FAIL 未成功执行
  */
FL_ErrorStatus FL_ADC_CommonDeInit(void)
{
    /* 关闭总线时钟 */
    FL_RCC_DisableGroup2BusClock(FL_RCC_GROUP2_BUSCLK_ADC);
    /* 关闭操作时钟 */
    FL_RCC_DisableGroup2OperationClock(FL_RCC_GROUP2_OPCLK_ADC);
    return FL_PASS;
}
/**
  * @brief  ADC共用寄存器设置以配置外设工作时钟
  *
  * @note   其中LL_LPTIM_OPERATION_MODE_EXTERNAL_ASYN_PAUSE_CNT 模式需要外部脉冲提供给LPTIM模块作为工作时钟,此时
  *         LPTIM完全工作在异步模式下。
  * @param  LPTIM  外设入口地址
  * @param  LPTIM_InitStruct指向LL_LPTIM_TimeInitTypeDef类的结构体,它包含指定LPTIM外设的配置信息
  *
  * @retval ErrorStatus枚举值
  *         -FL_FAIL 配置过程发生错误
  *         -FL_PASS LPUART配置成功
  */
FL_ErrorStatus FL_ADC_CommonInit(FL_ADC_CommonInitTypeDef *ADC_CommonInitStruct)
{
    FL_ErrorStatus status = FL_PASS;
    /* 入口参数检查 */
    assert_param(IS_FL_ADC_ADCCLK_PRESCALER(ADC_CommonInitStruct->clockPrescaler));
    assert_param(IS_FL_ADC_ADCCLK_SOURCE(ADC_CommonInitStruct->clockSource));
    /* 开启总线时钟 */
    FL_RCC_EnableGroup2BusClock(FL_RCC_GROUP2_BUSCLK_ADC);
    /* 开启操作时钟 */
    FL_RCC_EnableGroup2OperationClock(FL_RCC_GROUP2_OPCLK_ADC);
    /* 配置ADCCLOCK时钟预分频 */
    FL_RCC_SetADCPrescaler(ADC_CommonInitStruct->clockPrescaler);
    /* 配置ADCCLOCK时钟模块时钟源 */
    FL_RCC_SetADCClockSource(ADC_CommonInitStruct->clockSource);
    return status;
}
/**
  * @brief  设置 ADC_CommonInitStruct 为默认配置
  * @param  ADC_CommonInitStruct 指向需要将值设置为默认配置的结构体 @ref LL_ADC_CommonInitTypeDef 结构体
  *
  * @retval None
  */
void FL_ADC_CommonStructInit(FL_ADC_CommonInitTypeDef *ADC_CommonInitStruct)
{
    /*默认使用RCHF作为ADC时钟模块时钟源,预分频系数16*/
    ADC_CommonInitStruct->clockSource               = FL_RCC_ADC_CLK_SOURCE_RCHF;
    ADC_CommonInitStruct->clockPrescaler        = FL_RCC_ADC_PSC_DIV16;
}
/**
  * @brief  恢复对应的ADC入口地址寄存器为默认值
  *
  * @param  ADCx  外设入口地址
  *
  * @retval ErrorStatus枚举值
  *         -FL_FAIL 配置过程发生错误
  *         -FL_PASS LPUART配置成功
  */
FL_ErrorStatus  FL_ADC_DeInit(ADC_Type *ADCx)
{
    FL_ErrorStatus status = FL_PASS;
    /* 入口合法性检查 */
    assert_param(IS_FL_ADC_INSTANCE(ADCx));
    /* 外设复位使能 */
    FL_RCC_EnablePeripheralReset();
    FL_RCC_EnableResetAPB2Peripheral(FL_RCC_RSTAPB_ADC);
    FL_RCC_DisableResetAPB2Peripheral(FL_RCC_RSTAPB_ADC);
    FL_RCC_EnableResetAPB2Peripheral(FL_RCC_RSTAPB_ADCCR);
    FL_RCC_DisableResetAPB2Peripheral(FL_RCC_RSTAPB_ADCCR);
    FL_RCC_DisablePeripheralReset();
    return status;
}
/**
  * @brief  初始化ADCx指定的入口地址的外设寄存器
  *
  * @note   用户必须检查此函数的返回值,以确保自校准完成,否则转换结果精度无法保证,除此之外ADC使能过采样实际不会增加ADC的
  *         转换精度只会提高转换结果的稳定性(同时配置移位寄存器的情况下),同时过采样会降低转换速度。
  * @param  ADCx  外设入口地址
  * @param  ADC_InitStruct 向一FL_ADC_InitTypeDef结构体,它包含指定ADC外设的配置信息
  *
  * @retval ErrorStatus枚举值
  *         -FL_FAIL 配置过程发生错误
  *         -FL_PASS LPUART配置成功
  */
FL_ErrorStatus FL_ADC_Init(ADC_Type *ADCx, FL_ADC_InitTypeDef  *ADC_InitStruct)
{
    FL_ErrorStatus status = FL_PASS;
    uint32_t i = 0;
    /* 入口合法性检查 */
    assert_param(IS_FL_ADC_INSTANCE(ADCx));
    assert_param(IS_FL_ADC_CONTINUOUSCONVMODE(ADC_InitStruct->conversionMode));
    assert_param(IS_FL_ADC_AUTO_MODE(ADC_InitStruct->autoMode));
    assert_param(IS_FL_ADC_SCANDIRECTION(ADC_InitStruct->scanDirection));
    assert_param(IS_FL_ADC_EXTERNALTRIGCONV(ADC_InitStruct->externalTrigConv));
    assert_param(IS_FL_ADC_OVERSAMPCOFIG(ADC_InitStruct->oversamplingMode));
    assert_param(IS_FL_ADC_OVERSAMPINGRATIO(ADC_InitStruct->overSampingMultiplier));
    assert_param(IS_FL_ADC_OVERSAMPINGSHIFT(ADC_InitStruct->oversamplingShift));
    /* 使能a工作时钟 */
    FL_RCC_EnableGroup1BusClock(FL_RCC_GROUP1_BUSCLK_ANAC);
    FL_SVD_EnableADCMonitor(SVD);
    if(!FL_VREF_IsEnabled(VREF))
    {
        FL_VREF_ClearFlag_Ready(VREF);
        FL_VREF_Enable(VREF);//置位VREF_EN寄存器,使能VREF1p2模块
    }
    FL_VREF_EnableTemperatureSensor(VREF);//置位PTAT_EN寄存器
    while(FL_VREF_IsActiveFlag_Ready(VREF) == 0)
    {
        if(i >= 128000)
        {
            break;
        }
        i++;
    }
    FL_ADC_Disable(ADCx);
    if(FL_ADC_IsEnabled(ADCx) == 0U)
    {
        /* 连续转换模式 */
        FL_ADC_SetConversionMode(ADCx, ADC_InitStruct->conversionMode);
        /* 自动转换模式 */
        FL_ADC_SetSingleConversionAutoMode(ADCx, ADC_InitStruct->autoMode);
        /* 通道等待使能 */
        if(ADC_InitStruct->waitMode)
        {
            FL_ADC_EnableWaitMode(ADCx);
        }
        else
        {
            FL_ADC_DisableWaitMode(ADCx);
        }
        /*数据冲突模式设置*/
        if(ADC_InitStruct->overrunMode)
        {
            FL_ADC_EnableOverrunMode(ADCx);
        }
        else
        {
            FL_ADC_DisableOverrunMode(ADCx);
        }
        /* 多通道扫描方向 */
        FL_ADC_SetSequenceScanDirection(ADCx, ADC_InitStruct->scanDirection);
        /* 采样控制模式*/
        FL_ADC_SetSamplingTimeControlMode(ADCx, FL_ADC_SAMPLING_TIME_CONTROL_BY_REG);
        FL_ADC_SetSamplingStartControlMode(ADCx, FL_ADC_SAMPLING_START_CONTROL_BY_REG);
        /* 触发模式 */
        FL_ADC_SetTriggerEdge(ADCx, ADC_InitStruct->externalTrigConv);
        /* 触发源 */
        FL_ADC_SetTriggerSource(ADCx, ADC_InitStruct->triggerSource);
        /*通道采样时间设置*/
        FL_ADC_SetSamplingInterval(ADCx, FL_ADC_SAMPLING_INTERVAL_11_CYCLE);
        FL_ADC_SetFastChannelSamplingTime(ADCx, ADC_InitStruct->fastChannelTime);
        FL_ADC_SetSlowChannelSamplingTime(ADCx, ADC_InitStruct->lowChannelTime);
        if(ADC_InitStruct->oversamplingMode)
        {
            /*使能过采样倍数后,需要配置移位寄存器进行移位,这一过程是硬件自动完成的最终最大
            可输出16位的结果值(即256被采样得到的结果是20bit的,右移4bit结果就是16bit的)*/
            FL_ADC_SetOverSamplingMultiplier(ADCx, ADC_InitStruct->overSampingMultiplier);
            FL_ADC_SetOverSamplingShift(ADCx, ADC_InitStruct->oversamplingShift);
            /* 过采样使能 */
            FL_ADC_EnableOverSampling(ADCx);
        }
        else
        {
            /* 关闭过采样 */
            FL_ADC_DisableOverSampling(ADCx);
        }
    }
    else
    {
        status = FL_FAIL;
    }
    return status;
}

/**
  * @brief  设置 ADC_InitStruct 为默认配置
  * @param  ADC_InitStruct 指向需要将值设置为默认配置的结构体 @ref FL_ADC_InitTypeDef 结构体
  *
  * @retval None
  */
void FL_ADC_StructInit(FL_ADC_InitTypeDef *ADC_InitStruct)
{
    ADC_InitStruct->conversionMode                  = FL_ADC_CONV_MODE_SINGLE;
    ADC_InitStruct->autoMode                    = FL_ADC_SINGLE_CONV_MODE_AUTO;
    ADC_InitStruct->scanDirection               = FL_ADC_SEQ_SCAN_DIR_FORWARD;
    ADC_InitStruct->externalTrigConv            = FL_ADC_TRIGGER_EDGE_NONE;
    ADC_InitStruct->overrunMode                 = FL_ENABLE;
    ADC_InitStruct->waitMode                    = FL_ENABLE;
    ADC_InitStruct->fastChannelTime             = FL_ADC_FAST_CH_SAMPLING_TIME_4_ADCCLK;
    ADC_InitStruct->lowChannelTime                  = FL_ADC_SLOW_CH_SAMPLING_TIME_192_ADCCLK;
    ADC_InitStruct->oversamplingMode            = FL_ENABLE;
    ADC_InitStruct->overSampingMultiplier   = FL_ADC_OVERSAMPLING_MUL_16X;
    ADC_InitStruct->oversamplingShift           = FL_ADC_OVERSAMPLING_SHIFT_4B;
}

/**
  * @}
  */

/**
  * @}
  */

/**
  * @}
  */

/******************************************* END OF FILE *******************************************/