//保证ADC检测出来的值是稳定
#include “adc.h”
_detection sampling;
_detection display;
/ADC,DMA模式/
/PC0~PC4 分别对应 ADC_Channel_10~ADC_Channel_14/
#define AVR_NUMBER 1//取平均值的次数
//u16 Sampling_vol1,Sampling_vol2,Sampling_vol3,Sampling_vol4,Sampling_vol5;//3.3V基准计算的采样值1~5
//DMA高16位保存ADC2,低16位保存ADC1
#define ADC1_2_DR_ADDRESS ((u32)0x40012400+0x4c)//0x4c意思是ADC_DR的具体地址,0x40012400意思是ADC寄存器的地址
#define ADC3_DR_ADDRESS ((u32)0x40013c00+0x4c)//0x4c意思是ADC_DR的具体地址,0x40013c00意思是ADC寄存器的地址
typedef union{
__IO u32 Value;//__IO提示编译器该对象的值可能在未监测的情况下改变
__IO u16 Raw_Value[2];
}_ADC1_2;
_ADC1_2 ADC1_2;
//__IO u16 ADC3_Raw_Value;
//8分频,
void Adc_Init(void)
{
ADC_InitTypeDef ADC_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC |RCC_APB2Periph_ADC1|RCC_APB2Periph_ADC2 |RCC_APB2Periph_ADC3
, ENABLE);//使能 ADC1 通道时钟
RCC_ADCCLKConfig(RCC_PCLK2_Div8); //设置 ADC 分频因子 8
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;//模拟输入
GPIO_Init(GPIOC, &GPIO_InitStructure); //初始化 GPIOC
ADC_DeInit(ADC1); //复位 ADC1,将外设 ADC1 的全部寄存器重设为缺省值
ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult;//ADC双模式,规则同步转换
ADC_InitStructure.ADC_ScanConvMode = DISABLE; //单通道模式
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//连续转换
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//软件触发
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC 数据右对齐
ADC_InitStructure.ADC_NbrOfChannel = 1; //顺序进行规则转换的 ADC 通道的数目
ADC_Init(ADC1, &ADC_InitStructure); //根据指定的参数初始化外设 ADC1
//ADC2配置
ADC_DeInit(ADC2);
ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult;//ADC双模式,规则同步转换
ADC_InitStructure.ADC_ScanConvMode = DISABLE; //单通道模式
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//连续转换
ADC_InitStructure.ADC_ExternalTrigConv =ADC_ExternalTrigConv_None;//软件触发
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC 数据右对齐
ADC_InitStructure.ADC_NbrOfChannel = 1; //顺序进行规则转换的 ADC 通道的数目
ADC_Init(ADC2, &ADC_InitStructure); //根据指定的参数初始化外设 ADC2
//ADC3配置
ADC_DeInit(ADC3);
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//ADC独立模式,规则同步转换
ADC_InitStructure.ADC_ScanConvMode = DISABLE; //单通道模式
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//连续转换
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//软件触发
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC 数据右对齐
ADC_InitStructure.ADC_NbrOfChannel = 1; //顺序进行规则转换的 ADC 通道的数目
ADC_Init(ADC3, &ADC_InitStructure); //根据指定的参数初始化外设 ADC
//采样时间71μs;
ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC2, ADC_Channel_11, 1, ADC_SampleTime_239Cycles5);//采样时间过短,会影响DMA数据的传输
ADC_RegularChannelConfig(ADC3, ADC_Channel_12, 1, ADC_SampleTime_239Cycles5);
ADC_TempSensorVrefintCmd(ENABLE);
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
ADC_Cmd(ADC2, ENABLE);
ADC_Cmd(ADC3, ENABLE);
//// configuration DMA ///////////////////////////////////////////////////////////////
/* Enable DMA1 clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);
//DMA1配置
DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_2_DR_ADDRESS; // 外设地址
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADC1_2.Value;//存放地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//设置DMA传输,由外设至内存
DMA_InitStructure.DMA_BufferSize = AVR_NUMBER; // 传输数据量的大小
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // 设置DMA的外设递增模式,一个外设
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; // 设置DMA的内存递增模式
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; // 外设数据字长
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; // 内存数据字长
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; // 设置DMA的传输模式:连续不断的循环模式
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; // 设置DMA的优先级别
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; // 设置DMA的2个memory中的变量互相访问
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
//DMA2配置
DMA_DeInit(DMA2_Channel5);
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC3_DR_ADDRESS; // 外设地址
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADC3_Raw_Value;//存放地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//设置DMA传输,由外设至内存
DMA_InitStructure.DMA_BufferSize = AVR_NUMBER;// 传输数据量的大小
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // 设置DMA的外设递增模式,一个外设
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; // 设置DMA的内存递增模式
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; // 外设数据字长
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; // 内存数据字长
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; // 设置DMA的传输模式:连续不断的循环模式
DMA_InitStructure.DMA_Priority = DMA_Priority_High; // 设置DMA的优先级别
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; // 设置DMA的2个memory中的变量互相访问
DMA_Init(DMA2_Channel5, &DMA_InitStructure);
/* Enable DMA channel1 */
DMA_Cmd(DMA1_Channel1, ENABLE);
DMA_Cmd(DMA2_Channel5, ENABLE);
/* Enable ADC1 DMA */
ADC_DMACmd(ADC1, ENABLE);
ADC_DMACmd(ADC2, ENABLE);
ADC_DMACmd(ADC3, ENABLE);
/* Enable ADC1 reset calibaration register */
ADC_ResetCalibration(ADC1);
ADC_ResetCalibration(ADC2);
ADC_ResetCalibration(ADC3);
while(ADC_GetResetCalibrationStatus(ADC1)&&ADC_GetResetCalibrationStatus(ADC2)
);//同时等待复位校准结束&&ADC_GetResetCalibrationStatus(ADC3)
/* Start ADC1 calibaration */
ADC_StartCalibration(ADC1);
ADC_StartCalibration(ADC2);
ADC_StartCalibration(ADC3);
while(ADC_GetCalibrationStatus(ADC1)&&ADC_GetCalibrationStatus(ADC2)&&ADC_GetCalibrationStatus(ADC3));
/* Start ADC1 Software Conversion */
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
ADC_SoftwareStartConvCmd(ADC2, ENABLE);
ADC_SoftwareStartConvCmd(ADC3, ENABLE);
}
float vol_1,vol_2;//转换的电流电压值
//获取检测到的值
void Get_Adc_Value(void){
vol_1 = KalmanFilter_1(ADC1_2.Raw_Value[0]/4095.0*3279,0.0001,1000,0)*vol1_ratio;//xl4016输出电压
vol_2 = KalmanFilter_2(ADC1_2.Raw_Value[1]/4095.0*3279,0.0001,1000,0)*vol2_ratio;//
sampling.V = vol_2; //负载两端的电压值单位V
sampling.I = (vol_1- vol_2)/cur_ratio; //负载电流
}
#ifndef __ADC_H
#define __ADC_H
#include “sys.h”
#define vol1_ratio 4.009
#define vol2_ratio 3.972
#define cur_ratio 5.09
typedef struct{
float V;
float I;
}_detection;
extern _detection sampling;
extern void Adc_Init(void);
extern void Get_Adc_Value(void);
#endif