ADC 采样不准 最多几十个数的抖动
ADC设置为双ADC同步模式,共采集6通道。MCU主频56M,ADC工作在14M,采样周期ADC_SampleTime_1Cycles5。用TIM5 以1ms触发一次转换,显示在TFT上。结果是如果采集的是参考电压,结果是4095最大值,但是如果采集的不是参考电压结果就会抖动,很严重。请各位看看应该是什么问题。/***************************************************************************** 名 称:void ADC_Configuration(void)
* 功 能:ADC 配置函数
* 入口参数:无
* 出口参数:无
* 说 明:
* 调用方法:
****************************************************************************/
void ADC_Configuration(void)
{
ADC_InitTypeDef ADC_InitStructure; //limaojun:定义ADC结构体变量
GPIO_InitTypeDef GPIO_InitStructure; // GPIO
DMA_InitTypeDef DMA_InitStructure; // DMA
//设置AD模拟输入端口为输入 1路AD 规则通道//limaojun:选择ADC模块(1、2、3)所要使用的引脚及配置信息这里选用的是ADC1使用PC1配置为模拟输入模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12|
GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOC, &GPIO_InitStructure);
/* Enable DMA clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
/* Enable ADC1 and GPIOC clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1|RCC_APB2Periph_ADC2 , ENABLE);
//ADC时钟配置
RCC_ADCCLKConfig(RCC_PCLK2_Div4);
/* DMA channel1 configuration ----------------------------------------------*/
//使能DMA
DMA_DeInit(DMA1_Channel1); //limaojun:复位所选DMA通道
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address; //DMA通道1的地址 limaojun:根据外设ADC在存储器当中的地址映射而来
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADC_ConvertedValue; //DMA传送地址 limaoju:ADC转换出的数据的存储地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //传送方向limaojun:指定外设是DMA的源还是目的地址,这里是源地址
DMA_InitStructure.DMA_BufferSize = 6;//?????????????????????? //传送内存大小,100个16位
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //limaojun:指出外设的地址寄存器是否增加了
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //确定传送内存地址递增
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;//HalfWord; //ADC1转换的数据是16位
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;//HalfWord; //传送的目的地址是16位宽度
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//???????????? //循环缓冲模式
DMA_InitStructure.DMA_Priority = DMA_Priority_High; //limaojun:配置DMA通道的软件优先级
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //limaojun:使能DMA通道的存储器到存储器传输,这里未使能因为DMA操作模式选择的是循环缓冲模式
DMA_Init(DMA1_Channel1, &DMA_InitStructure); //limaojun:DMA初始化完成
/* 允许DMA1通道1传输结束中断 */
//DMA_ITConfig(DMA1_Channel1,DMA_IT_TC, ENABLE);
//使能DMA通道1
DMA_Cmd(DMA1_Channel1, ENABLE);
//ADC1配置 # ???
ADC_InitStructure.ADC_Mode = ADC_Mode_RegInjecSimult;//Independent; //ADC1工作在独立模式
ADC_InitStructure.ADC_ScanConvMode = ENABLE; //模数转换工作在扫描模式(多通道)还是单次(单通道)模式
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //模数转换工作在循环扫描模式(多通道)还是单次(单通道)模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//转换由软件而不是外部触发启动
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//ADC数据右对齐
ADC_InitStructure.ADC_NbrOfChannel = 3; //规定了顺序进行规则转换的ADC通道的数目。这个数目的取值范围是1到16
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC1 regular channels configuration [规则模式通道配置]*/
//ADC1 规则通道配置
ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1,ADC_SampleTime_1Cycles5); //通道10采样时间 55.5周期
ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 2,ADC_SampleTime_1Cycles5); //通道11采样时间 55.5周期
ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 3,ADC_SampleTime_1Cycles5); //通道12采样时间 55.5周期
ADC_DMACmd(ADC1, ENABLE);//使能ADC1 DMA
//ADC2配置 # ???
ADC_InitStructure.ADC_Mode = ADC_Mode_RegInjecSimult;//Independent; //ADC1工作在独立模式
ADC_InitStructure.ADC_ScanConvMode = ENABLE; //模数转换工作在扫描模式(多通道)还是单次(单通道)模式
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //模数转换工作在循环扫描模式(多通道)还是单次(单通道)模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//转换由软件而不是外部触发启动
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//ADC数据右对齐
ADC_InitStructure.ADC_NbrOfChannel = 3; //规定了顺序进行规则转换的ADC通道的数目。这个数目的取值范围是1到16
ADC_Init(ADC2, &ADC_InitStructure);
//ADC2 规则通道配置
ADC_RegularChannelConfig(ADC2, ADC_Channel_13, 1,ADC_SampleTime_1Cycles5); //通道13采样时间 55.5周期
ADC_RegularChannelConfig(ADC2, ADC_Channel_14, 2,ADC_SampleTime_1Cycles5); //通道14采样时间 55.5周期
ADC_RegularChannelConfig(ADC2, ADC_Channel_15, 3,ADC_SampleTime_1Cycles5); //通道15采样时间 55.5周期
ADC_ExternalTrigConvCmd(ADC2, ENABLE);// DISABLE
//使能ADC1
ADC_Cmd(ADC1, ENABLE);
// 初始化ADC1校准寄存器
ADC_ResetCalibration(ADC1);
//检测ADC1校准寄存器初始化是否完成
while(ADC_GetResetCalibrationStatus(ADC1));
//开始校准ADC1
ADC_StartCalibration(ADC1);
//检测是否完成校准
while(ADC_GetCalibrationStatus(ADC1));
//使能ADC2
ADC_Cmd(ADC2, ENABLE);
// 初始化ADC1校准寄存器
ADC_ResetCalibration(ADC2);
//检测ADC1校准寄存器初始化是否完成
while(ADC_GetResetCalibrationStatus(ADC2));
//开始校准ADC2
ADC_StartCalibration(ADC2);
//检测是否完成校准
while(ADC_GetCalibrationStatus(ADC2));
//ADC1转换启动
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
RE:ADC 采样不准 最多几十个数的抖动
你采集的电压不稳定。建议哟你给稳定的电压测试。回复:ADC 采样不准 最多几十个数的抖动
回复第 2 楼 于2013-02-22 11:37:08发表:你采集的电压不稳定。建议哟你给稳定的电压测试。
我之前用的是usb供电,后来换作电池组情况依然如此我想电源不稳肯定是有原因,但不主要原因。参考stm32硬件设计指南,知道采样速率与adc的输入阻抗有关,如果输入阻抗不匹配也使结果不准确。但是我只是简单的从电位器的中心抽头取电压而且电位器两端的电压就取自参考电压和地结果会这么不稳!
回复:ADC 采样不准 最多几十个数的抖动
回复第 3 楼 于2013-02-23 06:35:35发表:回复第 2 楼 于2013-02-22 11:37:08发表:
你采集的电压不稳定。建议哟你给稳定的电压测试。
我之前用的是usb供电,后来换作电池组情况依然如此我想电源不稳肯定是有原因,但不主要原因。参考stm32硬件设计指南,知道采样速率与adc的输入阻抗有关,如果输入阻抗不匹配也使结果不准确。但是我只是简单的从电位器的中心抽头取电压而且电位器两端的电压就取自参考电压和地结果会这么不稳!
楼主你的问题解决了吗?我也遇到采样值跳动的问题,我是用stm32f3的芯片adc采样速率500k ,61.5个sampling time 去采集串联电压参考ref3130经两个千分之一电阻分压得到的1.5v电压,采样数字量跳动二三十个。
页:
[1]