
/******************************************************************************
*@file  : app.c
*@brief : application
*@ver   : 1.0.0
*@date  : 2022.10.20
******************************************************************************/
#include  "app.h"

uint32_t gu32_ADCxConvertedInjValue;    //ADC Value
  
static ADC_HandleTypeDef ADC_InjectHandle;

static volatile uint32_t gadc1InjectConFlag = 0;    //ADC1 Inject channel conversion end interrupt flag
static volatile uint32_t gadc2InjectConFlag = 0;    //ADC2 Inject channel conversion end interrupt flag
static volatile uint32_t gadc1InjectGroupFlag = 0;  //ADC1 Inject channel group conversion end interrupt flag
static volatile uint32_t gadc2InjectGroupFlag = 0;  //ADC2 Inject channel group conversion end interrupt flag
static volatile uint32_t gadcExtTrigFlag = 0;       //ADC Regular channel External trigger flag



void HAL_ADC_IRQCallback(void)
{
    __IO uint32_t Status;


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

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

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

            }

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

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

        }

    }

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

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

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

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

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

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

            /* Clear the ADC analog watchdog flag */
            __HAL_ADC_CLEAR_FLAG(&ADC_InjectHandle, 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_InjectHandle.Instance->SR & ADC_SR_JEOG)
        {
            __HAL_ADC_CLEAR_FLAG(&ADC_InjectHandle,ADC_SR_JEOG);			
            gu32_ADCxConvertedInjValue = HAL_ADCEx_InjectedGetValue(&ADC_InjectHandle,ADC_INJECTED_RANK_1);
            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_Injectchannels(void)
{
    ADC_InjectionConfTypeDef sConfigInjected;
    ADC_AnalogWDGConfTypeDef ADC_AnalogWDGConf;

    //ADC Init
    ADC_InjectHandle.Init.ClockPrescaler = ADC_CLOCK_DIV16;     //ADC_CLK分频选择 
    ADC_InjectHandle.Init.Resolution     = ADC_RESOLUTION_12B;  //分辨率 
    ADC_InjectHandle.Init.DataAlign      = ADC_DATAALIGN_RIGHT; //数据对齐
    ADC_InjectHandle.Init.ConConvMode    = DISABLE;             //连续转换模式
    ADC_InjectHandle.Init.DiscontinuousConvMode = DISABLE;      //间断模式
    ADC_InjectHandle.Init.ExternalTrigConv = ADC_SOFTWARE_START;//触发模式：外部触发或软件触发
    ADC_InjectHandle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;//外部触发边沿选择
    ADC_InjectHandle.Init.DMAMode = ADC_DMAMODE_DISABLE;        //DMA选择
    //过采样
    ADC_InjectHandle.Init.OverMode = ADC_OVERMODE_DISABLE;      //溢出时是否保留上次采样数据
    ADC_InjectHandle.Init.OverSampMode = ADC_OVERSAMPMODE_DISABLE;//过采样使能
    //AnalogWDG
    ADC_InjectHandle.Init.AnalogWDGEn = ADC_ANALOGWDGEN_DISABLE;    //模拟看门狗使能位
    ADC_InjectHandle.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_InjectHandle.Instance = ADC2;

    HAL_ADC_Init(&ADC_InjectHandle);

    /* The total adc Inject channels number */
    ADC_InjectHandle.ChannelNum = 1;

    //Inject Channel Config
    sConfigInjected.InjectedNbrOfConversion    = 4; //注入序列长度
    sConfigInjected.InjectedChannel            = ADC_CHANNEL_10;
    sConfigInjected.InjectedRank               = ADC_INJECTED_RANK_1;   //注入序列转换顺序
    sConfigInjected.InjectedSamplingTime       = ADC_SMP_CLOCK_3;   //通道采样时间
    sConfigInjected.InjectedSingleDiff         = ADC_SINGLE_ENDED;   //ADC_DIFFERENTIAL_ENDED; //注入通道单端/差分模式  
    sConfigInjected.ExternalTrigInjecConv      = ADC_SOFTWARE_START;//注入通道触发模式
    sConfigInjected.ExternalTrigInjecConvEdge  = ADC_EXTERNALTRIGINJECCONVEDGE_NONE;//注入通道外部触发边沿选择
    sConfigInjected.AutoInjectedConv           = DISABLE;//注入组自动转换
    sConfigInjected.InjectedDiscontinuousConvMode = DISABLE;//注入通道上的间断模式使能控制
    //offset
    sConfigInjected.InjectedOffsetNumber       = ADC_OFFSET_NONE;  //modeString[0].number; //偏移通道选择 
    sConfigInjected.InjectedOffset             = 0; //注入通道偏移量
    sConfigInjected.InjectedOffsetSign         = 0; //注入通道偏移计算方式
    sConfigInjected.InjectedOffsetSaturation   = 0; //注入通道偏移结果格式选择
    //oversampling mode
    sConfigInjected.InjecOversamplingMode      = DISABLE;    //注入通道过采样使能
    sConfigInjected.InjecOversampling.Ratio    =ADC_OVERSAMPLING_RATIO_2;//注入通道过采样率
    sConfigInjected.InjecOversampling.RightBitShift =ADC_RIGHTBITSHIFT_2;//注入通道过采样移位系数

    if(HAL_ADCEx_InjectedConfigChannel(&ADC_InjectHandle, &sConfigInjected) != HAL_OK)
    {
        /* Channel Configuration Error */
        printfS("Inject Channel_10 Configuration Error \r\n");
    }
   
    //Inject Channel Config
    sConfigInjected.InjectedChannel            = ADC_CHANNEL_11;
    sConfigInjected.InjectedRank               = ADC_INJECTED_RANK_2;
    sConfigInjected.InjectedSamplingTime       = ADC_SMP_CLOCK_320;
    sConfigInjected.InjectedSingleDiff         = ADC_SINGLE_ENDED;   //ADC_DIFFERENTIAL_ENDED;   

    if(HAL_ADCEx_InjectedConfigChannel(&ADC_InjectHandle, &sConfigInjected) != HAL_OK)
    {
        /* Channel Configuration Error */
        printfS("Inject Channel_11 Configuration Error \r\n");
    }

    //Inject Channel Config
    sConfigInjected.InjectedChannel            = ADC_CHANNEL_12;
    sConfigInjected.InjectedRank               = ADC_INJECTED_RANK_3;
    sConfigInjected.InjectedSamplingTime       = ADC_SMP_CLOCK_320;
    sConfigInjected.InjectedSingleDiff         = ADC_SINGLE_ENDED;   //ADC_DIFFERENTIAL_ENDED;   

    if(HAL_ADCEx_InjectedConfigChannel(&ADC_InjectHandle, &sConfigInjected) != HAL_OK)
    {
        /* Channel Configuration Error */
        printfS("Inject Channel_12 Configuration Error \r\n");
    }

    //Inject Channel Config
    sConfigInjected.InjectedChannel            = ADC_CHANNEL_13;
    sConfigInjected.InjectedRank               = ADC_INJECTED_RANK_4;
    sConfigInjected.InjectedSamplingTime       = ADC_SMP_CLOCK_320;
    sConfigInjected.InjectedSingleDiff         = ADC_SINGLE_ENDED;   //ADC_DIFFERENTIAL_ENDED;   

    if(HAL_ADCEx_InjectedConfigChannel(&ADC_InjectHandle, &sConfigInjected) != HAL_OK)
    {
        /* Channel Configuration Error */
        printfS("Inject Channel_13 Configuration Error \r\n");
    }
}


/******************************************************************************
* brief : ADC Polling Mode Inject channels test.
* param : none
* return: none
******************************************************************************/ 
void ADC_Test_Polling_Injectchannels(void)
{
    uint32_t i, VrefP, Voltage;

    printfS("The ADC test ADC_Test_Polling_Nchannels start.");
    
    VrefP = ADC_GetVrefP();
    printfS("The VrefP value is : %d \r\n", VrefP);
    
    ADC_Init_Polling_Injectchannels();
    
    while(1)
    {

        HAL_ADCEx_InjectedStart(&ADC_InjectHandle);

        while(!READ_BIT(ADC_InjectHandle.Instance->SR,ADC_SR_JEOG)){};
        __HAL_ADC_CLEAR_FLAG(&ADC_InjectHandle,ADC_SR_JEOG);	
		
        gu32_ADCxConvertedInjValue = HAL_ADCEx_InjectedGetValue(&ADC_InjectHandle,ADC_INJECTED_RANK_1);
        printfS("The Inject Rank1 convert result : Channel %d = 0x%08x. ", +
        gu32_ADCxConvertedInjValue>>16 & 0xFF,gu32_ADCxConvertedInjValue);
        Voltage = (gu32_ADCxConvertedInjValue & 0xFFF) * VrefP / 4095;
        printfS("The Voltage is: %d mV \r\n", Voltage); 
        
        gu32_ADCxConvertedInjValue = HAL_ADCEx_InjectedGetValue(&ADC_InjectHandle,ADC_INJECTED_RANK_2);
        printfS("The Inject Rank1 convert result : Channel %d = 0x%08x. ", gu32_ADCxConvertedInjValue>>16 & 0xFF,gu32_ADCxConvertedInjValue);
        Voltage = (gu32_ADCxConvertedInjValue & 0xFFF) * VrefP / 4095;
        printfS("The Voltage is: %d mV \r\n", Voltage);
        
        gu32_ADCxConvertedInjValue = HAL_ADCEx_InjectedGetValue(&ADC_InjectHandle,ADC_INJECTED_RANK_3);
        printfS("The Inject Rank1 convert result : Channel %d = 0x%08x. ", gu32_ADCxConvertedInjValue>>16 & 0xFF,gu32_ADCxConvertedInjValue);
        Voltage = (gu32_ADCxConvertedInjValue & 0xFFF) * VrefP / 4095;
        printfS("The Voltage is: %d mV \r\n", Voltage);
        
        gu32_ADCxConvertedInjValue = HAL_ADCEx_InjectedGetValue(&ADC_InjectHandle,ADC_INJECTED_RANK_4);
        printfS("The Inject Rank1 convert result : Channel %d = 0x%08x. ", gu32_ADCxConvertedInjValue>>16 & 0xFF,gu32_ADCxConvertedInjValue);
        Voltage = (gu32_ADCxConvertedInjValue & 0xFFF) * VrefP / 4095;
        printfS("The Voltage is: %d mV \r\n", Voltage);

        HAL_DelayMs(1000);     
    }
}


/*===========================================Inject Channel IT Test========================================*/
/******************************************************************************
* brief : INject channel conversion end interrupt callback function.
* param : none
* return: none
******************************************************************************/ 
void ADCx_InjectConvCpltCallback(ADC_HandleTypeDef *hadc)
{
    /* Get the converted value of regular channel */
    gu32_ADCxConvertedInjValue = HAL_ADCEx_InjectedGetValue(&ADC_InjectHandle,ADC_INJECTED_RANK_1);
    if(hadc->Instance ==ADC1)
    {
        gadc1InjectConFlag =1;
    }
    else if(hadc->Instance ==ADC2)
    {
        gadc2InjectConFlag =1;
    }

}
/******************************************************************************
* brief : Inject channel group conversion end interrupt callback function.
* param : none
* return: none
******************************************************************************/ 
void ADCx_InjectGroupCpltCallback(ADC_HandleTypeDef *hadc)
{
    if(hadc->Instance ==ADC1)
    {
        gadc1InjectGroupFlag =1;
    }
    else if(hadc->Instance ==ADC2)
    {
        gadc2InjectGroupFlag =1;
    }
}
/******************************************************************************
* brief : ADC Inject Mode Interrupt Mode Initialization.
* param : none
* return: none
******************************************************************************/ 
void ADC_Init_IT_Injectchannels(void)
{
    ADC_InjectionConfTypeDef sConfigInjected;
    ADC_AnalogWDGConfTypeDef ADC_AnalogWDGConf;

    //ADC Init
    ADC_InjectHandle.Init.ClockPrescaler = ADC_CLOCK_DIV16;     //ADC_CLK分频选择 
    ADC_InjectHandle.Init.Resolution     = ADC_RESOLUTION_12B;  //分辨率 
    ADC_InjectHandle.Init.DataAlign      = ADC_DATAALIGN_RIGHT; //数据对齐
    ADC_InjectHandle.Init.ConConvMode    = DISABLE;             //连续转换模式
    ADC_InjectHandle.Init.DiscontinuousConvMode = DISABLE;      //间断模式
    ADC_InjectHandle.Init.ExternalTrigConv = ADC_SOFTWARE_START;//触发模式：外部触发或软件触发
    ADC_InjectHandle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;//外部触发边沿选择
    ADC_InjectHandle.Init.DMAMode = ADC_DMAMODE_DISABLE;        //DMA选择
    //过采样
    ADC_InjectHandle.Init.OverMode = ADC_OVERMODE_DISABLE;      //溢出时是否保留上次采样数据
    ADC_InjectHandle.Init.OverSampMode = ADC_OVERSAMPMODE_DISABLE;//过采样使能
    //AnalogWDG
    ADC_InjectHandle.Init.AnalogWDGEn = ADC_ANALOGWDGEN_DISABLE;    //模拟看门狗使能位
    ADC_InjectHandle.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_InjectHandle.Instance = ADC1;
    
    ADC_InjectHandle.InjectedConvCpltCallback =ADCx_InjectConvCpltCallback;
    ADC_InjectHandle.InjectedGroupConvCpltCallback =ADCx_InjectGroupCpltCallback;

    HAL_ADC_Init(&ADC_InjectHandle);

    /* The total adc Inject channels number */
    ADC_InjectHandle.ChannelNum = 1;

    //Inject Channel Config
    sConfigInjected.InjectedNbrOfConversion    = 1; //注入序列长度
    sConfigInjected.InjectedChannel            = ADC_CHANNEL_10;
    sConfigInjected.InjectedRank               = ADC_INJECTED_RANK_1;   //注入序列转换顺序
    sConfigInjected.InjectedSamplingTime       = ADC_SMP_CLOCK_3;   //通道采样时间
    sConfigInjected.InjectedSingleDiff         = ADC_SINGLE_ENDED;   //ADC_DIFFERENTIAL_ENDED; //注入通道单端/差分模式  
    sConfigInjected.ExternalTrigInjecConv      = ADC_SOFTWARE_START;//注入通道触发模式
    sConfigInjected.ExternalTrigInjecConvEdge  = ADC_EXTERNALTRIGINJECCONVEDGE_NONE;//注入通道外部触发边沿选择
    sConfigInjected.AutoInjectedConv           = DISABLE;//注入组自动转换
    sConfigInjected.InjectedDiscontinuousConvMode = DISABLE;//注入通道上的间断模式使能控制
    //offset
    sConfigInjected.InjectedOffsetNumber       = ADC_OFFSET_NONE;  //modeString[0].number; //偏移通道选择 
    sConfigInjected.InjectedOffset             = 0; //注入通道偏移量
    sConfigInjected.InjectedOffsetSign         = 0; //注入通道偏移计算方式
    sConfigInjected.InjectedOffsetSaturation   = 0; //注入通道偏移结果格式选择
    //oversampling mode
    sConfigInjected.InjecOversamplingMode      = DISABLE;    //注入通道过采样使能
    sConfigInjected.InjecOversampling.Ratio    =ADC_OVERSAMPLING_RATIO_2;//注入通道过采样率
    sConfigInjected.InjecOversampling.RightBitShift =ADC_RIGHTBITSHIFT_2;//注入通道过采样移位系数

    if(HAL_ADCEx_InjectedConfigChannel(&ADC_InjectHandle, &sConfigInjected) != HAL_OK)
    {
        /* Channel Configuration Error */
        printfS("Inject Channel_10 Configuration Error \r\n");
    }

}

/******************************************************************************
* brief : ADC Inject mode Interrupt Mode test.
* param : none
* return: none
******************************************************************************/ 
void ADC_Test_IT_Injectchannels(void)
{
    uint32_t i, VrefP, Voltage;

    printfS("The ADC test ADC_Test_Polling_Nchannels start.");
    
    VrefP = ADC_GetVrefP();
    printfS("The VrefP value is : %d \r\n", VrefP);
    
    ADC_Init_IT_Injectchannels();
   
    HAL_ADC_InjectedStart_IT(&ADC_InjectHandle);
   
    while(1)
    {
//        //ADC2     
//        if((gadc2InjectConFlag) && (gadc2InjectGroupFlag))
//        {
//            gadc2InjectConFlag = 0;
//            gadc2InjectGroupFlag = 0;      
//            printfS("The adc convert result : Channel %d = %d\r\n", gu32_ADCxConvertedInjValue>>16 & 0xFF, gu32_ADCxConvertedInjValue & 0xFFF);
//            Voltage = (gu32_ADCxConvertedInjValue & 0xFFF) * VrefP / 4095;
//            printfS("The Voltage is: %d mV \r\n", Voltage);            

//        }
        //ADC1 
        if((gadc1InjectConFlag) && (gadc1InjectGroupFlag))
        {
            gadc1InjectConFlag = 0;
            gadc1InjectGroupFlag = 0;      
            printfS("The adc convert result : Channel %d = %d\r\n", gu32_ADCxConvertedInjValue>>16 & 0xFF, gu32_ADCxConvertedInjValue & 0xFFF);
            Voltage = (gu32_ADCxConvertedInjValue & 0xFFF) * VrefP / 4095;
            printfS("The Voltage is: %d mV \r\n", Voltage);            

        }
        else 
        {
            printfS("Wait for ADC Irq \r\n");
            HAL_ADC_InjectedStart_IT(&ADC_InjectHandle);
        }
        HAL_DelayMs(1000);
    }

}

/*===========================================Inject Channel EXT Test========================================*/\

/******************************************************************************
* brief : ADC Inject Mode External trigger Initialization.
* param : none
* return: none
******************************************************************************/ 
void ADC_Init_EXTTrig_Injectchannels(void)
{
    ADC_InjectionConfTypeDef sConfigInjected;
    ADC_AnalogWDGConfTypeDef ADC_AnalogWDGConf;

    //ADC Init
    ADC_InjectHandle.Init.ClockPrescaler = ADC_CLOCK_DIV16;     //ADC_CLK分频选择 
    ADC_InjectHandle.Init.Resolution     = ADC_RESOLUTION_12B;  //分辨率 
    ADC_InjectHandle.Init.DataAlign      = ADC_DATAALIGN_RIGHT; //数据对齐
    ADC_InjectHandle.Init.ConConvMode    = DISABLE;             //连续转换模式
    ADC_InjectHandle.Init.DiscontinuousConvMode = DISABLE;      //间断模式
    ADC_InjectHandle.Init.ExternalTrigConv = ADC_SOFTWARE_START;//触发模式：外部触发或软件触发
    ADC_InjectHandle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;//外部触发边沿选择
    ADC_InjectHandle.Init.DMAMode = ADC_DMAMODE_DISABLE;        //DMA选择
    //过采样
    ADC_InjectHandle.Init.OverMode = ADC_OVERMODE_DISABLE;      //溢出时是否保留上次采样数据
    ADC_InjectHandle.Init.OverSampMode = ADC_OVERSAMPMODE_DISABLE;//过采样使能
    //AnalogWDG
    ADC_InjectHandle.Init.AnalogWDGEn = ADC_ANALOGWDGEN_DISABLE;    //模拟看门狗使能位
    ADC_InjectHandle.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_InjectHandle.Instance = ADC2;

    HAL_ADC_Init(&ADC_InjectHandle);

    /* The total adc Inject channels number */
    ADC_InjectHandle.ChannelNum = 1;

    //Inject Channel Config
    sConfigInjected.InjectedNbrOfConversion    = 1; //注入序列长度
    sConfigInjected.InjectedChannel            = ADC_CHANNEL_10;
    sConfigInjected.InjectedRank               = ADC_INJECTED_RANK_1;   //注入序列转换顺序
    sConfigInjected.InjectedSamplingTime       = ADC_SMP_CLOCK_320;   //通道采样时间
    sConfigInjected.InjectedSingleDiff         = ADC_SINGLE_ENDED;   //ADC_DIFFERENTIAL_ENDED; //注入通道单端/差分模式  
    sConfigInjected.ExternalTrigInjecConv      = ADC_EXTERNAL_TIG6;//注入通道触发模式
    sConfigInjected.ExternalTrigInjecConvEdge  = ADC_EXTERNALTRIGCONVEDGE_RISING;//注入通道外部触发边沿选择
    sConfigInjected.AutoInjectedConv           = DISABLE;//注入组自动转换
    sConfigInjected.InjectedDiscontinuousConvMode = DISABLE;//注入通道上的间断模式使能控制
    //offset
    sConfigInjected.InjectedOffsetNumber       = ADC_OFFSET_NONE;  //modeString[0].number; //偏移通道选择 
    sConfigInjected.InjectedOffset             = 0; //注入通道偏移量
    sConfigInjected.InjectedOffsetSign         = 0; //注入通道偏移计算方式
    sConfigInjected.InjectedOffsetSaturation   = 0; //注入通道偏移结果格式选择
    //oversampling mode
    sConfigInjected.InjecOversamplingMode      = DISABLE;    //注入通道过采样使能
    sConfigInjected.InjecOversampling.Ratio    =ADC_OVERSAMPLING_RATIO_2;//注入通道过采样率
    sConfigInjected.InjecOversampling.RightBitShift =ADC_RIGHTBITSHIFT_2;//注入通道过采样移位系数

    if(HAL_ADCEx_InjectedConfigChannel(&ADC_InjectHandle, &sConfigInjected) != HAL_OK)
    {
        /* Channel Configuration Error */
        printfS("Inject Channel_10 Configuration Error \r\n");
    }
   
}

/******************************************************************************
* brief : ADC Inject Mode External trigger test.
* param : none
* return: none
******************************************************************************/ 
void ADC_Test_EXTTrig_Injectchannels(void)
{
    uint32_t i, VrefP, Voltage;
    GPIO_InitTypeDef GPIO_PINx_Handle;

    printfS("The ADC test ADC_Test_Polling_Nchannels start.");
    
    VrefP = ADC_GetVrefP();
    printfS("The VrefP value is : %d \r\n", VrefP);
    
    /*---------------------------EXTI_Line15-----------------------------*/ 
    __HAL_RCC_EXTI_CLK_ENABLE();
    __HAL_RCC_GPIOB_CLK_ENABLE();   
	/* Initialization GPIO */
    GPIO_PINx_Handle.Pin       = GPIO_PIN_15;
    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_15, EXTI_MODE_IT_RISING);
    NVIC_ClearPendingIRQ(EXTI15_10_IRQn);
    NVIC_SetPriority(EXTI15_10_IRQn, 5);
    NVIC_EnableIRQ(EXTI15_10_IRQn);
    
    ADC_Init_EXTTrig_Injectchannels();
   
    //Start ADC 
    HAL_ADCEx_InjectedStart(&ADC_InjectHandle);
    while(1)
    {  	    
        if(gadcExtTrigFlag)
        {
            //clear
            gadcExtTrigFlag = 0; 
            printfS("The adc convert result : Channel %d = %d\r\n", gu32_ADCxConvertedInjValue>>16 & 0xFF, gu32_ADCxConvertedInjValue & 0xFFF);
            Voltage = (gu32_ADCxConvertedInjValue&0xFFF)*VrefP/4095;
            printfS("The Voltage is: %d mV \r\n", Voltage); 
        }
        else
        {
            printfS("Wait for EXTI11 Irq \r\n");
        }
        HAL_DelayMs(1000);
    }
}

/******************************************************************************
* brief : ADC Inject Mode test.
* param : Test_Case：Test mode selection
* return: none
******************************************************************************/ 
void ADC_Inject_Channel_Test(ADC_Inject_Test_mode Test_Case)
{

    switch(Test_Case)
    {
        case ADC_Inject_POLLING:
            ADC_Test_Polling_Injectchannels();
        break;
        case ADC_Inject_IT:
            ADC_Test_IT_Injectchannels();
        break;
        case ADC_Inject_EXT:
            ADC_Test_EXTTrig_Injectchannels();
        break;        
        default:break;

    }
}



