ADC: Analog to Digital Converter
ADC分辨率:12-bit
ADC工作模式包括:
外部输入的DC power supply有两种模式:
/**
?* \brief ? ? ? ADC initialize parameters
?*
?* \ingroup ? ? ADC_Exported_Types
?*/
typedef struct
{
? ? uint32_t ADC_SampleTime; ? ? ? ?/**< Specifies the ADC sample clock, adc_sample_period = (n+1) cycles from 10MHz.
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? This parameter can be a value of 0~255 or 2048~14591. */
? ? uint32_t ADC_ConvertTime; ? ? ? /**< Specifies the ADC Sample convert time.
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? This parameter can be a value of \ref ADC_Convert_Time*/
? ? uint32_t ADC_DataWriteToFifo; ? /**< Enable or disable writing ADC sampling data to FIFO in one shot mode.
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? This parameter can be a value of \ref ADC_Data_Write_To_Fifo*/
? ? uint32_t ADC_FifoThdLevel; ? ? ?/**< Specifies the ADC FIFO threshold to trigger \ref ADC_INT_FIFO_THD interrupt.
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? This parameter can be a value of 0 to 31. */
? ? uint32_t ADC_WaterLevel; ? ? ? ?/**< Specifies the ADC FIFO burst size to trigger GDMA.
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? This parameter can be a value of 0 to 31. */
? ? uint32_t ADC_FifoOverWriteEn; ? /**< Specifies if over write FIFO when FIFO overflow.
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? This parameter can be a value of \ref ADC_Over_Write_Enable. */
? ? uint32_t ADC_DataLatchEdge; ? ? /**< Specifies ADC data latch edge.
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? This parameter can be a value of \ref ADC_Latch_Data_Edge. */
? ? uint16_t ADC_SchIndex[16]; ? ? ?/**< Specifies ADC mode and channel for schedule table.
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? This parameter can be a value of \ref ADC_Schedule_Table. */
? ? uint16_t ADC_Bitmap; ? ? ? ? ? ?/**< Specifies the schedule table channel map.
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? This parameter can be a value of 16-bit map. */
? ? uint32_t ADC_TimerTriggerEn; ? ?/**< Enable ADC one-shot mode when tim7 toggles. */
? ? uint32_t ADC_DataAlign; ? ? ? ? /**< ADC data MSB or LSB aligned. */
? ? uint32_t ADC_DataMinusEn; ? ? ? /**< Enable or disable function that adc data latched minus the given offset before writes to reg/FIFO. */
? ? uint32_t ADC_DataMinusOffset; ? /**< Offset to be minused from adc data latched. */
? ? uint32_t ADC_DataAvgSel; ? ? ? ?/**< Number of data for calculate average.
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? This parameter can be a value of \ref ADC_Data_Avg_Num. */
? ? uint32_t ADC_DataAvgEn; ? ? ? ? /**< Enable the calculation for average result of the one-shot data.
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? This parameter can be a value of \ref ADC_Data_Avg_En. */
? ? uint32_t ADC_PowerOnMode; ? ? ? /**< Specifies ADC power on mode.
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? This parameter can be a value of \ref ADC_Power_On_Mode. */
? ? uint32_t ADC_PowerAlwaysOnEn; ? /**< Specifies the power always on.
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? This parameter can be a value of \ref ADC_Power_Always_On_Cmd. */
? ? uint32_t ADC_DataLatchDly; ? ? ?/**< Specifies delay of ck_ad to latch data.*/
? ? uint32_t ADC_RG2X0Dly; ? ? ? ? ?/**< Specifies the power on delay time selection of RG2X_AUXADC[0].
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? This parameter can be a value of \ref ADC_RG2X_0_Delay_Time */
? ? uint32_t ADC_RG0X1Dly; ? ? ? ? ?/**< Specifies the power on delay time selection of RG0X_AUXADC[1].
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? This parameter can be a value of \ref ADC_RG0X_1_Delay_Time */
? ? uint32_t ADC_RG0X0Dly; ? ? ? ? ?/**< Specifies the power on delay time selection of RG0X_AUXADC[0].
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? This parameter can be a value of \ref ADC_RG0X_0_Delay_Time */
} ADC_InitTypeDef;
?
/**
?* \defgroup ? ?ADC_Convert_Time ADC Convert Time
?* \{
?* \ingroup ? ? ADC_Exported_Constants
?*/
#define ADC_CONVERT_TIME_500NS ? ? ? ? ? ? ? ? ? ? ?((uint32_t)(0 << 9))
/** \defgroup ? ADC_Data_Write_To_Fifo ?Write DATA To FIFO
?* \{
?* \ingroup ? ? ADC_Exported_Constants
?*/
#define ADC_DATA_WRITE_TO_FIFO_DISABLE ? ? ? ? ? ? ?((uint32_t)(0 << 27))
#define ADC_DATA_WRITE_TO_FIFO_ENABLE ? ? ? ? ? ? ? ((uint32_t)(1 << 27))
/**
?* \defgroup ? ?ADC_Interrupts_Definition ADC Interrupts Definition
?* \{
?* \ingroup ? ? ADC_Exported_Constants
?*/#define ADC_INT_FIFO_RD_REQ ? ? ? ? ? ? ? ? ? ? ? ? ((uint32_t)(1 << 0))
#define ADC_INT_FIFO_RD_ERR ? ? ? ? ? ? ? ? ? ? ? ? ((uint32_t)(1 << 1))
#define ADC_INT_FIFO_THD ? ? ? ? ? ? ? ? ? ? ? ? ? ?((uint32_t)(1 << 2))
#define ADC_INT_FIFO_OVERFLOW ? ? ? ? ? ? ? ? ? ? ? ((uint32_t)(1 << 3))
#define ADC_INT_ONE_SHOT_DONE ? ? ? ? ? ? ? ? ? ? ? ((uint32_t)(1 << 4))
/** \} */
/**
?* \defgroup ? ?ADC_Schedule_Table ADC Channel and Mode
?* \{
?* \ingroup ? ? ADC_Exported_Constants
?*/
#define EXT_SINGLE_ENDED(index) ? ? ? ? ? ? ? ? ? ? ((uint16_t)((0x00 << 3) | (index)))
#define EXT_DIFFERENTIAL(index) ? ? ? ? ? ? ? ? ? ? ((uint16_t)((0x01 << 3) | (index)))
#define INTERNAL_VBAT_MODE ? ? ? ? ? ? ? ? ? ? ? ? ?((uint16_t)((0x02 << 3) | 0x00))
/** \} */
/**
?* \defgroup ? ?ADC_Data_Avg_Num ADC Data Averge Num
?* \{
?* \brief ? ? ? Number of raw data for calculate average.
?* \ingroup ? ? ADC_Exported_Constants
?*/#define ADC_DATA_AVERAGE_OF_2 ? ? ? ? ? ? ? ? ? ? ? ((uint32_t)(0 << 25))
#define ADC_DATA_AVERAGE_OF_4 ? ? ? ? ? ? ? ? ? ? ? ((uint32_t)(1 << 25))
#define ADC_DATA_AVERAGE_OF_8 ? ? ? ? ? ? ? ? ? ? ? ((uint32_t)(2 << 25))
#define ADC_DATA_AVERAGE_OF_16 ? ? ? ? ? ? ? ? ? ? ?((uint32_t)(3 << 25))
#define ADC_DATA_AVERAGE_OF_32 ? ? ? ? ? ? ? ? ? ? ?((uint32_t)(4 << 25))
#define ADC_DATA_AVERAGE_OF_64 ? ? ? ? ? ? ? ? ? ? ?((uint32_t)(5 << 25))
#define ADC_DATA_AVERAGE_OF_128 ? ? ? ? ? ? ? ? ? ? ((uint32_t)(6 << 25))
#define ADC_DATA_AVERAGE_OF_256 ? ? ? ? ? ? ? ? ? ? ((uint32_t)(7 << 25))
/** \} */
/**
?* \defgroup ? ?ADC_Power_On_Mode ADC Power On Mode
?* \{
?* \ingroup ? ? ADC_Exported_Constants
?*/#define ADC_POWER_ON_AUTO ? ? ? ? ? ? ? ? ? ? ? ? ? ((uint32_t)(0 << 19))
#define ADC_POWER_ON_MANUAL ? ? ? ? ? ? ? ? ? ? ? ? ((uint32_t)(1 << 19))
/** \} */
/**
?* \defgroup ? ?ADC_Power_Always_On_Cmd ADC Power Always On Cmd
?* \{
?* \ingroup ? ? ADC_Exported_Constants
?*/
#define ADC_POWER_ALWAYS_ON_DISABLE ? ? ? ? ? ? ? ? ((uint32_t)(0 << 15))
#define ADC_POWER_ALWAYS_ON_ENABLE ? ? ? ? ? ? ? ? ?((uint32_t)(1 << 15))
/** \} */?
/**
?* \defgroup ? ?ADC_RG2X_0_Delay_Time ADC RG2X_0 Delay Time
?* \{
?* \ingroup ? ? ADC_Exported_Constants
?*/
#define ADC_RG2X_0_DELAY_10_US ? ? ? ? ? ? ? ? ? ? ?((uint32_t)(0 << 4))
#define ADC_RG2X_0_DELAY_20_US ? ? ? ? ? ? ? ? ? ? ?((uint32_t)(1 << 4))
#define ADC_RG2X_0_DELAY_40_US ? ? ? ? ? ? ? ? ? ? ?((uint32_t)(2 << 4))
#define ADC_RG2X_0_DELAY_80_US ? ? ? ? ? ? ? ? ? ? ?((uint32_t)(3 << 4))
/** \} */?
/**
?* rtl876x_adc.h
?* \brief Initializes the ADC peripheral according to the specified
?* ? ? parameters in the ADC_InitStruct
?* \param[in] ?ADCx: selected ADC peripheral.
?* \param[in] ?ADC_InitStruct: pointer to a ADC_InitTypeDef structure that
?* ? ? contains the configuration information for the specified ADC peripheral
?* \return ? ? ?None.
?*
?* <b>Example usage</b>
?* \code{.c}
?*
?* void driver_adc_init(void)
?* {
?* ? ?//Turn on the clock.
?* ? ?RCC_PeriphClockCmd(APBPeriph_ADC, APBPeriph_ADC_CLOCK, ENABLE);?* ? ?ADC_InitTypeDef ADC_InitStruct;
?* ? ?ADC_StructInit(&ADC_InitStruct);
?* ? ?ADC_InitStruct.ADC_SchIndex[0] = EXT_SINGLE_ENDED(0);
?* ? ?ADC_InitStruct.ADC_SchIndex[1] = EXT_SINGLE_ENDED(1);
?* ? ?ADC_InitStruct.ADC_Bitmap = 0x03;
?* ? ?//Add other initialization parameters that need to be configured here.
?* ? ?ADC_Init(ADC, &ADC_InitStruct);
?* }
?* \endcode
?*/
void ADC_Init(ADC_TypeDef *ADCx, ADC_InitTypeDef *ADC_InitStruct);/**
? * @brief ?Fills each ADC_InitStruct member with its default value.
? * @param ?ADC_InitStruct: pointer to an ADC_InitTypeDef structure which will be initialized.
? * @retval None
? */
void ADC_StructInit(ADC_InitTypeDef *ADC_InitStruct)
{
? ? ADC_InitStruct->ADC_SampleTime ? ? ?= 255; ?/* (n + 1) cycle of 10MHz,n = 0~255 or n = 2048~14591 */
? ? ADC_InitStruct->ADC_ConvertTime ? ? = ADC_CONVERT_TIME_500NS;? ? ADC_InitStruct->ADC_DataWriteToFifo = ADC_DATA_WRITE_TO_FIFO_DISABLE;
? ? ADC_InitStruct->ADC_FifoThdLevel ? ?= 0x0A;
? ? ADC_InitStruct->ADC_WaterLevel ? ? ?= 0x1;
? ? ADC_InitStruct->ADC_FifoOverWriteEn = ADC_FIFO_OVER_WRITE_ENABLE;
? ? ADC_InitStruct->ADC_DataLatchEdge ? = ADC_LATCH_DATA_Positive;? ? ADC_InitStruct->ADC_SchIndex[0] ? ? = 0;
? ? ADC_InitStruct->ADC_SchIndex[1] ? ? = 0;
? ? ADC_InitStruct->ADC_SchIndex[2] ? ? = 0;
? ? ADC_InitStruct->ADC_SchIndex[3] ? ? = 0;
? ? ADC_InitStruct->ADC_SchIndex[4] ? ? = 0;
? ? ADC_InitStruct->ADC_SchIndex[5] ? ? = 0;
? ? ADC_InitStruct->ADC_SchIndex[6] ? ? = 0;
? ? ADC_InitStruct->ADC_SchIndex[7] ? ? = 0;
? ? ADC_InitStruct->ADC_SchIndex[8] ? ? = 0;
? ? ADC_InitStruct->ADC_SchIndex[9] ? ? = 0;
? ? ADC_InitStruct->ADC_SchIndex[10] ? ?= 0;
? ? ADC_InitStruct->ADC_SchIndex[11] ? ?= 0;
? ? ADC_InitStruct->ADC_SchIndex[12] ? ?= 0;
? ? ADC_InitStruct->ADC_SchIndex[13] ? ?= 0;
? ? ADC_InitStruct->ADC_SchIndex[14] ? ?= 0;
? ? ADC_InitStruct->ADC_SchIndex[15] ? ?= 0;
? ? ADC_InitStruct->ADC_Bitmap ? ? ? ? ?= 0x0;? ? ADC_InitStruct->ADC_TimerTriggerEn ?= ADC_TIMER_TRIGGER_DISABLE;
? ? ADC_InitStruct->ADC_DataAlign ? ? ? = ADC_DATA_ALIGN_LSB;
? ? ADC_InitStruct->ADC_DataMinusEn ? ? = ADC_DATA_MINUS_DISABLE;
? ? ADC_InitStruct->ADC_DataMinusOffset = 0;? ? ADC_InitStruct->ADC_DataAvgEn ? ? ? = ADC_DATA_AVERAGE_DISABLE;
? ? ADC_InitStruct->ADC_DataAvgSel ? ? ?= ADC_DATA_AVERAGE_OF_2;
? ? /* Reserved parameter, please do not change values*/
? ? ADC_InitStruct->ADC_PowerOnMode ? ? = ADC_POWER_ON_AUTO;
? ? ADC_InitStruct->ADC_PowerAlwaysOnEn = ADC_POWER_ALWAYS_ON_DISABLE;
? ? ADC_InitStruct->ADC_DataLatchDly ? ?= 0x1;
? ? ADC_InitStruct->ADC_RG2X0Dly ? ? ? ?= ADC_RG2X_0_DELAY_10_US;
? ? ADC_InitStruct->ADC_RG0X1Dly ? ? ? ?= ADC_RG0X_1_DELAY_20_US;
? ? ADC_InitStruct->ADC_RG0X0Dly ? ? ? ?= ADC_RG0X_0_DELAY_30_US;? ? return;
}
?typedef enum
{
? ? NO_ERROR = 0,
? ? PARAMETER_ERROR = -1,
? ? RAM_DATA_ERROR = -2,
? ? NO_CALIBRATION = -3,
? ? VERSION_ERROR = -4,
} ADC_ErrorStatus;
/**
?* rtl876x_adc.h
?* \brief ? Fills each ADC_InitStruct member with its default value.
?* \param[in] ADC_InitStruct: Pointer to an ADC_InitTypeDef structure which will be initialized.
?* \return ?None.
?*
?* <b>Example usage</b>
?* \code{.c}
?*
?* void driver_adc_init(void)
?* {
?* ? ?//Turn on the clock.
?* ? ?RCC_PeriphClockCmd(APBPeriph_ADC, APBPeriph_ADC_CLOCK, ENABLE);?* ? ?ADC_InitTypeDef ADC_InitStruct;
?* ? ?ADC_StructInit(&ADC_InitStruct);
?* ? ?ADC_InitStruct.ADC_SchIndex[0] = EXT_SINGLE_ENDED(0);
?* ? ?ADC_InitStruct.ADC_SchIndex[1] = EXT_SINGLE_ENDED(1);
?* ? ?ADC_InitStruct.ADC_Bitmap = 0x03;
?* ? ?//Add other initialization parameters that need to be configured here.
?* ? ?ADC_Init(ADC, &ADC_InitStruct);
?* }
?* \endcode
?* \callgraph
?*
?*/
void ADC_StructInit(ADC_InitTypeDef *ADC_InitStruct);/**
? * @brief ?Fills each ADC_InitStruct member with its default value.
? * @param ?ADC_InitStruct: pointer to an ADC_InitTypeDef structure which will be initialized.
? * @retval None
? */
void ADC_StructInit(ADC_InitTypeDef *ADC_InitStruct)
{
? ? ADC_InitStruct->ADC_SampleTime ? ? ?= 255; ?/* (n + 1) cycle of 10MHz,n = 0~255 or n = 2048~14591 */
? ? ADC_InitStruct->ADC_ConvertTime ? ? = ADC_CONVERT_TIME_500NS;? ? ADC_InitStruct->ADC_DataWriteToFifo = ADC_DATA_WRITE_TO_FIFO_DISABLE;
? ? ADC_InitStruct->ADC_FifoThdLevel ? ?= 0x0A;
? ? ADC_InitStruct->ADC_WaterLevel ? ? ?= 0x1;
? ? ADC_InitStruct->ADC_FifoOverWriteEn = ADC_FIFO_OVER_WRITE_ENABLE;
? ? ADC_InitStruct->ADC_DataLatchEdge ? = ADC_LATCH_DATA_Positive;? ? ADC_InitStruct->ADC_SchIndex[0] ? ? = 0;
? ? ADC_InitStruct->ADC_SchIndex[1] ? ? = 0;
? ? ADC_InitStruct->ADC_SchIndex[2] ? ? = 0;
? ? ADC_InitStruct->ADC_SchIndex[3] ? ? = 0;
? ? ADC_InitStruct->ADC_SchIndex[4] ? ? = 0;
? ? ADC_InitStruct->ADC_SchIndex[5] ? ? = 0;
? ? ADC_InitStruct->ADC_SchIndex[6] ? ? = 0;
? ? ADC_InitStruct->ADC_SchIndex[7] ? ? = 0;
? ? ADC_InitStruct->ADC_SchIndex[8] ? ? = 0;
? ? ADC_InitStruct->ADC_SchIndex[9] ? ? = 0;
? ? ADC_InitStruct->ADC_SchIndex[10] ? ?= 0;
? ? ADC_InitStruct->ADC_SchIndex[11] ? ?= 0;
? ? ADC_InitStruct->ADC_SchIndex[12] ? ?= 0;
? ? ADC_InitStruct->ADC_SchIndex[13] ? ?= 0;
? ? ADC_InitStruct->ADC_SchIndex[14] ? ?= 0;
? ? ADC_InitStruct->ADC_SchIndex[15] ? ?= 0;
? ? ADC_InitStruct->ADC_Bitmap ? ? ? ? ?= 0x0;? ? ADC_InitStruct->ADC_TimerTriggerEn ?= ADC_TIMER_TRIGGER_DISABLE;
? ? ADC_InitStruct->ADC_DataAlign ? ? ? = ADC_DATA_ALIGN_LSB;
? ? ADC_InitStruct->ADC_DataMinusEn ? ? = ADC_DATA_MINUS_DISABLE;
? ? ADC_InitStruct->ADC_DataMinusOffset = 0;? ? ADC_InitStruct->ADC_DataAvgEn ? ? ? = ADC_DATA_AVERAGE_DISABLE;
? ? ADC_InitStruct->ADC_DataAvgSel ? ? ?= ADC_DATA_AVERAGE_OF_2;
? ? /* Reserved parameter, please do not change values*/
? ? ADC_InitStruct->ADC_PowerOnMode ? ? = ADC_POWER_ON_AUTO;
? ? ADC_InitStruct->ADC_PowerAlwaysOnEn = ADC_POWER_ALWAYS_ON_DISABLE;
? ? ADC_InitStruct->ADC_DataLatchDly ? ?= 0x1;
? ? ADC_InitStruct->ADC_RG2X0Dly ? ? ? ?= ADC_RG2X_0_DELAY_10_US;
? ? ADC_InitStruct->ADC_RG0X1Dly ? ? ? ?= ADC_RG0X_1_DELAY_20_US;
? ? ADC_InitStruct->ADC_RG0X0Dly ? ? ? ?= ADC_RG0X_0_DELAY_30_US;? ? return;
}
/**
? * @brief ?Initializes the ADC peripheral according to the specified
? * ? ? ? ? parameters in the ADC_InitStruct
? * @param ?ADCx: selected ADC peripheral.
? * @param ?ADC_InitStruct: pointer to a ADCInitTypeDef structure that
? * ? ? ? ? contains the configuration information for the specified ADC peripheral
? * @retval None
? */
void ADC_Init(ADC_TypeDef *ADCx, ADC_InitTypeDef *ADC_InitStruct)
{
? ? assert_param(IS_ADC_PERIPH(ADCx));
? ? assert_param(IS_ADC_DATA_WRITE_TO_FIFO_CMD(ADC_InitStruct->ADC_DataWriteToFifo));
? ? assert_param(IS_ADC_FIFO_THRESHOLD(ADC_InitStruct->ADC_FifoThdLevel));
? ? assert_param(IS_ADC_WATER_LEVEL_CONFIG(ADC_InitStruct->ADC_WaterLevel));
? ? assert_param(IS_ADC_OVERWRITE_MODE(ADC_InitStruct->ADC_FifoOverWriteEn));
? ? assert_param(IS_ADC_LATCH_DATA_EDGE(ADC_InitStruct->ADC_DataLatchEdge));
? ? assert_param(IS_ADC_DATA_AVG_NUM(ADC_InitStruct->ADC_DataAvgSel));
? ? assert_param(IS_ADC_DATA_AVG_EN(ADC_InitStruct->ADC_DataAvgEn));
? ? assert_param(IS_ADC_POWER_ON_MODE(ADC_InitStruct->ADC_PowerOnMode));
? ? assert_param(IS_ADC_RG2X_0_DELAY_TIME(ADC_InitStruct->ADC_RG2X0Dly));
? ? assert_param(IS_ADC_RG0X_1_DELAY_TIME(ADC_InitStruct->ADC_RG0X1Dly));
? ? assert_param(IS_ADC_RG0X_0_DELAY_TIME(ADC_InitStruct->ADC_RG0X0Dly));
? ? assert_param(IS_ADC_DATA_MINUS_CMD(ADC_InitStruct->ADC_DataMinusEn));
? ? assert_param(IS_ADC_DATA_ALIGN(ADC_InitStruct->ADC_DataAlign));
? ? assert_param(IS_ADC_TIMER_TRIGGER_CMD(ADC_InitStruct->ADC_TimerTriggerEn));
? ? assert_param(IS_ADC_POWER_ALWAYS_ON(ADC_InitStruct->ADC_PowerAlwaysOnEn));
? ? assert_param(IS_ADC_CONVERT_TIME(ADC_InitStruct->ADC_ConvertTime));? ? /* Added to stabilize the power supply! */
? ? uint8_t reg_value = 0;
? ? reg_value = btaon_fast_read_safe(0x110);
? ? btaon_fast_write(0x110, reg_value | 0x04);? ? uint8_t index = 0;
? ? /*Disable all interrupt.*/
? ? ADCx->INTCR &= (~0x1f);? ? /* Set power mode first */
? ? ADCx->PWRDLY = (((ADC_InitStruct->ADC_DataLatchDly & 0x7) << 6) |
? ? ? ? ? ? ? ? ? ? ADC_InitStruct->ADC_PowerAlwaysOnEn |
? ? ? ? ? ? ? ? ? ? ADC_InitStruct->ADC_PowerOnMode);
? ? if (ADC_InitStruct->ADC_PowerOnMode == ADC_POWER_ON_AUTO)
? ? {
? ? ? ? ADCx->PWRDLY |= (ADC_InitStruct->ADC_RG2X0Dly \
? ? ? ? ? ? ? ? ? ? ? ? ?| ADC_InitStruct->ADC_RG0X1Dly \
? ? ? ? ? ? ? ? ? ? ? ? ?| ADC_InitStruct->ADC_RG0X0Dly);
? ? }? ? if (ADC_InitStruct->ADC_DataAvgEn == ADC_DATA_AVERAGE_ENABLE)
? ? {
? ? ? ? ADCx->PWRDLY |= (ADC_InitStruct->ADC_DataAvgEn | ADC_InitStruct->ADC_DataAvgSel);
? ? ? ? /* Disable schedule table */
? ? ? ? ADCx->SCHCR &= (~0xffff);
? ? ? ? /* Set schedule table */
? ? ? ? ADCx->SCHTAB0 = ADC_InitStruct->ADC_SchIndex[0];
? ? ? ? ADCx->SCHCR |= (uint16_t)0x0001;
? ? }
? ? else
? ? {
? ? ? ? /* Disable schedule table */
? ? ? ? ADCx->SCHCR &= (~0xffff);? ? ? ? /* Set schedule table */
? ? ? ? for (index = 0; index < 8; index++)
? ? ? ? {
? ? ? ? ? ? *(__IO uint32_t *)((uint32_t *)(&ADCx->SCHTAB0) + index) = (ADC_InitStruct->ADC_SchIndex[index * 2]
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (ADC_InitStruct->ADC_SchIndex[index * 2 + 1] << 16));
? ? ? ? }
? ? ? ? ADCx->SCHCR = ADC_InitStruct->ADC_Bitmap;
? ? }
? ? /* Set ADC mode */
? ? ADCx->CR = ((ADC_InitStruct->ADC_DataWriteToFifo)
? ? ? ? ? ? ? ? | ((ADC_InitStruct->ADC_FifoThdLevel & 0x3F) << 20)
? ? ? ? ? ? ? ? | ((ADC_InitStruct->ADC_WaterLevel & 0x3F) << 14)
? ? ? ? ? ? ? ? | (ADC_InitStruct->ADC_FifoOverWriteEn)
? ? ? ? ? ? ? ? | (ADC_InitStruct->ADC_DataLatchEdge));? ? /* adc data and clock config */
? ? if ((ADC_InitStruct->ADC_SampleTime & 0x38FF) < 19)
? ? {
? ? ? ? /* adc sample period max 400kHz */
? ? ? ? ADC_InitStruct->ADC_SampleTime = 19;
? ? }? ? ADCx->DATCLK = ((ADC_InitStruct->ADC_DataMinusEn)
? ? ? ? ? ? ? ? ? ? | (ADC_InitStruct->ADC_DataAlign)
? ? ? ? ? ? ? ? ? ? | (ADC_InitStruct->ADC_TimerTriggerEn)
? ? ? ? ? ? ? ? ? ? | ((ADC_InitStruct->ADC_DataMinusOffset & 0xFFF) << 16)
? ? ? ? ? ? ? ? ? ? | ((ADC_InitStruct->ADC_ConvertTime))
? ? ? ? ? ? ? ? ? ? | ((ADC_InitStruct->ADC_SampleTime & 0x3800) << 2)
? ? ? ? ? ? ? ? ? ? | (ADC_InitStruct->ADC_SampleTime & 0xFF));
? ? ADCx->ANACTL |= (0x03 << 10);? ? /*clear adc fifo*/
? ? ADCx->CR |= BIT26;
? ? /*clear all interrupt*/
? ? ADCx->INTCR |= (0x1f << 8);? ? return;
}
?
?/**
?* rtl876x_adc.h
?* \brief ? ? Config ADC bypass resistor.
?* \param[in] channelNum: External channel number, can be 0~7.
?* \param[in] NewState: Specifies whether the channel enables bypass mode.
?* ? ? ? ? ? ?This parameter can be: ENABLE or DISABLE.
?* \return ? ?None.
?* \attention The input voltage of channel pin using bypass mode cannot exceed 0.9V!
?*
?* <b>Example usage</b>
?* \code{.c}
?*
?* void adc_demo(void)
?* {
?* ? ADC_BypassCmd(0,ENABLE);
?* }
?* \endcode
?*/
void ADC_BypassCmd(uint8_t ChannelNum, FunctionalState NewState);/**
? * @brief ?Config ADC bypass resistor.Attention!!!Channels using bypass mode cannot over 0.9V!!!!
? * @param ?channelNum: external channel number, can be 0~7.
? * @param ?NewState: ENABLE or DISABLE.
? * @retval None
? */
void ADC_BypassCmd(uint8_t ChannelNum, FunctionalState NewState)
{
? ? assert_param(ChannelNum <= 7);
? ? assert_param(IS_FUNCTIONAL_STATE(NewState));? ? if (NewState != DISABLE)
? ? {
? ? ? ? ADC->ANACTL |= BIT(ChannelNum + 16);
? ? }
? ? else
? ? {
? ? ? ? ADC->ANACTL &= ~BIT(ChannelNum + 16);
? ? }
}
/**
?* rtl876x_adc.h
?* \brief ? Enables or disables the ADC peripheral.
?* \param[in] ?ADCx: Specify ADC peripheral.
?* \param[in] ?adcMode: ADC operation mode selection.
? ? ? ? This parameter can be one of the following values:
?* ? ? \arg ADC_ONE_SHOT_MODE: One shot mode.
?* ? ? \arg ADC_CONTINUOUS_MODE: Continuous sampling mode.
?* \param[in] ?NewState: New state of the ADC peripheral.
?* ? ? This parameter can be: ENABLE or DISABLE.
?* \return ?None.
?*
?* <b>Example usage</b>
?* \code{.c}
?*
?* void board_adc_init(void)
?* {
?* ? ? Pad_Config(P2_0, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE,
?* ? ? ? ? ? ? ? ?PAD_OUT_LOW);
?*
?* ? ? Pad_Config(P2_1, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE,
?* ? ? ? ? ? ? ? ?PAD_OUT_LOW);
?* }
?*
?* void driver_adc_init(void)
?* {
?* ? ?//open clock
?* ? ?RCC_PeriphClockCmd(APBPeriph_ADC, APBPeriph_ADC_CLOCK, ENABLE);
?*
?* ? ?ADC_InitTypeDef ADC_InitStruct;
?* ? ?ADC_StructInit(&ADC_InitStruct);
?* ? ?ADC_InitStruct.ADC_SchIndex[0] = EXT_SINGLE_ENDED(0);
?* ? ?ADC_InitStruct.ADC_SchIndex[1] = EXT_SINGLE_ENDED(1);
?* ? ?ADC_InitStruct.ADC_Bitmap = 0x03;
?* ? ?//Add other initialization parameters here.
?* ? ?ADC_Init(ADC, &ADC_InitStruct);
?*
?* ? ?ADC_INTConfig(ADC, ADC_INT_ONE_SHOT_DONE, ENABLE);
?* }
?*
?* void adc_demo(void)
?* {
?* ? ?board_adc_init();
?* ? ?driver_adc_init();
?* ? ?ADC_Cmd(ADC, ADC_ONE_SHOT_MODE, ENABLE);
?* }
?* \endcode
?*/
void ADC_Cmd(ADC_TypeDef *ADCx, uint8_t adcMode, FunctionalState NewState);?/**
? * @brief ?Enables or disables the ADC peripheral.
? * @param ?ADCx: selected ADC peripheral.
? * @param ?adcMode: adc mode select.
? ? ? ? This parameter can be one of the following values:
? * ? ? @arg ADC_ONE_SHOT_MODE: one shot mode.
? * ? ? @arg ADC_CONTINUOUS_MODE: continuous mode.
? * @param ?NewState: new state of the ADC peripheral.
? * ? ? This parameter can be: ENABLE or DISABLE.
? * @retval None
? */
void ADC_Cmd(ADC_TypeDef *ADCx, uint8_t adcMode, FunctionalState NewState)
{
? ? /* Check the parameters */
? ? assert_param(IS_ADC_PERIPH(ADCx));
? ? assert_param(IS_ADC_SAMPLE_MODE(adcMode));
? ? assert_param(IS_FUNCTIONAL_STATE(NewState));? ? if (NewState == ENABLE)
? ? {
? ? ? ? /* In case manual mode */
? ? ? ? if (ADCx->PWRDLY ?& ADC_POWER_ON_MANUAL)
? ? ? ? {
? ? ? ? ? ? ADCx->PWRDLY ?|= 0x3C00;
// ? ? ? ? ? ?ADC_DelayUs(80);
? ? ? ? ? ? platform_delay_us(80);
? ? ? ? ? ? ADCx->PWRDLY ?|= (BIT14 | BIT15);
// ? ? ? ? ? ?ADC_DelayUs(320);
? ? ? ? ? ? platform_delay_us(320);
? ? ? ? ? ? ADCx->PWRDLY ?|= (BIT16 | BIT17);
// ? ? ? ? ? ?ADC_DelayUs(240);
? ? ? ? ? ? platform_delay_us(240);
? ? ? ? ? ? ADCx->PWRDLY ?|= BIT18;
? ? ? ? }
? ? ? ? /* Reset ADC mode first */
? ? ? ? ADCx->CR &= ~0x03;
? ? ? ? /* Enable ADC */
? ? ? ? ADCx->CR |= adcMode;
? ? }
? ? else
? ? {
? ? ? ? ADCx->CR &= ~0x03;
? ? }? ? return;
}
bool ADC_CalibrationInit(void);?
srand(random_seed_value);
/**
?* rtl876x_adc.h
?* \brief ? Enables or disables the specified ADC interrupts.
?* \param[in] ?ADCx: Specify ADC peripheral.
?* \param[in] ?ADC_IT: Specify the ADC interrupts sources to be enabled or disabled.
?* ? ? This parameter can be any combination of the following values:
?* ? ? \arg ADC_INT_FIFO_RD_REQ : FIFO read request.
?* ? ? \arg ADC_INT_FIFO_RD_ERR : FIFO read error.
?* ? ? \arg ADC_INT_FIFO_THD : ADC FIFO size > thd.
?* ? ? \arg ADC_INT_FIFO_OVERFLOW : ADC FIFO overflow.
?* ? ? \arg ADC_INT_ONE_SHOT_DONE : ADC one shot mode done.
?* \param[in] ?newState: New state of the specified ADC interrupt.
?* ? ? This parameter can be: ENABLE or DISABLE.
?* \return ?None.
?*
?* <b>Example usage</b>
?* \code{.c}
?*
?* void driver_adc_init(void)
?* {
?* ? ?//open clock
?* ? ?RCC_PeriphClockCmd(APBPeriph_ADC, APBPeriph_ADC_CLOCK, ENABLE);
?*
?* ? ?ADC_InitTypeDef ADC_InitStruct;
?* ? ?ADC_StructInit(&ADC_InitStruct);
?* ? ?ADC_InitStruct.ADC_SchIndex[0] = EXT_SINGLE_ENDED(0);
?* ? ?ADC_InitStruct.ADC_SchIndex[1] = EXT_SINGLE_ENDED(1);
?* ? ?ADC_InitStruct.ADC_Bitmap = 0x03;
?* ? ?//Add other initialization parameters here.
?* ? ?ADC_Init(ADC, &ADC_InitStruct);
?*
?* ? ?ADC_INTConfig(ADC, ADC_INT_FIFO_RD_ERR, ENABLE);
?* ? ?ADC_INTConfig(ADC, ADC_INT_ONE_SHOT_DONE, ENABLE);
?* }
?* \endcode
?*
?*/
void ADC_INTConfig(ADC_TypeDef *ADCx, uint32_t ADC_INT, FunctionalState NewState);?/**
? * @brief ?Enables or disables the specified ADC interrupts.
? * @param ?ADCx: selected ADC peripheral.
? * @param ?ADC_INT: specifies the ADC interrupts sources to be enabled or disabled.
? * ? ? ? ? This parameter can be any combination of the following values:
? * ? ? ? ? @arg ADC_INT_FIFO_RD_REQ :FIFO read request
? * ? ? ? ? @arg ADC_INT_FIFO_RD_ERR :FIFO read error
? * ? ? ? ? @arg ADC_INT_FIFO_THD :ADC FIFO size > thd
? * ? ? ? ? @arg ADC_INT_FIFO_FULL :ADC FIFO overflow
? * ? ? ? ? @arg ADC_INT_ONE_SHOT_DONE :ADC one shot mode done
? * @param ?NewState: new state of the specified ADC interrupts.
? * ? ? ? ? This parameter can be: ENABLE or DISABLE.
? * @retval None
? */
void ADC_INTConfig(ADC_TypeDef *ADCx, uint32_t ADC_INT, FunctionalState NewState)
{
? ? /* Check the parameters */
? ? assert_param(IS_ADC_PERIPH(ADCx));
? ? assert_param(IS_ADC_INT(ADC_INT));
? ? assert_param(IS_FUNCTIONAL_STATE(NewState));? ? if (NewState != DISABLE)
? ? {
? ? ? ? /* Enable the selected ADC interrupts */
? ? ? ? ADCx->INTCR |= ADC_INT;
? ? }
? ? else
? ? {
? ? ? ? /* Disable the selected ADC interrupts */
? ? ? ? ADCx->INTCR &= (uint32_t)~ADC_INT;
? ? }
}
?
/**
?* rtl876x_adc.h
?* \brief ?Check whether the specified ADC interrupt flag is set.
?* \param[in] ?ADCx: selected ADC peripheral.
?* \param[in] ?ADC_INT_FLAG: Specifies the interrupt flag to check.
?* ? ? This parameter can be one of the following values:
?* ? ? \arg ADC_INT_ONE_SHOT_DONE: ADC once convert end interrupt.
?* ? ? \arg ADC_INT_FIFO_OVERFLOW: ADC FIFO overflow interrupt.
?* ? ? \arg ADC_INT_FIFO_THD: FIFO larger than threshold interrupt.
?* ? ? \arg ADC_INT_FIFO_RD_ERR: ADC read FIFO error interrupt.
?* ? ? \arg ADC_INT_FIFO_RD_REQ: ADC read FIFO request interrupt.
?*
?* \return The new state of ADC_INT (SET or RESET).
?* \retval SET.
?* \retval RESET.
?*
?* <b>Example usage</b>
?* \code{.c}
?*
?* void adc_demo(void)
?* {
?* ? ? ITStatus int_status = RESET;
?* ? ? int_status = ADC_GetINTStatus(ADC,ADC_INT_FIFO_OVERFLOW);
?* }
?* \endcode
?*/
ITStatus ADC_GetINTStatus(ADC_TypeDef *ADCx, uint32_t ADC_INT);/**
? * @brief ?Checks whether the specified ADC interrupt status flag is set or not.
? * @param ?ADCx: selected ADC peripheral.
? * @param ?ADC_INT_FLAG: specifies the interrupt status flag to check.
? * ? ? This parameter can be one of the following values:
? * ? ? @arg ADC_INT_ONE_SHOT_DONE: ADC once convert end interrupt
? * ? ? @arg ADC_INT_FIFO_OVERFLOW: ADC FIFO overflow interrupt
? * ? ? @arg ADC_INT_FIFO_THD: fifo larger than threshold
? * ? ? @arg ADC_INT_FIFO_RD_ERR: ADC read FIFO error interrupt
? * ? ? @arg ADC_INT_FIFO_RD_REQ: ADC read FIFO request interrupt
? * @retval The new state of ADC_INT (SET or RESET).
? */
ITStatus ADC_GetINTStatus(ADC_TypeDef *ADCx, uint32_t ADC_INT)
{
? ? /* Check the parameters */
? ? assert_param(IS_ADC_PERIPH(ADCx));
? ? assert_param(IS_ADC_INT(ADC_INT));? ? FlagStatus bitstatus = RESET;
? ? if ((ADCx->INTCR & (ADC_INT << 16)) != 0)
? ? {
? ? ? ? bitstatus = SET;
? ? }? ? return bitstatus;
}
NOTE:获取中断状态?
/**
?* rtl876x_adc.h
?* \brief ? ? ?Read ADC data according to specific channel.
?* \param[in] ?ADCx: Specify ADC peripheral.
?* \param[in] ?index: Can be 0 to 15.
?* \return ? ? The 12-bit converted ADC raw data.
?*
?* <b>Example usage</b>
?* \code{.c}
?*
?* void board_adc_init(void)
?* {
?* ? ? Pad_Config(P2_0, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE,
?* ? ? ? ? ? ? ? ?PAD_OUT_LOW);
?*
?* ? ? Pad_Config(P2_1, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE,
?* ? ? ? ? ? ? ? ?PAD_OUT_LOW);
?* }
?*
?* void driver_adc_init(void)
?* {
?* ? ?//open clock
?* ? ?RCC_PeriphClockCmd(APBPeriph_ADC, APBPeriph_ADC_CLOCK, ENABLE);
?*
?* ? ?ADC_InitTypeDef ADC_InitStruct;
?* ? ?ADC_StructInit(&ADC_InitStruct);
?* ? ?ADC_InitStruct.ADC_SchIndex[0] = EXT_SINGLE_ENDED(0);
?* ? ?ADC_InitStruct.ADC_SchIndex[1] = EXT_SINGLE_ENDED(1);
?* ? ?ADC_InitStruct.ADC_Bitmap = 0x03;
?* ? ?//Add other initialization parameters here.
?* ? ?ADC_Init(ADC, &ADC_InitStruct);
?*
?* ? ?ADC_INTConfig(ADC, ADC_INT_ONE_SHOT_DONE, ENABLE);
?* }
?*
?* void adc_demo(void)
?* {
?* ? ?board_adc_init();
?* ? ?driver_adc_init();
?* ? ?ADC_Cmd(ADC, ADC_ONE_SHOT_MODE, ENABLE);
?* ? ?while(ADC_GetINTStatus(ADC, ADC_INT_ONE_SHOT_DONE) == RESET);
?* ? ?uint16_t raw_data_0 = ADC_ReadRawData(ADC, 0);
?* ? ?uint16_t raw_data_1 = ADC_ReadRawData(ADC, 1);
?* }
?* \endcode
?*/
uint16_t ADC_ReadRawData(ADC_TypeDef *ADCx, uint8_t index);
/**
? * @brief ?Read ADC data according to specific channel.
? * @param ?ADCx: selected ADC peripheral.
? * @param ?index: can be 0 to 15
? * @retval The 12-bit converted ADC data.
? */
uint16_t ADC_ReadRawData(ADC_TypeDef *ADCx, uint8_t index)
{
? ? /* Check the parameters */
? ? assert_param(IS_ADC_PERIPH(ADCx));
? ? assert_param(index < 16);? ? if (index & BIT(0))
? ? {
? ? ? ? return ((*(uint32_t *)((uint32_t *)(&ADCx->SCHD0) + (index >> 1))) >> 16);
? ? }
? ? else
? ? {
? ? ? ? return (*(uint32_t *)((uint32_t *)(&ADCx->SCHD0) + (index >> 1)));
? ? }
}
float ADC_GetVoltage(const ADC_SampleMode vSampleMode, int32_t vSampleData,
? ? ? ? ? ? ? ? ? ? ?ADC_ErrorStatus *pErrorStatus);?
NOTES:获取到的电压值单位是mV。?
PAD设置过程中,设置为软件模式?为什么?设置为软件模式之后,就不用配置PINMUX。
如果是ADC_ONE_SHOT_MODE模式,每一次启动都需要主动调用ADC_Cmd接口。