
/******************************************************************************
*@file  : app.c
*@brief : application
*@ver   : 1.0.0
*@date  : 2022.10.20
******************************************************************************/

#include "app.h"   


#define BUFFER_LENGTH    (21)
uint32_t gadcBuffer[BUFFER_LENGTH];                 //ADC Value
static volatile uint32_t gitcConunt = 0;            //transfer complete interrupt count
static volatile uint32_t gieConunt = 0;             //transfer error interrupt count
__IO uint32_t gadcxConvertedRegValue;               //ADC value obtained in interrupt      
static volatile uint32_t gadc1EocFlag = 0;          //ADC1 Regular channel conversion end interrupt flag
static volatile uint32_t gadc2EocFlag = 0;          //ADC2 Regular channel conversion end interrupt flag
static volatile uint32_t gadc1EogFlag = 0;          //ADC1 Regular channel group conversion end interrupt flag
static volatile uint32_t gadc2EogFlag = 0;          //ADC2 Regular channel group conversion end interrupt flag
static volatile uint32_t gadcExtTrigFlag = 0;       //ADC Regular channel External trigger flag
static volatile uint32_t gadc1ItcConunt = 0;        // transfer complete interrupt count

ADC_HandleTypeDef ADC_Handle;
DMA_HandleTypeDef  ADC1_DMAHandle = {0};

/******************************************************************************
* @brief : ADC interrupt callback function.
* @param : none
* @return: none
******************************************************************************/ 
void HAL_ADC_IRQCallback(void)
{
    __IO uint32_t Status;


    Status = ADC_Handle.Instance->SR;
    /************ Check End of Conversion flag for injected ************/
    if(__HAL_ADC_GET_IT_SOURCE(&ADC_Handle, ADC_IE_JEOCIE))
    {
        if((Status & ADC_SR_JEOC) == ADC_SR_JEOC)
        {
            /* Conversion complete callback */ 
            if (NULL != ADC_Handle.InjectedConvCpltCallback)
            {
                ADC_Handle.InjectedConvCpltCallback(&ADC_Handle);
            }

            /* Clear injected group conversion flag */
            __HAL_ADC_CLEAR_FLAG(&ADC_Handle, ADC_SR_JEOC);
        }
    }

    /************ Check End of Conversion flag for injected group ************/
    if(__HAL_ADC_GET_IT_SOURCE(&ADC_Handle, ADC_IE_JEOGIE))
    {	
        if((Status & ADC_SR_JEOG) == ADC_SR_JEOG)
        {
            if(ADC_IS_SOFTWARE_START_INJECTED(&ADC_Handle)    || \
            (ADC_IS_SOFTWARE_START_REGULAR(&ADC_Handle) &&(ADC_Handle.Init.ConConvMode == 0)) && (HAL_IS_BIT_CLR(ADC_Handle.Instance->CR1, ADC_CR1_JAUTO))) 
            {
                /* Disable ADC end of conversion interrupt on injected injected */
                __HAL_ADC_DISABLE_IT(&ADC_Handle, ADC_IE_JEOCIE);

            }

        /* Conversion complete callback */ 
        if (NULL != ADC_Handle.InjectedGroupConvCpltCallback)
        ADC_Handle.InjectedGroupConvCpltCallback(&ADC_Handle);

        /* Clear injected group conversion flag */
        __HAL_ADC_CLEAR_FLAG(&ADC_Handle, ADC_SR_JEOG);

        }

    }

    /************ Check Conversion flag for regular Channel ************/
    if(__HAL_ADC_GET_IT_SOURCE(&ADC_Handle, ADC_IE_EOCIE))
    {
        if((Status & ADC_SR_EOC) == ADC_SR_EOC)
        {      
            /* Conversion complete callback */
            if (NULL != ADC_Handle.ConvCpltCallback)
            ADC_Handle.ConvCpltCallback(&ADC_Handle);

            /* Clear conversion flag */
            __HAL_ADC_CLEAR_FLAG(&ADC_Handle, ADC_SR_EOC);
        }
    }

    /************ Check End of Conversion flag for regular group ************/
    if(__HAL_ADC_GET_IT_SOURCE(&ADC_Handle, ADC_IE_EOGIE))
    {
        if((Status & ADC_SR_EOG) == ADC_SR_EOG)
        {      
            if((__HAL_ADC_CHECK_TRIG_REGULAR(&ADC_Handle, ADC_SOFTWARE_START)) && 
            (ADC_Handle.Init.ConConvMode == 0))
            {
                /* Disable ADC end of conversion interrupt on group regular */
                __HAL_ADC_DISABLE_IT(&ADC_Handle, ADC_IE_EOGIE);
            }

            /* Conversion complete callback */
            if (NULL != ADC_Handle.GroupCpltCallback)
            ADC_Handle.GroupCpltCallback(&ADC_Handle);

            /* Clear regular group conversion flag */
            __HAL_ADC_CLEAR_FLAG(&ADC_Handle, ADC_SR_EOG);
        }
    }

    /************ Check Analog watchdog flags ************/
    if(__HAL_ADC_GET_IT_SOURCE(&ADC_Handle, ADC_IE_AWDIE))
    {
        if((Status & ADC_SR_AWD) == ADC_SR_AWD)
        {
            /* Level out of window callback */ 
            if (NULL != ADC_Handle.LevelOutOfWindowCallback)
            ADC_Handle.LevelOutOfWindowCallback(&ADC_Handle);

            /* Clear the ADC analog watchdog flag */
            __HAL_ADC_CLEAR_FLAG(&ADC_Handle, ADC_SR_AWD);
            }
    } 
}



/******************************************************************************
* @brief : EXTI interrupt callback function.
* @param : Line: EXTI line
* @return: none
******************************************************************************/ 
void HAL_EXTI_LineCallback(uint32_t Line)
{
    if (EXTI->PDR & Line) 
    {
        EXTI->PDR = Line;        
        if(ADC_Handle.Instance->SR & ADC_SR_EOC)
        {
            //clear
            __HAL_ADC_CLEAR_FLAG(&ADC_Handle,ADC_SR_EOC); 
            gadcxConvertedRegValue = HAL_ADC_GetValue(&ADC_Handle);
            gadcExtTrigFlag = 1;
        }
    }
}

/******************************************************************************
* @brief : ADC Get The VrefP Value.
* @param : none
* @return: VrefP Value
******************************************************************************/ 
uint32_t ADC_GetVrefP(void)
{
    ADC_HandleTypeDef ADC_Handle_Vrefp;
    ADC_ChannelConfTypeDef ADC_ChannelConf;
    uint32_t TrimValue_3v, AdcValue_VrefP[1], VrefP,temp;
    
    //PMU CLK Enable
    RCC->APB1ENR |= 1<<27;
    //VBG1P2
    *(__IO uint32_t*)(0x400070C0) = 0x05;
    
    HAL_SimpleDelay(2000);
    
    ADC_Handle_Vrefp.Init.ClockPrescaler = ADC_CLOCK_DIV16;       //ADC_CLK分频选择
    ADC_Handle_Vrefp.Init.Resolution     = ADC_RESOLUTION_12B;    //分辨率
    ADC_Handle_Vrefp.Init.DataAlign      = ADC_DATAALIGN_RIGHT;   //数据对齐
    ADC_Handle_Vrefp.Init.ConConvMode    = DISABLE;               //连续转换模式

    ADC_Handle_Vrefp.Init.DiscontinuousConvMode = DISABLE;        //间断模式
    ADC_Handle_Vrefp.Init.NbrOfDiscConversion = 1;                //间断模式通道计数
    ADC_Handle_Vrefp.Init.ExternalTrigConv = ADC_SOFTWARE_START;  //触发模式：外部触发或软件触发
    ADC_Handle_Vrefp.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;//外部触发边沿选择
    ADC_Handle_Vrefp.Init.DMAMode = ADC_DMAMODE_DISABLE;          //DMA选择
    ADC_Handle_Vrefp.Init.OverMode = ADC_OVERMODE_DISABLE;        //溢出时是否保留上次采样数据

    ADC_Handle_Vrefp.Init.OverSampMode = ADC_OVERSAMPMODE_DISABLE;//过采样使能设置
    ADC_Handle_Vrefp.Init.Oversampling.Ratio =ADC_OVERSAMPLING_RATIO_2;//过采样率
    ADC_Handle_Vrefp.Init.Oversampling.RightBitShift =ADC_RIGHTBITSHIFT_2;//过采样移位系数
    ADC_Handle_Vrefp.Init.Oversampling.TriggeredMode =0;          //过采样触发模式    
    ADC_Handle_Vrefp.Init.AnalogWDGEn = ADC_ANALOGWDGEN_DISABLE;  //模拟看门狗
    ADC_Handle_Vrefp.Init.ChannelEn = ADC_CHANNEL_VBGR_EN;

    ADC_Handle_Vrefp.Instance = ADC1;  

    HAL_ADC_Init(&ADC_Handle_Vrefp);

    /* The total adc regular channels number */
    ADC_Handle_Vrefp.ChannelNum = 1;
    
    /* Add adc channels */
    ADC_ChannelConf.Channel = ADC_CHANNEL_VBGR;
    ADC_ChannelConf.Sq = ADC_SEQUENCE_SQ1;
    ADC_ChannelConf.Smp = ADC_SMP_CLOCK_320;
    ADC_ChannelConf.SingleDiff = ADC_SINGLE_ENDED;
    ADC_ChannelConf.OffsetNumber = ADC_OFFSET_NONE;
    ADC_ChannelConf.Offset = 0;	
    HAL_ADC_ConfigChannel(&ADC_Handle_Vrefp,&ADC_ChannelConf);
    
    HAL_ADC_Polling(&ADC_Handle_Vrefp, AdcValue_VrefP, ADC_Handle_Vrefp.ChannelNum, 0);
    
    printfS("The adc convert result :  0x%08x[ %d ], VBGR = %dmV\r\n", AdcValue_VrefP[0], AdcValue_VrefP[0] & 0xFFF, ((AdcValue_VrefP[0] & 0xFFF) * 3300 / 4095));
    
    //VBG1P2
    *(__IO uint32_t*)(0x400070C0) &= ~0x05;
    
    TrimValue_3v = *(volatile uint32_t*)(0x00080240); //Read the 1.2v trim value in 3.0v vrefp.

    printfS("The adc 1.2v trim value is : 0x%08x \r\n", TrimValue_3v);

    if(((~TrimValue_3v&0xFFFF0000)>>16) == (TrimValue_3v&0x0000FFFF))
    {
        temp = TrimValue_3v & 0xFFF;
        
        VrefP = (uint32_t)(temp * 3000 / (AdcValue_VrefP[0] & 0xFFF));
      
        return VrefP;
    }
    return 0;
}


/******************************************************************************
* @brief : ADC Polling Mode Initialization.
* @param : none
* @return: none
******************************************************************************/ 
void ADC_Init_Polling_Nchannels(void)
{
    ADC_ChannelConfTypeDef ADC_ChannelConf;

    ADC_Handle.Init.ClockPrescaler = ADC_CLOCK_DIV16;       //ADC_CLK分频选择
    ADC_Handle.Init.Resolution     = ADC_RESOLUTION_12B;    //分辨率
    ADC_Handle.Init.DataAlign      = ADC_DATAALIGN_RIGHT;   //数据对齐
    ADC_Handle.Init.ConConvMode    = DISABLE;               //连续转换模式

    ADC_Handle.Init.DiscontinuousConvMode = DISABLE;        //间断模式
    ADC_Handle.Init.NbrOfDiscConversion   =1;               //间断模式通道计数
    ADC_Handle.Init.ExternalTrigConv = ADC_SOFTWARE_START;  //触发模式：外部触发或软件触发
    ADC_Handle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;//外部触发边沿选择
    ADC_Handle.Init.DMAMode = ADC_DMAMODE_DISABLE;          //DMA选择
    ADC_Handle.Init.OverMode = ADC_OVERMODE_DISABLE;        //溢出时是否保留上次采样数据

    ADC_Handle.Init.OverSampMode = ADC_OVERSAMPMODE_DISABLE;//过采样使能
    ADC_Handle.Init.Oversampling.Ratio =ADC_OVERSAMPLING_RATIO_2;//过采样率
    ADC_Handle.Init.Oversampling.RightBitShift =ADC_RIGHTBITSHIFT_2;//过采样移位系数
    ADC_Handle.Init.Oversampling.TriggeredMode =0;          //过采样触发模式    
    ADC_Handle.Init.AnalogWDGEn = ADC_ANALOGWDGEN_DISABLE;  //模拟看门狗
    ADC_Handle.Init.ChannelEn = ADC_CHANNEL_0_EN | ADC_CHANNEL_1_EN | ADC_CHANNEL_14_EN | ADC_CHANNEL_15_EN | \
                        ADC_CHANNEL_4_EN | ADC_CHANNEL_5_EN | ADC_CHANNEL_6_EN | ADC_CHANNEL_7_EN | \
                        ADC_CHANNEL_8_EN | ADC_CHANNEL_9_EN | ADC_CHANNEL_10_EN | ADC_CHANNEL_11_EN | \
                        ADC_CHANNEL_12_EN | ADC_CHANNEL_13_EN;// | ADC_CHANNEL_2_EN | ADC_CHANNEL_3_EN;

    ADC_Handle.Instance = ADC1;  //ADC2

    HAL_ADC_Init(&ADC_Handle);


    /* The total adc regular channels number */
    ADC_Handle.ChannelNum = 14;

    /* Add adc channels */
    ADC_ChannelConf.Channel = ADC_CHANNEL_0;
    ADC_ChannelConf.Sq = ADC_SEQUENCE_SQ1;  //转换顺序
    ADC_ChannelConf.Smp = ADC_SMP_CLOCK_320;//采样时间
    ADC_ChannelConf.SingleDiff =  ADC_SINGLE_ENDED;  // ADC_DIFFERENTIAL_ENDED ;    //单端/差分模式
    //offset config
    ADC_ChannelConf.OffsetNumber = ADC_OFFSET_NONE;   //modeString[0].number;  //ADC_OFFSET_NONE;  //偏移通道选择
    ADC_ChannelConf.Offset =  0; //偏移量
    ADC_ChannelConf.OffsetSign = 0; //偏移计算方式
    ADC_ChannelConf.OffsetSaturation = 0;//偏移结果格式选择
    HAL_ADC_ConfigChannel(&ADC_Handle,&ADC_ChannelConf);


    ADC_ChannelConf.Channel = ADC_CHANNEL_1;
    ADC_ChannelConf.Sq = ADC_SEQUENCE_SQ2;
    ADC_ChannelConf.Smp = ADC_SMP_CLOCK_320;
    ADC_ChannelConf.SingleDiff = ADC_SINGLE_ENDED;
    ADC_ChannelConf.OffsetNumber = ADC_OFFSET_NONE;
    ADC_ChannelConf.Offset = 0;	
    HAL_ADC_ConfigChannel(&ADC_Handle,&ADC_ChannelConf);

    ADC_ChannelConf.Channel = ADC_CHANNEL_4;
    ADC_ChannelConf.Sq = ADC_SEQUENCE_SQ3;
    ADC_ChannelConf.Smp = ADC_SMP_CLOCK_320;
    ADC_ChannelConf.SingleDiff = ADC_SINGLE_ENDED;
    ADC_ChannelConf.OffsetNumber = ADC_OFFSET_NONE;
    ADC_ChannelConf.Offset = 0;	
    HAL_ADC_ConfigChannel(&ADC_Handle,&ADC_ChannelConf);

    ADC_ChannelConf.Channel = ADC_CHANNEL_5;
    ADC_ChannelConf.Sq = ADC_SEQUENCE_SQ4;
    ADC_ChannelConf.Smp = ADC_SMP_CLOCK_320;
    ADC_ChannelConf.SingleDiff = ADC_SINGLE_ENDED;
    ADC_ChannelConf.OffsetNumber = ADC_OFFSET_NONE;
    ADC_ChannelConf.Offset = 0;	
    HAL_ADC_ConfigChannel(&ADC_Handle,&ADC_ChannelConf);

    ADC_ChannelConf.Channel = ADC_CHANNEL_6;
    ADC_ChannelConf.Sq = ADC_SEQUENCE_SQ5;
    ADC_ChannelConf.Smp = ADC_SMP_CLOCK_320;
    ADC_ChannelConf.SingleDiff = ADC_SINGLE_ENDED;
    ADC_ChannelConf.OffsetNumber = ADC_OFFSET_NONE;
    ADC_ChannelConf.Offset = 0;	
    HAL_ADC_ConfigChannel(&ADC_Handle,&ADC_ChannelConf);

    ADC_ChannelConf.Channel = ADC_CHANNEL_7;
    ADC_ChannelConf.Sq = ADC_SEQUENCE_SQ6;
    ADC_ChannelConf.Smp = ADC_SMP_CLOCK_320;
    ADC_ChannelConf.SingleDiff = ADC_SINGLE_ENDED;
    ADC_ChannelConf.OffsetNumber = ADC_OFFSET_NONE;
    ADC_ChannelConf.Offset = 0;	
    HAL_ADC_ConfigChannel(&ADC_Handle,&ADC_ChannelConf);

    ADC_ChannelConf.Channel = ADC_CHANNEL_8;
    ADC_ChannelConf.Sq = ADC_SEQUENCE_SQ7;
    ADC_ChannelConf.Smp = ADC_SMP_CLOCK_320;
    ADC_ChannelConf.SingleDiff = ADC_SINGLE_ENDED;
    ADC_ChannelConf.OffsetNumber = ADC_OFFSET_NONE;
    ADC_ChannelConf.Offset = 0;	
    HAL_ADC_ConfigChannel(&ADC_Handle,&ADC_ChannelConf);

    ADC_ChannelConf.Channel = ADC_CHANNEL_9;
    ADC_ChannelConf.Sq = ADC_SEQUENCE_SQ8;
    ADC_ChannelConf.Smp = ADC_SMP_CLOCK_320;
    ADC_ChannelConf.SingleDiff = ADC_SINGLE_ENDED;
    ADC_ChannelConf.OffsetNumber = ADC_OFFSET_NONE;
    ADC_ChannelConf.Offset = 0;	
    HAL_ADC_ConfigChannel(&ADC_Handle,&ADC_ChannelConf);

    ADC_ChannelConf.Channel = ADC_CHANNEL_10;
    ADC_ChannelConf.Sq = ADC_SEQUENCE_SQ9;
    ADC_ChannelConf.Smp = ADC_SMP_CLOCK_320;
    ADC_ChannelConf.SingleDiff = ADC_SINGLE_ENDED;
    ADC_ChannelConf.OffsetNumber = ADC_OFFSET_NONE;
    ADC_ChannelConf.Offset = 0;	
    HAL_ADC_ConfigChannel(&ADC_Handle,&ADC_ChannelConf);

    ADC_ChannelConf.Channel = ADC_CHANNEL_11;
    ADC_ChannelConf.Sq = ADC_SEQUENCE_SQ10;
    ADC_ChannelConf.Smp = ADC_SMP_CLOCK_320;
    ADC_ChannelConf.SingleDiff = ADC_SINGLE_ENDED;
    ADC_ChannelConf.OffsetNumber = ADC_OFFSET_NONE;
    ADC_ChannelConf.Offset = 0;	
    HAL_ADC_ConfigChannel(&ADC_Handle,&ADC_ChannelConf);

    ADC_ChannelConf.Channel = ADC_CHANNEL_12;
    ADC_ChannelConf.Sq = ADC_SEQUENCE_SQ11;
    ADC_ChannelConf.Smp = ADC_SMP_CLOCK_320;
    ADC_ChannelConf.SingleDiff = ADC_SINGLE_ENDED;
    ADC_ChannelConf.OffsetNumber = ADC_OFFSET_NONE;
    ADC_ChannelConf.Offset = 0;	
    HAL_ADC_ConfigChannel(&ADC_Handle,&ADC_ChannelConf);

    ADC_ChannelConf.Channel = ADC_CHANNEL_13;
    ADC_ChannelConf.Sq = ADC_SEQUENCE_SQ12;
    ADC_ChannelConf.Smp = ADC_SMP_CLOCK_320;
    ADC_ChannelConf.SingleDiff = ADC_SINGLE_ENDED;
    ADC_ChannelConf.OffsetNumber = ADC_OFFSET_NONE;
    ADC_ChannelConf.Offset = 0;	
    HAL_ADC_ConfigChannel(&ADC_Handle,&ADC_ChannelConf);

    ADC_ChannelConf.Channel = ADC_CHANNEL_14;
    ADC_ChannelConf.Sq = ADC_SEQUENCE_SQ13;
    ADC_ChannelConf.Smp = ADC_SMP_CLOCK_320;
    ADC_ChannelConf.SingleDiff = ADC_SINGLE_ENDED;
    ADC_ChannelConf.OffsetNumber = ADC_OFFSET_NONE;
    ADC_ChannelConf.Offset = 0;	
    HAL_ADC_ConfigChannel(&ADC_Handle,&ADC_ChannelConf);

    ADC_ChannelConf.Channel = ADC_CHANNEL_15;
    ADC_ChannelConf.Sq = ADC_SEQUENCE_SQ14;
    ADC_ChannelConf.Smp = ADC_SMP_CLOCK_320;
    ADC_ChannelConf.SingleDiff = ADC_SINGLE_ENDED;
    ADC_ChannelConf.OffsetNumber = ADC_OFFSET_NONE;
    ADC_ChannelConf.Offset = 0;	
    HAL_ADC_ConfigChannel(&ADC_Handle,&ADC_ChannelConf);
    
//    ADC_ChannelConf.Channel = ADC_CHANNEL_2;
//    ADC_ChannelConf.Sq = ADC_SEQUENCE_SQ15;
//    ADC_ChannelConf.Smp = ADC_SMP_CLOCK_320;
//    ADC_ChannelConf.SingleDiff = ADC_SINGLE_ENDED;
//    ADC_ChannelConf.OffsetNumber = ADC_OFFSET_NONE;
//    ADC_ChannelConf.Offset = 0;	
//    HAL_ADC_ConfigChannel(&ADC_Handle,&ADC_ChannelConf);

//    ADC_ChannelConf.Channel = ADC_CHANNEL_3;
//    ADC_ChannelConf.Sq = ADC_SEQUENCE_SQ16;
//    ADC_ChannelConf.Smp = ADC_SMP_CLOCK_320;
//    ADC_ChannelConf.SingleDiff = ADC_SINGLE_ENDED;
//    ADC_ChannelConf.OffsetNumber = ADC_OFFSET_NONE;
//    ADC_ChannelConf.Offset = 0;	
//    HAL_ADC_ConfigChannel(&ADC_Handle,&ADC_ChannelConf);
	
}


/******************************************************************************
* @brief : ADC Polling Mode test.
* @param : none
* @return: none
******************************************************************************/ 
void ADC_Test_Polling_Nchannels(void)
{
    uint32_t i, VrefP, Voltage;
    
    uint32_t lu32_COM_OK  = 0;

    printfS("The ADC test ADC_Test_Polling_Nchannels start.");
    
    VrefP = ADC_GetVrefP();
    printfS("The VrefP value is : %d \r\n", VrefP);
    
    ADC_Init_Polling_Nchannels();
    
    while(1)
    {
        for (i = 0; i < BUFFER_LENGTH; i++)
        {
            gadcBuffer[i] = 0;
        }

        HAL_ADC_Polling(&ADC_Handle, gadcBuffer, ADC_Handle.ChannelNum, 0);
       
        
        for (i = 0; i < ADC_Handle.ChannelNum; i++)
        {
            printfS("The adc convert result : Channel %d = %d\r\n", gadcBuffer[i]>>16 & 0xFF,gadcBuffer[i]&0xFFF);
            Voltage = (gadcBuffer[i]&0xFFF)*VrefP/4095;
            printfS("The Voltage is: %d mV \r\n", Voltage);
           
        } 
        HAL_DelayMs(1000);     
    }
}


/******************************************************************************
* @brief : Regular channel conversion end interrupt callback function.
* @param : none
* @return: none
******************************************************************************/ 
static void ADCx_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
	/* Get the converted value of regular channel */
    gadcxConvertedRegValue = HAL_ADC_GetValue(hadc);
	if(hadc->Instance ==ADC1)
	{
		gadc1EocFlag =1;
	}
	else if(hadc->Instance ==ADC2)
	{
		gadc2EocFlag =1;
	}
	
}

/******************************************************************************
* @brief : Regular channel group conversion end interrupt callback function.
* @param : none
* @return: none
******************************************************************************/ 
static void ADCx_GroupCpltCallback(ADC_HandleTypeDef *hadc)
{
	if(hadc->Instance ==ADC1)
	{
		gadc1EogFlag =1;
	}
	else if(hadc->Instance ==ADC2)
	{
		gadc2EogFlag =1;
	}
}


/******************************************************************************
* @brief : ADC Interrupt Mode Initialization.
* @param : none
* @return: none
******************************************************************************/ 
void ADC_Init_IT_Nchannels(void)
{
    //ADC Init
    ADC_ChannelConfTypeDef ADC_ChannelConf;
    ADC_Handle.Init.ClockPrescaler = ADC_CLOCK_DIV16;       //ADC_CLK分频选择
    ADC_Handle.Init.Resolution     = ADC_RESOLUTION_12B;    //分辨率
    ADC_Handle.Init.DataAlign      = ADC_DATAALIGN_RIGHT;   //数据对齐
    ADC_Handle.Init.ConConvMode    = DISABLE;               //连续转换模式

    ADC_Handle.Init.DiscontinuousConvMode = DISABLE;        //间断模式
    ADC_Handle.Init.NbrOfDiscConversion   =1;               //间断模式通道计数
    ADC_Handle.Init.ExternalTrigConv = ADC_SOFTWARE_START;  //触发模式：外部触发或软件触发
    ADC_Handle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;//外部触发边沿选择
    ADC_Handle.Init.DMAMode = ADC_DMAMODE_DISABLE;          //DMA选择
    ADC_Handle.Init.OverMode = ADC_OVERMODE_DISABLE;        //溢出时是否保留上次采样数据

    ADC_Handle.Init.OverSampMode = ADC_OVERSAMPMODE_DISABLE;//过采样使能
    ADC_Handle.Init.Oversampling.Ratio =ADC_OVERSAMPLING_RATIO_2;//过采样率
    ADC_Handle.Init.Oversampling.RightBitShift =ADC_RIGHTBITSHIFT_2;//过采样移位系数
    ADC_Handle.Init.Oversampling.TriggeredMode =0;          //过采样触发模式    
    ADC_Handle.Init.AnalogWDGEn = ADC_ANALOGWDGEN_DISABLE;  //模拟看门狗
    ADC_Handle.Init.ChannelEn = ADC_CHANNEL_15_EN;

    ADC_Handle.Instance = ADC2;  

    HAL_ADC_Init(&ADC_Handle);
	
	ADC_Handle.ConvCpltCallback = ADCx_ConvCpltCallback;
    ADC_Handle.GroupCpltCallback  = ADCx_GroupCpltCallback;
    HAL_ADC_Init(&ADC_Handle);
	
	/* The total adc regular channels number */
    ADC_Handle.ChannelNum = 1;
    
    /* Add adc channels */
    ADC_ChannelConf.Channel = ADC_CHANNEL_15;
    ADC_ChannelConf.Sq = ADC_SEQUENCE_SQ1;
    ADC_ChannelConf.Smp = ADC_SMP_CLOCK_320;
    ADC_ChannelConf.SingleDiff = ADC_SINGLE_ENDED;
	ADC_ChannelConf.OffsetNumber = ADC_OFFSET_NONE;//偏移通道选择
    ADC_ChannelConf.Offset = 0;//偏移量	
    HAL_ADC_ConfigChannel(&ADC_Handle,&ADC_ChannelConf);
}



/******************************************************************************
* @brief : ADC Interrupt Mode test.
* @param : none
* @return: none
******************************************************************************/ 
void ADC_Test_IT_Nchannels(void)
{
    uint32_t i, VrefP, Voltage;
    
    VrefP = ADC_GetVrefP();
    printfS("The VrefP value is : %d \r\n", VrefP);
	
    
    ADC_Init_IT_Nchannels();
	
    HAL_ADC_Start_IT(&ADC_Handle);
	
    while(1)
    {
        //ADC2     
        if((gadc2EocFlag) && (gadc2EogFlag))
        {
            gadc2EocFlag =0;
            gadc2EogFlag =0;      
            for (i = 0; i < ADC_Handle.ChannelNum; i++)
            {
                printfS("The adc convert result : Channel %d = %d\r\n", gadcxConvertedRegValue>>16 & 0xFF, gadcxConvertedRegValue & 0xFFF);
                Voltage = (gadcxConvertedRegValue&0xFFF)*VrefP/4095;
                printfS("The Voltage is: %d mV \r\n", Voltage);            
            }
        }
        //ADC1 
        /*if((gadc1EocFlag) && (gadc1EogFlag))
        {
            gadc1EocFlag =0;
            gadc1EogFlag =0;      
            for (i = 0; i < ADC_Handle.ChannelNum; i++)
            {
                printfS("The adc convert result : Channel %d = %d\r\n", gadcxConvertedRegValue>>16 & 0xFF, gadcxConvertedRegValue & 0xFFF);
                Voltage = (gadcxConvertedRegValue&0xFFF)*VrefP/4095;
                printfS("The Voltage is: %d mV \r\n", Voltage);            
            }
        }*/
        else 
        {
            printfS("Wait for ADC Irq \r\n");
            HAL_ADC_Start_IT(&ADC_Handle);
        }
        HAL_DelayMs(1000);
    }
}



/******************************************************************************
* @brief : ADC External trigger Mode Initialization.
* @param : none
* @return: none
******************************************************************************/ 
void ADC_Init_ExtTrig_Nchannels(void)
{
    //ADC Init
    ADC_ChannelConfTypeDef ADC_ChannelConf;

    ADC_Handle.Init.ClockPrescaler = ADC_CLOCK_DIV16;       //ADC_CLK分频选择
    ADC_Handle.Init.Resolution     = ADC_RESOLUTION_12B;    //分辨率
    ADC_Handle.Init.DataAlign      = ADC_DATAALIGN_RIGHT;   //数据对齐
    ADC_Handle.Init.ConConvMode    = DISABLE;               //连续转换模式

    ADC_Handle.Init.DiscontinuousConvMode = DISABLE;        //间断模式
    ADC_Handle.Init.NbrOfDiscConversion   = 1;               //间断模式通道计数
    ADC_Handle.Init.ExternalTrigConv = ADC_EXTERNAL_TIG6;  //触发模式：外部触发或软件触发
    ADC_Handle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_FALLING;//外部触发边沿选择
    ADC_Handle.Init.DMAMode = ADC_DMAMODE_DISABLE;          //DMA选择
    ADC_Handle.Init.OverMode = ADC_OVERMODE_DISABLE;        //溢出时是否保留上次采样数据

    ADC_Handle.Init.OverSampMode = ADC_OVERSAMPMODE_DISABLE;//过采样使能
    ADC_Handle.Init.Oversampling.Ratio =ADC_OVERSAMPLING_RATIO_2;//过采样率
    ADC_Handle.Init.Oversampling.RightBitShift =ADC_RIGHTBITSHIFT_2;//过采样移位系数
    ADC_Handle.Init.Oversampling.TriggeredMode =0;          //过采样触发模式    
    ADC_Handle.Init.AnalogWDGEn = ADC_ANALOGWDGEN_DISABLE;  //模拟看门狗
    ADC_Handle.Init.ChannelEn = ADC_CHANNEL_15_EN;

    ADC_Handle.Instance = ADC1;  

    HAL_ADC_Init(&ADC_Handle);
	
	/* The total adc regular channels number */
    ADC_Handle.ChannelNum = 1;
    
    /* Add adc channels */
    ADC_ChannelConf.Channel = ADC_CHANNEL_15;
    ADC_ChannelConf.Sq = ADC_SEQUENCE_SQ1;
    ADC_ChannelConf.Smp = ADC_SMP_CLOCK_320;
    ADC_ChannelConf.SingleDiff = ADC_SINGLE_ENDED;
	ADC_ChannelConf.OffsetNumber = ADC_OFFSET_NONE;//偏移通道选择
    ADC_ChannelConf.Offset = 0;//偏移量	
    HAL_ADC_ConfigChannel(&ADC_Handle,&ADC_ChannelConf);

}

/******************************************************************************
* @brief : ADC External trigger Mode test.
* @param : none
* @return: none
******************************************************************************/ 
void ADC_Test_ExtTrig_Nchannels(void)
{
    uint32_t i, VrefP, Voltage;
    GPIO_InitTypeDef GPIO_PINx_Handle;
    
    
    VrefP = ADC_GetVrefP();
    printfS("The VrefP value is : %d \r\n", VrefP);
	
    /*---------------------------EXTI_Line11-----------------------------*/ 
    __HAL_RCC_EXTI_CLK_ENABLE();
    __HAL_RCC_GPIOB_CLK_ENABLE(); 
	/* Initialization GPIO */
    GPIO_PINx_Handle.Pin       = GPIO_PIN_11;
    GPIO_PINx_Handle.Mode      = GPIO_MODE_INPUT;
    GPIO_PINx_Handle.Pull      = GPIO_NOPULL;
	GPIO_PINx_Handle.Drive     = GPIO_DRIVE_LEVEL3;
    HAL_GPIO_Init(GPIOB, &GPIO_PINx_Handle);
    
    /* Config EXTI */
    HAL_EXTI_SetConfigLine((GPIO_TypeDef *)GPIOB, EXTI_LINE_11, EXTI_MODE_IT_FALLING);
    NVIC_ClearPendingIRQ(EXTI15_10_IRQn);
    NVIC_SetPriority(EXTI15_10_IRQn, 5);
    NVIC_EnableIRQ(EXTI15_10_IRQn);
    
    
    ADC_Init_ExtTrig_Nchannels();
	
    HAL_ADC_Start(&ADC_Handle);
	
    while(1)
    {
        if(gadcExtTrigFlag)
        {
            //clear
            gadcExtTrigFlag = 0; 
            printfS("The adc convert result : Channel %d = %d\r\n", gadcxConvertedRegValue>>16 & 0xFF, gadcxConvertedRegValue & 0xFFF);
            Voltage = (gadcxConvertedRegValue&0xFFF)*VrefP/4095;
            printfS("The Voltage is: %d mV \r\n", Voltage); 
        }
        else
        {
            printfS("Wait for EXTI11 Irq \r\n");
        }
        HAL_DelayMs(1000);
    }
}


 /******************************************************************************
* @brief : DMA adc to memory transfer complete interrupt Callback.
* @param : hdma: pointer to a DMA_HandleTypeDef structure that contains
*                 the configuration information for DMA module.
* @return: none
******************************************************************************/ 
void DMA_ADC1_ITC_Callback(DMA_HandleTypeDef *hdma)
{    
    gadc1ItcConunt = 1;
}



/******************************************************************************
* @brief : ADC DMA Mode Initialization.
* @param : none
* @return: none
******************************************************************************/ 
void ADC_Init_DMA_Nchannels(void)
{
    ADC_ChannelConfTypeDef ADC_ChannelConf;

    ADC_Handle.Init.ClockPrescaler = ADC_CLOCK_DIV16;       //ADC_CLK分频选择
    ADC_Handle.Init.Resolution     = ADC_RESOLUTION_12B;    //分辨率
    ADC_Handle.Init.DataAlign      = ADC_DATAALIGN_RIGHT;   //数据对齐
    ADC_Handle.Init.ConConvMode    = DISABLE;               //连续转换模式
    ADC_Handle.Init.DiscontinuousConvMode = DISABLE;        //间断模式
    
    ADC_Handle.Init.NbrOfDiscConversion   =1;               //间断模式通道计数
    
    ADC_Handle.Init.ExternalTrigConv = ADC_SOFTWARE_START;  //触发模式：外部触发或软件触发
    ADC_Handle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;//外部触发边沿选择
    
    ADC_Handle.Init.DMAMode = ADC_DMAMODE_DISABLE;          //DMA选择
    ADC_Handle.Init.OverMode = ADC_OVERMODE_DISABLE;        //溢出时是否保留上次采样数据

    ADC_Handle.Init.OverSampMode = ADC_OVERSAMPMODE_DISABLE;//过采样使能
    ADC_Handle.Init.Oversampling.Ratio =ADC_OVERSAMPLING_RATIO_2;//过采样率
    ADC_Handle.Init.Oversampling.RightBitShift =ADC_RIGHTBITSHIFT_2;//过采样移位系数
    ADC_Handle.Init.Oversampling.TriggeredMode = 0;          //过采样触发模式    
    ADC_Handle.Init.AnalogWDGEn = ADC_ANALOGWDGEN_DISABLE;  //模拟看门狗
    ADC_Handle.Init.ChannelEn = ADC_CHANNEL_0_EN | ADC_CHANNEL_1_EN | ADC_CHANNEL_14_EN | ADC_CHANNEL_15_EN | \
                        ADC_CHANNEL_4_EN | ADC_CHANNEL_5_EN | ADC_CHANNEL_6_EN | ADC_CHANNEL_7_EN | \
                        ADC_CHANNEL_8_EN | ADC_CHANNEL_9_EN | ADC_CHANNEL_10_EN | ADC_CHANNEL_11_EN | \
                        ADC_CHANNEL_12_EN | ADC_CHANNEL_13_EN;// | ADC_CHANNEL_2_EN | ADC_CHANNEL_3_EN;

    ADC_Handle.Instance = ADC1;  //ADC2

    HAL_ADC_Init(&ADC_Handle);


    /* The total adc regular channels number */
    ADC_Handle.ChannelNum = 1;

    /* Add adc channels */
    ADC_ChannelConf.Channel = ADC_CHANNEL_0;
    ADC_ChannelConf.Sq = ADC_SEQUENCE_SQ1;  //转换顺序
    ADC_ChannelConf.Smp = ADC_SMP_CLOCK_320;//采样时间
    ADC_ChannelConf.SingleDiff =  ADC_SINGLE_ENDED;  // ADC_DIFFERENTIAL_ENDED ;    //单端/差分模式
    //offset config
    ADC_ChannelConf.OffsetNumber = ADC_OFFSET_NONE;   //modeString[0].number;  //ADC_OFFSET_NONE;  //偏移通道选择
    ADC_ChannelConf.Offset =  0; //偏移量
    ADC_ChannelConf.OffsetSign = 0; //偏移计算方式
    ADC_ChannelConf.OffsetSaturation = 0;//偏移结果格式选择
    HAL_ADC_ConfigChannel(&ADC_Handle,&ADC_ChannelConf);



    /*## DMA配置 ##*/
    //ADC1
    __HAL_RCC_DMA1_CLK_ENABLE();
    ADC1_DMAHandle.Instance = DMA1_Channel3; 
    ADC1_DMAHandle.Init.Mode = DMA_MODE_CIRCULAR;    
    ADC1_DMAHandle.Init.ReqID = DMA1_REQ0_ADC1;         
    ADC1_DMAHandle.Init.DataFlow = DMA_DATAFLOW_P2M;
    ADC1_DMAHandle.Init.SrcInc = DMA_SRCINC_DISABLE;
    ADC1_DMAHandle.Init.DestInc = DMA_DESTINC_ENABLE;
    ADC1_DMAHandle.Init.SrcWidth = DMA_SRCWIDTH_WORD;   
    ADC1_DMAHandle.Init.DestWidth = DMA_DESTWIDTH_WORD;
    ADC1_DMAHandle.Init.SrcBurst = DMA_SRCBURST_1;
    ADC1_DMAHandle.Init.DestBurst = DMA_DESTBURST_1;    
    ADC1_DMAHandle.XferCpltCallback  = DMA_ADC1_ITC_Callback;

    HAL_DMA_Init(&ADC1_DMAHandle);
    ADC_Handle.DMA_Handle = &ADC1_DMAHandle;
    
    NVIC_ClearPendingIRQ(DMA1_IRQn);
    NVIC_EnableIRQ(DMA1_IRQn);

}

/******************************************************************************
* @brief : ADC DMA Mode Test.
* @param : none
* @return: none
******************************************************************************/ 
void ADC_Test_DMA_Nchannels(void)
{
    uint32_t i, VrefP, Voltage;

    VrefP = ADC_GetVrefP();
    printfS("The VrefP value is : %d \r\n", VrefP);
    ADC_Init_DMA_Nchannels();

 
    HAL_ADC_Start_DMA(&ADC_Handle,gadcBuffer,ADC_Handle.ChannelNum);
    while(1)
    {
        
        HAL_ADC_Start(&ADC_Handle);
        while(!gadc1ItcConunt);
        gadc1ItcConunt =0;
        for (i = 0; i < ADC_Handle.ChannelNum; i++)
        {
            printfS("The adc convert result : Channel %d = %d\r\n", gadcBuffer[i] >>16 & 0xFF, gadcBuffer[i] & 0xFFF);
            Voltage = (gadcBuffer[i]&0xFFF)*VrefP/4095;
            printfS("The Voltage is: %d mV \r\n", Voltage);           
        }
        HAL_Delay(500);
    }
}





/******************************************************************************
* @brief : ADC Regular channel test.
* @param : Test_Case：Test mode selection
* @return: none
******************************************************************************/ 
void ADC_Regular_Channel_Test(ADC_Regular_Test_mode Test_Case)
{

    switch(Test_Case)
    {
        case ADC_Regular_POLLING:
            ADC_Test_Polling_Nchannels();
        break;
        case ADC_Regular_IT:
            ADC_Test_IT_Nchannels();
        break;
        case ADC_Regular_EXT:
            ADC_Test_ExtTrig_Nchannels();
        break;        
        case ADC_Regular_DMA:
            ADC_Test_DMA_Nchannels();
        break;
        default:break;

    }
}



