forked from SZV10X_Software/SZV103_FM33A0xxEV_SiZhu

wujiazhi
2024-06-13 72def895431ad7a08e635b11f3da738e2b2c4618
HARDWARE/ADC/ADC.c
@@ -1,242 +1,201 @@
/******************************************************************************
 * Copyright (C) 2014-2015 HangZhou SiZhu Co.,LTD.
 *
 *-----------------------------------------------------------------------------
 * File:              ADC.c
 * Description:      use arm inner adc to sample given voltage
 * Author:           Lishoujian (867693272@qq.com)
 * Date:             Jan 9, 2015
 *****************************************************************************/
/* ----------------------- Platform includes --------------------------------*/
#include "adc.h"
#include "delay.h"
#include "fm25V02.h"
#include "stm32f10x_dma.h"
#include "calculate.h"
#include "devicegpioinit.h"
#include "gpio.h"
#include "power_manage.h"
// ÄÚ²¿ÀÛ¼Ó  Î¶ÈбÂÊ
// float  const_TmpeK   = 4.5295;  //0X640 ADCбÂÊ
// float  const_30_top   = 30.0;
volatile u16                        ad_data[1000];
/******************************************
 * func:    Adc_Init
 * desc:    config gpio;initialize arm inner adc1
 * input:   none
 * output:  none
 * return:  none
 *****************************************/
void  Adc_set(u8 tem_flag)
{
   ADC_InitTypeDef     ADC_InitStructure;
   GPIO_InitTypeDef    GPIO_InitStructure;
// ÍⲿÀÛ¼Ó  Î¶ÈбÂÊ
float const_TmpeK_14BIT = 23.0247; // 14BIT ADCбÂÊ
float const_30_top = 30.0;
      /*GPIO³õʼ»¯*/
   /*dma ad ²É¼¯º¯Êý³õʼ»¯*/
   /*dma ³õʼ»¯ÅäÖú¯Êý*/
   RCC_APB2PeriphClockCmd( RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOC, ENABLE);//enbale adc channel clock
   //RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);   //Enable DMA
   RCC_ADCCLKConfig(RCC_PCLK2_Div6);
   /*¸´Î»ADC1*/
   //ADC_DeInit(ADC1);
   /*GPIO³õʼ»¯*/
   GPIO_InitStructure.GPIO_Pin  = ADC_dianchi_PIN_NUM;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_Init(ADC_dianchi_PIN_GROUP, &GPIO_InitStructure);
   ADC_InitStructure.ADC_Mode                      =  ADC_Mode_Independent;   //ADC1 work mode:independent
   ADC_InitStructure.ADC_ScanConvMode             =  DISABLE;   //single channel mode
   ADC_InitStructure.ADC_ContinuousConvMode     =  DISABLE;   //once   conversion
   ADC_InitStructure.ADC_ExternalTrigConv          =  ADC_ExternalTrigConv_None;   //triggered by software
   ADC_InitStructure.ADC_DataAlign                 =  ADC_DataAlign_Right;   //ADC data align right
   ADC_InitStructure.ADC_NbrOfChannel              =  13;
   ADC_Init(ADC1, &ADC_InitStructure);//init adc1 register
   if(tem_flag==1)
   {
      //¿ªÆôζȴ«¸ÐÆ÷
    ADC_TempSensorVrefintCmd(ENABLE);
   }
     /*ÅäÖÃADCʱÖÓ*/
   /*Ö¸¶¨Í¨µÀ²¢ÉèÖÃת»»Ê±¼ä*/
   //ADC_RegularChannelConfig(ADC1, data_p->ad_ch, 1, ADC_SampleTime_13Cycles5);
   ADC_Cmd(ADC1, ENABLE);//enbale adc1
   ADC_ResetCalibration(ADC1);//reset & calibrate adc1
   while(ADC_GetResetCalibrationStatus(ADC1));//waiting for ending
   ADC_StartCalibration(ADC1);//open calibrating adc1
   while(ADC_GetCalibrationStatus(ADC1));//waiting for ending
}
void  Adc_DeInit(u8 tem_flag)
void ADC_LithIO_Init(void)
{
   GPIO_InitTypeDef    GPIO_InitStructure;
//   ADC_InitTypeDef     ADC_InitStructure;
   /*GPIO³õʼ»¯*/
   RCC_APB2PeriphClockCmd( RCC_APB2Periph_ADC1 , DISABLE);//enbale adc channel clock
   if(tem_flag==1)
   {
      //¿ªÆôζȴ«¸ÐÆ÷
    ADC_TempSensorVrefintCmd(DISABLE);
   }
   ADC_DeInit(ADC1);
   ADC_Cmd(ADC1, DISABLE);
   GPIO_InitStructure.GPIO_Pin  = ADC_dianchi_PIN_NUM;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_Init(ADC_dianchi_PIN_GROUP, &GPIO_InitStructure);
  CMU_PERCLK_SetableEx(PADCLK, ENABLE); // PADʱÖÓ£¨GPIO£©Ê¹Äܺ¯Êý
  //   AnalogIO(LIT_PWR_UNDER_PORT,LIT_PWR_UNDER_PIN);//ADC_5
  //   GPIOx_ANEN_Setable(LIT_PWR_UNDER_PORT,LIT_PWR_UNDER_PIN,ENABLE);
  AnalogIO(LIT_ADC_PORT, LIT_ADC_PIN); // ADC_IN4
  GPIOx_ANEN_Setable(LIT_ADC_PORT, LIT_ADC_PIN, ENABLE);
}
u16 Get_val(u8 ch)
void ADC_AlkaIO_Init(void)
{
      u16 DataValue; //
      /* ADC1 regular channel14 configuration */
      ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_55Cycles5);
      /* Start ADC1 Software Conversion */
      ADC_SoftwareStartConvCmd(ADC1, ENABLE);
      /* Test if the ADC1 EOC flag is set or not */
      while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));
      /*Returns the ADC1 Master data value of the last converted channel*/
      DataValue = ADC_GetConversionValue(ADC1);
      return DataValue;
}
u16 Temp_GetADCData(void)
{
   /*Èí¼þÆô¶¯ADת»»*/
   ADC_SoftwareStartConvCmd(ADC1, ENABLE);
   /*µÈ´ýADת»»Íê³É*/
   while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));
   /*¶ÁÈ¡ºÍ·µ»ØADת»»Öµ*/
   return (ADC_GetConversionValue(ADC1));
  CMU_PERCLK_SetableEx(PADCLK, ENABLE); // PADʱÖÓ£¨GPIO£©Ê¹Äܺ¯Êý
  AnalogIO(ALK_ADC_PORT, ALK_ADC_PIN);  // ADC_IN8
  GPIOx_ANEN_Setable(ALK_ADC_PORT, ALK_ADC_PIN, ENABLE);
}
#define      DATA_START            2
#define      DATA_GET_LENGTH      20
/******************************************
 * func:    Get_vol_Average
 * desc:
 *   - sample total 100 data,list data from low to hign,get middle 64 data
 *   - calculation sample mean of 64 middle data
 * input:
 *   ch       - select sample channel of adc1
 *   vref_adc - Voltage reference of adc1 multiply by 1000. eg:3.3v ->33000
 * output:  none
 * return:  calculation sample mean of 64 middle data,multiply by 1000. eg:1.0v -> 1000
 *****************************************/
uint16 Get_vol_Average(u8 channel,u8 tem_flag)  //channelͨµÀºÅ   tem_flag£º0±íʾÍⲿ¶ÁÈ¡  1±íʾÄÚ²¿Í¨µÀ¶ÁȡζÈÓÃ
void ADC_IN5_Init(void)
{
   u32     i,  t;
//   uint16   temp;
   uint32    temp_vol;
   uint16    ad_get_address_p[DATA_GET_LENGTH + 1];
   uint32   temp_vol_small;
   uint32   temp_vol_big;
   temp_vol = 0;
   Adc_set(tem_flag);
   //ADC_DMA_Transmit();
  CDIF_CR_INTF_EN_Setable(ENABLE); // ¿çµçÔ´Óò½Ó¿ÚʹÄÜ
  VRTC_Init_RCMF_Trim();
  VRTC_RCMFCR_EN_Setable(ENABLE);
  VRTC_ADCCR_CKS_Set(VRTC_ADCCR_CKS_RCMF_2);    // ADC¹¤×÷ʱÖÓÑ¡Ôñ
  VRTC_ADCCR_CKE_Setable(ENABLE);               // ADC¹¤×÷ʱÖÓʹÄÜ
  ADC_CFGR_BUFSEL_Set(ADC_CFGR_BUFSEL_ADC_IN5); // ADCÊäÈëͨµÀÑ¡Ôñ
   for(i = 0; i < DATA_GET_LENGTH; i ++)
   {
      ad_get_address_p[i] = Get_val(channel);
      temp_vol += ad_get_address_p[i];
   }
   Adc_DeInit(tem_flag);
   temp_vol_small    = ad_get_address_p[DATA_START];
   temp_vol_big      = ad_get_address_p[DATA_START];
   for(i = (DATA_START+1); i < (DATA_GET_LENGTH -1); i ++)
   {
      if(temp_vol_small > ad_get_address_p[i])
         temp_vol_small = ad_get_address_p[i];
      if(temp_vol_big < ad_get_address_p[i])
         temp_vol_big = ad_get_address_p[i];
   }
   temp_vol = 0;
   for(t = DATA_START; t < (DATA_GET_LENGTH - 1); t ++)
   {
      temp_vol += ad_get_address_p[t];
   }
   temp_vol = temp_vol - temp_vol_small - temp_vol_big;
  temp_vol  = temp_vol /(DATA_GET_LENGTH - DATA_START - 3);
   return (uint16)temp_vol;
  ADC_CFGR_BUFEN_Setable(ENABLE);                      // ADCÊäÈëͨµÀbufferʹÄÜ/½ûÖ¹
  ADC_CR_MODE_Set(ADC_CR_MODE_EXTERNAL);               // ADC¹¤×÷ģʽѡÔñÍⲿÀÛ¼ÓÆ÷
  ADC_CR_RSTCTRL_EN_Setable(ENABLE);                   // ÔÊÐí»ý·ÖÆ÷Íⲿ¸´Î»
  ADC_CFGR_ACC_PERIOD_Set(ADC_CFGR_ACC_PERIOD_14BITS); // ÍⲿÀÛ¼ÓÆ÷ÀÛ¼ÓÖÜÆÚÅäÖÃ
  ADC_CR_HPEN_Set(ADC_CR_HPEN_1MHZ);
  ADC_TRIM_Write(0X7FF); // adcƵÂÊ1M Ê± ¼ÆËãʱ¼ä4ms
  //  ADC_TRIM_Write(0X3FF);                           //adcƵÂÊ1M Ê± ¼ÆËãʱ¼ä2ms
  //   ADC_TRIM_Write(0X1FF);                           //adcƵÂÊ1M Ê± ¼ÆËãʱ¼ä1ms
  ADC_CR_ACC_IE_Setable(DISABLE); // ÍⲿÀÛ¼ÓģʽÖжϽûÖ¹
  ADC_CR_EN_Setable(DISABLE);     // ADC¹Ø±Õ
}
// /**
//   * @brief  »ñÈ¡°ÍÌØÎÖ˹Â˲¨ºóµÄÊý¾Ý
//   * @param  ÎÞ
//   * @retval ADCÊý¾Ý
//   */
double Temp_GetBFiltedData(ad_data_s * data_p)
void ADC_IN10_Init(void)
{
   u16 i,t;
   volatile double average;
  volatile   u32 sum=0;
   double temp_adc_data[20];
   /*-------------------------Êý¾Ý²É¼¯-------------------------*/
   //AD²ÉÑùSMPL_NUM´Î
   Adc_set(0);
//   ADC_DMA_Transmit();
      for(t = 0; t < 20; t ++)
   {
      temp_adc_data[t]= data_p->ad_get_address_p[t];
      sum += temp_adc_data[t];
   }
   average=(double)sum/20;
   sum=0;
  CDIF_CR_INTF_EN_Setable(ENABLE); // ¿çµçÔ´Óò½Ó¿ÚʹÄÜ
  VRTC_Init_RCMF_Trim();
  VRTC_RCMFCR_EN_Setable(ENABLE);
  VRTC_ADCCR_CKS_Set(VRTC_ADCCR_CKS_RCMF_2);     // ADC¹¤×÷ʱÖÓÑ¡Ôñ
  VRTC_ADCCR_CKE_Setable(ENABLE);                // ADC¹¤×÷ʱÖÓʹÄÜ
  ADC_CFGR_BUFSEL_Set(ADC_CFGR_BUFSEL_ADC_IN10); // ADCÊäÈëͨµÀÑ¡Ôñ
   /*------------------------°ÍÌØÎÖ˹Â˲¨-----------------------*/
   filter_set_initial(temp_adc_data[1],temp_adc_data[0],average,average);
   //»ñÈ¡Â˲¨ºóµÄÊý¾Ý²¢ÇóºÍ
   for(i=2;i<20;i++)
   {
      temp_adc_data[i]=filter_get_output(temp_adc_data[i]);
      sum+= temp_adc_data[i];
   }
   //¼ÆËãÂ˲¨ºóÊý¾ÝµÄƽ¾ùÖµ
   average=(double)sum/(20-2);
  ADC_CFGR_BUFEN_Setable(ENABLE);                      // ADCÊäÈëͨµÀbufferʹÄÜ/½ûÖ¹
  ADC_CR_MODE_Set(ADC_CR_MODE_EXTERNAL);               // ADC¹¤×÷ģʽѡÔñÍⲿÀÛ¼ÓÆ÷
  ADC_CR_RSTCTRL_EN_Setable(ENABLE);                   // ÔÊÐí»ý·ÖÆ÷Íⲿ¸´Î»
  ADC_CFGR_ACC_PERIOD_Set(ADC_CFGR_ACC_PERIOD_14BITS); // ÍⲿÀÛ¼ÓÆ÷ÀÛ¼ÓÖÜÆÚÅäÖÃ
  ADC_CR_HPEN_Set(ADC_CR_HPEN_1MHZ);
   return average;
  ADC_TRIM_Write(0X7FF); // adcƵÂÊ1M Ê± ¼ÆËãʱ¼ä4ms
  //  ADC_TRIM_Write(0X3FF);                           //adcƵÂÊ1M Ê± ¼ÆËãʱ¼ä2ms
  //   ADC_TRIM_Write(0X1FF);                           //adcƵÂÊ1M Ê± ¼ÆËãʱ¼ä1ms
  ADC_CR_ACC_IE_Setable(DISABLE); // ÍⲿÀÛ¼ÓģʽÖжϽûÖ¹
  ADC_CR_EN_Setable(DISABLE);     // ADC¹Ø±Õ
}
void ADC_IN8_Init(void)
{
  CDIF_CR_INTF_EN_Setable(ENABLE); // ¿çµçÔ´Óò½Ó¿ÚʹÄÜ
  VRTC_Init_RCMF_Trim();
  VRTC_RCMFCR_EN_Setable(ENABLE);
  VRTC_ADCCR_CKS_Set(VRTC_ADCCR_CKS_RCMF_2);    // ADC¹¤×÷ʱÖÓÑ¡Ôñ
  VRTC_ADCCR_CKE_Setable(ENABLE);               // ADC¹¤×÷ʱÖÓʹÄÜ
  ADC_CFGR_BUFSEL_Set(ADC_CFGR_BUFSEL_ADC_IN8); // ADCÊäÈëͨµÀÑ¡Ôñ
  ADC_CFGR_BUFEN_Setable(ENABLE);                      // ADCÊäÈëͨµÀbufferʹÄÜ/½ûÖ¹
  ADC_CR_MODE_Set(ADC_CR_MODE_EXTERNAL);               // ADC¹¤×÷ģʽѡÔñÍⲿÀÛ¼ÓÆ÷
  ADC_CR_RSTCTRL_EN_Setable(ENABLE);                   // ÔÊÐí»ý·ÖÆ÷Íⲿ¸´Î»
  ADC_CFGR_ACC_PERIOD_Set(ADC_CFGR_ACC_PERIOD_14BITS); // ÍⲿÀÛ¼ÓÆ÷ÀÛ¼ÓÖÜÆÚÅäÖÃ
  ADC_CR_HPEN_Set(ADC_CR_HPEN_1MHZ);
  ADC_TRIM_Write(0X7FF); // adcƵÂÊ1M Ê± ¼ÆËãʱ¼ä4ms
  //    ADC_TRIM_Write(0X3FF);                           //adcƵÂÊ1M Ê± ¼ÆËãʱ¼ä2ms
  //   ADC_TRIM_Write(0X1FF);                           //adcƵÂÊ1M Ê± ¼ÆËãʱ¼ä1ms
  ADC_CR_ACC_IE_Setable(DISABLE); // ÍⲿÀÛ¼ÓģʽÖжϽûÖ¹
  ADC_CR_EN_Setable(DISABLE);     // ADC¹Ø±Õ
}
void ADC_Temp_Init(void)
{
  CDIF_CR_INTF_EN_Setable(ENABLE); // ¿çµçÔ´Óò½Ó¿ÚʹÄÜ
  VRTC_Init_RCMF_Trim();
  VRTC_RCMFCR_EN_Setable(ENABLE);
  VRTC_ADCCR_CKS_Set(VRTC_ADCCR_CKS_RCMF_2); // ADC¹¤×÷ʱÖÓÑ¡Ôñ
  VRTC_ADCCR_CKE_Setable(ENABLE);            // ADC¹¤×÷ʱÖÓʹÄÜ
  ADC_CFGR_BUFSEL_Set(ADC_CFGR_BUFSEL_TS);   // ADCÊäÈëͨµÀÑ¡Ôñ
  ADC_CFGR_BUFEN_Setable(ENABLE); // ADCÊäÈëͨµÀbufferʹÄÜ/½ûÖ¹
  ADC_CR_MODE_Set(ADC_CR_MODE_EXTERNAL); // ADC¹¤×÷ģʽѡÔñÍⲿÀÛ¼ÓÆ÷
  ADC_CR_RSTCTRL_EN_Setable(ENABLE); // ÔÊÐí»ý·ÖÆ÷Íⲿ¸´Î»  ÄÚ²¿Ä£Ê½disable  Íⲿģʽenable
  ADC_TRIM_Write(0x7FF); // ÍⲿÀۼƠ  ±ØÐëд0x7FF
  ADC_CFGR_ACC_PERIOD_Set(ADC_CFGR_ACC_PERIOD_14BITS); // ÍⲿÀÛ¼ÓÆ÷ÀÛ¼ÓÖÜÆÚÅäÖàÄÚ²¿ÀÛ¼Ó¿É×¢ÊÍ
  ADC_CR_ACC_IE_Setable(DISABLE); // ÍⲿÀÛ¼ÓģʽÖжϽûÖ¹
  ADC_CR_EN_Setable(DISABLE); // ADC¹Ø±Õ
}
uint32_t adc_vol_cal(uint32_t adc_data)
{
  int32_t Volt = 0;
  Volt = (adc_data * const_adc_Slope / 1000.0) + const_adc_Offset / 100.0;
  if (Volt < 0) // VoltΪ¸ºÖµ
  {
    Volt = 0;
  }
  return Volt;
}
float adc_tem_cal(uint32_t adc_data)
{
  float T = 0;
  // ÄÚ²¿ÀÛ¼Ó¼ÆËã
  //   if(adc_data >const_T_30 )
  //   {
  //      T=(adc_data-const_T_30)/const_TmpeK+const_30_top;
  //   }
  //   else
  //   {
  //      T=const_30_top-(const_T_30-adc_data)/const_TmpeK;
  //   }
  // ÍⲿÀۼƼÆËã
  if (adc_data > const_T_30_14BIT)
  {
    T = (adc_data - const_T_30_14BIT) / const_TmpeK_14BIT + const_30_top - 0.5;
  }
  else
  {
    T = const_30_top - (const_T_30_14BIT - adc_data) / const_TmpeK_14BIT - 0.5;
  }
  return T;
}
uint08 adc_wait_finish(void)
{
  uint32 timeout = 0;
  do
  {
    if (SET == ADC_ISR_ACC_IF_Chk())
      return 0; // ÍⲿÀÛ¼Ó
  } while (timeout++ < 0xFFFFFFFFU);
  return 1; // ³¬Ê±
}
uint32_t Get_AdcValue(void)
{
  volatile int32_t fVlotage = 0;
  uint32 fTempADC = 0;
  ADC_CR_EN_Setable(ENABLE); // ADCÆô¶¯
  ADC_ISR_ACC_IF_Clr();       // ÍⲿÀÛ¼ÓÇå³ýÖжϱêÖ¾
  if (0 == adc_wait_finish()) // µÈ´ýת»»Íê³É
    fTempADC = ADC_DR_Read(); // ¶ÁÈ¡ADÖµ
  else
    return 0;
  fVlotage = adc_vol_cal(fTempADC); // ADֵת»»Îªµçѹ,µçÔ´µçѹΪ5V
  return fVlotage;
}
float Get_AdcTempValue(void)
{
  float Temperature = 0;
  uint32 fTempADC = 0;
  ADC_CR_EN_Setable(ENABLE); // ADCÆô¶¯
  ADC_ISR_ACC_IF_Clr();       // ÍⲿÀÛ¼ÓÇå³ýÖжϱêÖ¾
  if (0 == adc_wait_finish()) // µÈ´ýת»»Íê³É
    fTempADC = ADC_DR_Read(); // ¶ÁÈ¡ADÖµ
  else
    return 0;
  Temperature = adc_tem_cal(fTempADC);
  return Temperature;
}