/****************************************************************************** * 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" 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; /*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) { 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); } u16 Get_val(u8 ch) { 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)); } #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±íʾÄÚ²¿Í¨µÀ¶ÁȡζÈÓà { 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(); 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; } // /** // * @brief »ñÈ¡°ÍÌØÎÖ˹Â˲¨ºóµÄÊý¾Ý // * @param ÎÞ // * @retval ADCÊý¾Ý // */ double Temp_GetBFiltedData(ad_data_s * data_p) { 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; /*------------------------°ÍÌØÎÖ˹Â˲¨-----------------------*/ 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); return average; }