/*--------------------------------------------------------------------------------------
*  @file     ADCSetup.c
*  @author   ZhangJing
*  @version  base on stm32f0x   
*  @date     2015.09.11
*  @brief    芯片内部ADC驱动
---------------------------------------------------------------------------------------*/
#include "stm32f10x_gpio.h"
#include "stm32f10x_adc.h"
#include "stm32f10x_dma.h"
#include "TypeDefine.h"
#include "ADCSetup.h"

__IO uint32_t ADC_ConvertedValue[2];//内部ADC转换数组
uint16_t batteryVolt[7]={ 0xffff , 0xffff , 0xffff , 0xffff , 0xffff, 0xffff , 0xffff };//电池电压采集数组
uint16_t batteryAverage = 0xffff;//电池电压平均值
uint8_t batteryCounts = 0;//采集次数累计
uint8_t ADC_Voit_Done=0; //电压AD采集完成标志

/***************************************************************************************
*  Function:	DriverADCInit						                                                           
*  Object:		Configures ADC GPIO.
*  输入:			无
*  输出:			无	                                     
*  备注:			PB0             
***************************************************************************************/
void AdcDmaInit(void)
{
	DMA_InitTypeDef DMA_InitStructure;
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);        /* use for adc model */

	/* DMA1 channel1 configuration ----------------------------------------------*/
	DMA_DeInit(DMA1_Channel1);
	DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;
	DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC_ConvertedValue;
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
	DMA_InitStructure.DMA_BufferSize = 1;
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
	DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
	DMA_InitStructure.DMA_Priority = DMA_Priority_High;
	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
	DMA_Init(DMA1_Channel1, &DMA_InitStructure);
	
	/* Enable DMA1 channel1 */
	DMA_Cmd(DMA1_Channel1, ENABLE);
}
/******************************************
*	功能：ADC1初始化，使用PC04引脚采集
******************************************/
void DriverADCInit(void)
{
	ADC_InitTypeDef ADC_InitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOC, ENABLE);

	/* Configure PC.04 (ADC Channel12) as analog input -------------------------*/
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOC, &GPIO_InitStructure);
	
	/* ADC1 configuration ------------------------------------------------------*/
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;/*ADC工作在独立模式*/
	ADC_InitStructure.ADC_ScanConvMode = ENABLE;
	ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;/*软件触发*/
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
	ADC_InitStructure.ADC_NbrOfChannel = 1;/*单通道*/
	ADC_Init(ADC1, &ADC_InitStructure);	
	/* ADC1 regular channel12 configuration */ 
	ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 1, ADC_SampleTime_55Cycles5);

	AdcDmaInit();/*DMA配置*/	
	/* Enable ADC1 DMA */
	ADC_DMACmd(ADC1, ENABLE); 
	/* Enable ADC1 */
	ADC_Cmd(ADC1, ENABLE);
	
	/* Enable ADC1 reset calibration register */   
	ADC_ResetCalibration(ADC1);
	/* Check the end of ADC1 reset calibration register */
	while(ADC_GetResetCalibrationStatus(ADC1));
	/*开始校准*/
	ADC_StartCalibration(ADC1);
	/* 等待校准结束*/
	while(ADC_GetCalibrationStatus(ADC1));
	ADC_SoftwareStartConvCmd(ADC1, ENABLE);/*开启转换*/     
}

/********************************************************************************************************
*  Function:	BatteryVoltADCGet						                                                           
*  Object:		电池电压采集
*  输入:			无
*  输出:			无	                                     
*  备注:			1、只要TaskSchedulerFlag.sensorPWBatteryFlag标志位置位或 motorWorkState == MOTOR_WORK_OFF才会采集一次电池电压值            
*							2、uint32_t tempADC1 = 0;临时变量读取AD数值
*							3、uint16_t  tempVolt = 0;临时变量计算采集电压
*							4、通过均值算法得出稳定电压值，每采集7次值，前2次值丢弃，比较一下，取平均值
*							5、realTimeData.batteryVolt = (uint8_t)( 100 - ( ( 45 - batteryAverage ) * 100 / 15 ) );//电池电压 4.5 - 3.0 = 1.5*10
********************************************************************************************************/
void BatteryVoltADCGet( void )
{
	uint32_t tempADC1 = 0;
	
	uint16_t  tempVolt = 0;
	
	uint8_t  i,j;
	
	if ( TaskSchedulerFlag.sensorPWBatteryFlag == TASK_FLAG_SET ) 
	{
		//conment by wulianwei
		/**if(( TaskSchedulerFlag.zigbeeXmitFlag != TASK_FLAG_CLEAR )&&(RunToLorawawn_flag != TASK_FLAG_CLEAR)&&(EngineeringModeValue.networkState == ENGINEERINGMODE_ON))//如果在采集的时候恰巧碰到数据发送，则此时不采集等待下一个周期再采电池电压
		{
			TaskSchedulerFlag.sensorPWBatteryFlag = TASK_FLAG_CLEAR;//传感器电源-电压关闭
			TaskSchedulerTimer.batteryVoltTimer = TEN_SECOND_TIMER;
		}
		else */ if (motorWorkState != MOTOR_WORK_OFF )
		{
			TaskSchedulerFlag.sensorPWBatteryFlag = TASK_FLAG_CLEAR;//传感器电源-电压关闭
			TaskSchedulerTimer.batteryVoltTimer = TEN_SECOND_TIMER;
		}		
		else 
		{
			//ADC 采集的值在DMA 中赋值
			
			ADC_RegularChannelConfig(ADC2, ADC_Channel_12, 1, ADC_SampleTime_55Cycles5);
			ADC_SoftwareStartConvCmd(ADC2, ENABLE);		//启动转换	
			while(!ADC_GetFlagStatus(ADC2, ADC_FLAG_EOC ));  //等待转换完成
			tempADC1=ADC_GetConversionValue(ADC2); //获取转换结果*ADC_ConvertedValue*	
			//tempADC1 = ADC_ConvertedValue[0] & 0x0fff;
			
			tempADC1 = tempADC1 * 2515 / 4096;    
			batteryVolt[batteryCounts] = (uint16_t)( tempADC1 * 6 );  //6这个数值是从分压电路得到
			
			batteryCounts++;
			
			if( batteryCounts >= 7 )//每采集7次值，前2次值丢弃，比较一下，取平均值
			{
				batteryCounts = 0;
				for( i = 2; i < 7; i++ )
				{
					tempVolt = batteryVolt[i];
					for( j = 2; j < 8 - i; j++ )
					{
						if( batteryVolt[j] > batteryVolt[j + 1] )
						{
							tempVolt = batteryVolt[j];
							batteryVolt[j] = batteryVolt[j + 1];
							batteryVolt[j + 1] = tempVolt;
						}
					}				
				}
				
				tempVolt = ( batteryVolt[3] + batteryVolt[4] + batteryVolt[5] ) / 3;//去掉最高最低值，其余3个值做平均值
				
				/*if( ( tempVolt % 100 ) > 70 )//如果余数>70mv采集值就向上加100mV
				{
					tempVolt /= 100;//x.x V,舍去后两位
					tempVolt += 1;
				}
				else
				{
					tempVolt /= 100;//x.x V,舍去后两位
				}*/

				if( tempVolt <= 4900 )//如果平均值大于45则说明采集值有很大误差，则重新采集7次   20170519修改电压《=4.9v都为正常的电压
				{
					batteryAverage = tempVolt;
					
					if( batteryAverage > 4500 )//如果采集值>4.5V则默认为4.5V，电压范围为3.0~4.5V
					{
						batteryAverage = 4500;
					}
					else if( batteryAverage < 3000 )
					{
						batteryAverage = 3000;
					}
					realTimeData.batteryVolt = (uint8_t)( 100 - ( ( 4500 - batteryAverage ) * 100 / 1500 ) );//电池电压 4.5 - 3.0 = 1.5*10
					
					TaskSchedulerFlag.sensorPWBatteryFlag = TASK_FLAG_CLEAR;//传感器电源-电压关闭
					ADC_Voit_Done=1;//电压采集并运算完毕
				}
			}		
		}
	}
}

