/********************************************************************************
* @file    ADC_CycleConversion_DMA.c
* @author  SOC AE Team
* @version V1.1
* @date    2025-06-27
* @brief   获取内部四分之一VDD通道的ADC连续20次的转换值，并且求平均值。
*
*******************************************************************************/
#include "sc32_conf.h"
#include "Function_Init.h"
#if defined(SC32f10xx)|| defined(SC32f12xx)
static volatile FlagStatus ADC_Flag = RESET;

void ADC_CycleConversion_DMA_Function(void)
{
  ADC_InitTypeDef ADC_InitStruct; //定义ADC初始化结构体变量
  DMA_InitTypeDef DMA_InitStruct; //定义DMA初始化结构体变量
  uint16_t ADC_ValueArray[20];
  uint16_t ADC_ValueMax, ADC_ValueMin, ADC_ValueMean, ADC_ValueNum;
  uint32_t ADC_ValueSum = 0;
  
  RCC_APB2Cmd(ENABLE);  //ADC外设挂载在APB2时钟上
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA, ENABLE);
  
  ADC_InitStruct.ADC_ConvMode = ADC_ConvMode_Continuous;  //ADC单次转换模式
  ADC_InitStruct.ADC_Prescaler = ADC_Prescaler_3CLOCK;  //转换时间为3个周期
  ADC_InitStruct.ADC_VREF = ADC_VREF_VDD; //参考电压为VDD
  ADC_InitStruct.ADC_EAIN = ADC_EAIN_0; //把ADC0设为ADC输入引脚
  
  ADC_Init(ADC, &ADC_InitStruct); //根据结构体标志位配置ADC
  ADC_SetChannel(ADC,ADC_Channel_VDD_D4);
  
  /* DMA外设配置 */
  DMA_StructInit(&DMA_InitStruct);
  
  DMA_InitStruct.DMA_CircularMode = DMA_CircularMode_Disable;
  DMA_InitStruct.DMA_DataSize = DMA_DataSize_HalfWord;
  DMA_InitStruct.DMA_TargetMode = DMA_TargetMode_INC_CIRC;
  DMA_InitStruct.DMA_SourceMode = DMA_SourceMode_FIXED;
  DMA_InitStruct.DMA_SrcAddress = (uint32_t)&ADC->ADC_VALUE;
  DMA_InitStruct.DMA_DstAddress = (uint32_t)ADC_ValueArray;
  DMA_InitStruct.DMA_Request = DMA_Request_ADC;
  DMA_InitStruct.DMA_BufferSize = 20;
  
  DMA_Init(DMA0, &DMA_InitStruct);
  
  DMA_ITConfig(DMA0,DMA_IT_INTEN | DMA_IT_TCIE,ENABLE);
  NVIC_EnableIRQ(DMA0_IRQn);
  
  ADC_DMACmd(ADC, ENABLE);
  ADC_Cmd(ADC,ENABLE);
  DMA_Cmd(DMA0, ENABLE);
  
  ADC_SoftwareStartConv(ADC); // 开启转换
  
  while(!ADC_Flag); //等待ADC 20次转换完成
  
  /* 获取20次ADC转换的平均值，去除最大最小值 */
  ADC_ValueMax = 0;
  ADC_ValueMin = 0X01 << 14;
  for(ADC_ValueNum = 0; ADC_ValueNum < 20; ADC_ValueNum ++)
  {
    ADC_ValueSum += ADC_ValueArray[ADC_ValueNum];
    if(ADC_ValueArray[ADC_ValueNum] > ADC_ValueMax)
      ADC_ValueMax = ADC_ValueArray[ADC_ValueNum];
    if(ADC_ValueArray[ADC_ValueNum] < ADC_ValueMin)
      ADC_ValueMin = ADC_ValueArray[ADC_ValueNum];
  }
  
  ADC_ValueMean = (uint16_t)((ADC_ValueSum - ADC_ValueMax - ADC_ValueMin) / 18);
  
  printf("\r\n ADC Conversion Value is 0x%x \r\n",ADC_ValueMean);
  
  while(1);
}

void ADC_CycleConversion_DMAHandler(void)
{
  if(DMA_GetFlagStatus(DMA0, DMA_FLAG_TCIF))
  {
    DMA_ClearFlag(DMA0, DMA_FLAG_TCIF | DMA_FLAG_HTIF);
    ADC_Flag = SET;
    
    /* 停止ADC连续转换 */
    ADC_ConvModeConfig(ADC,ADC_ConvMode_Single);
  }
}



#endif
