/*-------------------------------------------------------------------------------------- * @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;//电压采集并运算完毕 } } } } }