|
/******************************************************************************
|
* 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;
|
}
|