本帖最后由 yuandm1 于 2015-7-7 13:02 编辑
使用STM32F103VCT6 的ADC 连接外部称重传感器。测量的模拟值一直在跳动,大约有20个AD的变化。
ADC的外部输入电压范围为0-3V。用示波器观察纹波后,发现波形还可以。如下图。
程序如下:
void ADC_Configuration(void)
{
ADC_InitTypeDef ADC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
/* Enable DMA clock */ //-------------------------------------------------------------------------RCC
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
/* Enable ADC1 and GPIOC clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 , ENABLE);
/* DMA channel1 configuration */ //------------------------------------------------------------------DMA
//使能DMA
DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&ADC1->DR; //DMA外设ADC基地址
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&(system1.Adc_Values); //DMA传送地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //传送方向
DMA_InitStructure.DMA_BufferSize = M_SAMPLE_COUNT*M_ADC_NUMS; //传送内存大小 M_SAMPLE_COUNT*
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //传送内存地址递增
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //ADC1转换的数据是16位
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //传送的目的地址是16位宽度
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);
/* 允许DMA1通道1传输结束中断 */
//DMA_ITConfig(DMA1_Channel1,DMA_IT_TC, ENABLE);
//使能DMA通道1
DMA_Cmd(DMA1_Channel1, ENABLE);
//设置AD模拟输入端口 IO //---------------------------------------------------------------------------IO
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 |GPIO_Pin_1 ;//PB0 是拉力传感器 PB1是虚拟限位传感器
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOB, &GPIO_InitStructure);
//ADC配置--------------------------------------------------------------------------------------------ADC
// ADC_DeInit(ADC1); //将外设 ADC1 的全部寄存器重设为缺省值
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC1工作在独立模式
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数据右对齐
ADC_InitStructure.ADC_NbrOfChannel = M_ADC_NUMS; //规定了顺序进行规则转换的ADC通道的数目。这个数目的取值范围是1到16
ADC_Init(ADC1, &ADC_InitStructure);
//设置指定ADC的规则组通道,设置它们的转化顺序和采样时间
ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_239Cycles5 );
ADC_RegularChannelConfig(ADC1, ADC_Channel_9, 2, ADC_SampleTime_239Cycles5 );
//使能ADC1 DMA
ADC_DMACmd(ADC1, ENABLE);
//使能ADC1
ADC_Cmd(ADC1, ENABLE);
// 初始化ADC1校准寄存器
ADC_ResetCalibration(ADC1);
//检测ADC1校准寄存器初始化是否完成
while(ADC_GetResetCalibrationStatus(ADC1));
//开始校准ADC1
ADC_StartCalibration(ADC1);
//检测是否完成校准
while(ADC_GetCalibrationStatus(ADC1));
//ADC1转换启动
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}
由于有上面的波动。虽然做了中值滤波,平均值滤波。可是效果还是不很好。
请问大家在做ADC的时候用的什么算法。谢谢。
|