403A 替代 STM32F103 问题
本帖最后由 sevenwolf 于 2022-2-26 23:05 编辑403A 替代 STM32F103 连续采样10CH 第一个通道通常有数值AD=5-8 其他通道为 0;当第一通道有电压值输入时第二通道 采样值AD可= 8-12(第二通道无电压输入)。当第2通道有电压输入时则影响到第三通道,以此类推。 在原STM32F103上无此问题,Fad = 4.5M 采样周期 239.5周期,采用DMA方式连续采样10通道 版主帮我分析下哇好像是DMA 连续扫描时的相互干扰,都是上一通道影响下一通道。我把Fad降到500K都不行。使用STM32F103就是好的 各位大佬帮忙看看,到底什么问题。ST芯片是正常的
void ADC_Configuration(void)
{
ADC_InitTypeDef ADC_InitStructure;
ADC_BuffDataIni();
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
ADC_DMA_Configuration();
//RCC_ADCCLKConfig(RCC_PCLK2_Div6);//12M最大14M
RCC_ADCCLKConfig(RCC_PCLK2_Div8); //18/4 = 4.5M 提高转换精度
//RCC_GetClocksFreq(&RCC_Clocks);
ADC_DeInit(ADC1);
//ADC_InitStructure.ADC_Mode=ADC_Mode_Independent; //独立模式
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=CHANNEL_SUM; //采样通道数
ADC_Init(ADC1,&ADC_InitStructure);
//ADC_TempSensorVrefintCmd(ENABLE);
//SYSCFG_VBATMonitoringCmd(ENABLE); //激活电池监控
//ADC_TempSensorVrefintCmd(ENABLE); //开启内部参考电压通道
/*///////////adc输入/////////////////
PA2ADCIN1 REF 2.5V
PA3ADCIN2 TEMP
PA4ADCIN4 AN1
PA5ADCIN5 AN2
PA6ADCIN6 AN3
PA7ADCIN7 AN4
PC4ADCIN14 AN5
PC5ADCIN15 AN6
PB0ADCIN8 AN7
PB1ADCIN9 AN8
*/
//ADC_SampleTime_239Cycles5239.5+12.5 = 252 4.5M CLK= 56us采样时间*10 = 560us 20ms内采样 35.7个数值 //9M CLK= 28us采样时间*10 = 280us 20ms内采样 71.4个数值
ADC_RegularChannelConfig(ADC1,ADC_Channel_4,1,ADC_SampleTime_239Cycles5); //PA4//ADIN1
ADC_RegularChannelConfig(ADC1,ADC_Channel_5,2,ADC_SampleTime_239Cycles5); //PA5//ADIN2
ADC_RegularChannelConfig(ADC1,ADC_Channel_6,3,ADC_SampleTime_239Cycles5); //PA6//ADIN3
ADC_RegularChannelConfig(ADC1,ADC_Channel_7,4,ADC_SampleTime_239Cycles5); //PA7//ADIN4
ADC_RegularChannelConfig(ADC1,ADC_Channel_14,5,ADC_SampleTime_239Cycles5); //PC4//ADIN5
ADC_RegularChannelConfig(ADC1,ADC_Channel_15,6,ADC_SampleTime_239Cycles5); //PC5//ADIN6
ADC_RegularChannelConfig(ADC1,ADC_Channel_8,7,ADC_SampleTime_239Cycles5); //PB0//ADIN7
ADC_RegularChannelConfig(ADC1,ADC_Channel_9,8,ADC_SampleTime_239Cycles5); //PB1//ADIN8
ADC_RegularChannelConfig(ADC1,ADC_Channel_3,9,ADC_SampleTime_239Cycles5); //PA3 //机内温度
ADC_RegularChannelConfig(ADC1,ADC_Channel_2,10,ADC_SampleTime_239Cycles5); //PA2//参考电源
//////////////////使能ADC1通道DMA请求//////////////////////////////////////
ADC_DMACmd(ADC1,ENABLE);//重要
Delay_ms(1000);
///////////////////启动ADC1////////////////////////////////////////////////
ADC_Cmd(ADC1,ENABLE);
/////////////////进行ADC校准上电后需校准/////////////////////////////////
//////////////重置ADC校准寄存器 进行初始化/////////////////////////////////
ADC_ResetCalibration(ADC1);
//////////////等待ADC校准寄存器初始化完成//////////////////////////////////
while(ADC_GetResetCalibrationStatus(ADC1));
//////////////开始进行ADC1校准/////////////////////////////////////////////
ADC_StartCalibration(ADC1);
//////////////等待ADC1校准完成/////////////////////////////////////////////
while(ADC_GetCalibrationStatus(ADC1));
Delay_ms(1000);
////////////////////开始软件触发进行转换///////////////////////////////////
ADC_SoftwareStartConvCmd(ADC1,ENABLE);
//ADC_SoftwareStartConv(ADC1);
// gADC_Timer = ADC_CalculationTimer(); //10MS计算一个数值
}
void ADC_DMA_Configuration(void)
{
DMA_InitTypeDef DMA_InitStructure;
// NVIC_InitTypeDef NVIC_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_PeripheralBaseAddr=(u32)&ADC1->DR;
DMA_InitStructure.DMA_MemoryBaseAddr=(u32)gADC_DMAValue;
DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralSRC; //外设作为数据传输的来源
DMA_InitStructure.DMA_BufferSize=ADC_BUFF_SUM; //缓存数量
DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable; //外设地址寄存器不变
DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable; //内存地址寄存器递增
DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_HalfWord; //外设数据宽度为16位
DMA_InitStructure.DMA_MemoryDataSize=DMA_MemoryDataSize_HalfWord; //内存数据宽度为16位
DMA_InitStructure.DMA_Mode=DMA_Mode_Circular; //工作在循环缓存模式
DMA_InitStructure.DMA_Priority=DMA_Priority_High; //DMA通道x拥有高优先级
DMA_InitStructure.DMA_M2M=DMA_M2M_Disable; //DMA通道x没有设置为内存到内存传输
DMA_Init(DMA1_Channel1,&DMA_InitStructure);
DMA_ITConfig(DMA1_Channel1,DMA_IT_TC,ENABLE); //传输完成产生中断 //7.8ms更新
DMA_ClearITPendingBit(DMA1_IT_TC1);
DMA_Cmd(DMA1_Channel1,ENABLE);
}
使用AT32F403A_407_Firmware_Library_CN 中的ADC例程也存在这个问题,只要开DMA重复循环采样就存在这种问题,3个通道采样,只有第一通道给 3V信号,其他通道均接地
static void dma_config(void)
{
dma_init_type dma_init_struct;
crm_periph_clock_enable(CRM_DMA1_PERIPH_CLOCK, TRUE);
nvic_irq_enable(DMA1_Channel1_IRQn, 0, 0);
dma_reset(DMA1_CHANNEL1);
dma_default_para_init(&dma_init_struct);
dma_init_struct.buffer_size = 15;
dma_init_struct.direction = DMA_DIR_PERIPHERAL_TO_MEMORY;
dma_init_struct.memory_base_addr = (uint32_t)adc1_ordinary_valuetab;
dma_init_struct.memory_data_width = DMA_MEMORY_DATA_WIDTH_HALFWORD; //DMA_MEMORY_DATA_WIDTH_WORD;
dma_init_struct.memory_inc_enable = TRUE;
dma_init_struct.peripheral_base_addr = (uint32_t)&(ADC1->odt);
dma_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_WORD;
dma_init_struct.peripheral_inc_enable = FALSE;
dma_init_struct.priority = DMA_PRIORITY_HIGH;
dma_init_struct.loop_mode_enable = TRUE;//FALSE;
dma_init(DMA1_CHANNEL1, &dma_init_struct);
dma_interrupt_enable(DMA1_CHANNEL1, DMA_FDT_INT, TRUE);
dma_channel_enable(DMA1_CHANNEL1, TRUE);
}
/**
* @briefadc configuration.
* @paramnone
* @retval none
*/
static void adc_config(void)
{
adc_base_config_type adc_base_struct;
crm_periph_clock_enable(CRM_ADC1_PERIPH_CLOCK, TRUE);
crm_periph_clock_enable(CRM_ADC2_PERIPH_CLOCK, TRUE);
crm_adc_clock_div_set(CRM_ADC_DIV_6);
/* select combine mode */
adc_combine_mode_select(ADC_INDEPENDENT_MODE);//(ADC_ORDINARY_SMLT_ONLY_MODE);
adc_base_default_para_init(&adc_base_struct);
adc_base_struct.sequence_mode = TRUE;
adc_base_struct.repeat_mode = TRUE; //FALSE;
adc_base_struct.data_align = ADC_RIGHT_ALIGNMENT;
adc_base_struct.ordinary_channel_length = 3;
adc_base_config(ADC1, &adc_base_struct);
adc_ordinary_channel_set(ADC1, ADC_CHANNEL_4, 1, ADC_SAMPLETIME_239_5);
adc_ordinary_channel_set(ADC1, ADC_CHANNEL_5, 2, ADC_SAMPLETIME_239_5);
adc_ordinary_channel_set(ADC1, ADC_CHANNEL_6, 3, ADC_SAMPLETIME_239_5);
adc_ordinary_conversion_trigger_set(ADC1, ADC12_ORDINARY_TRIG_SOFTWARE, TRUE);
adc_dma_mode_enable(ADC1, TRUE);
adc_base_config(ADC2, &adc_base_struct);
adc_ordinary_channel_set(ADC2, ADC_CHANNEL_7, 1, ADC_SAMPLETIME_239_5);
adc_ordinary_channel_set(ADC2, ADC_CHANNEL_8, 2, ADC_SAMPLETIME_239_5);
adc_ordinary_channel_set(ADC2, ADC_CHANNEL_9, 3, ADC_SAMPLETIME_239_5);
adc_ordinary_conversion_trigger_set(ADC2, ADC12_ORDINARY_TRIG_SOFTWARE, TRUE);
adc_enable(ADC1, TRUE);
adc_enable(ADC2, TRUE);
adc_calibration_init(ADC1);
while(adc_calibration_init_status_get(ADC1));
adc_calibration_start(ADC1);
while(adc_calibration_status_get(ADC1));
adc_calibration_init(ADC2);
while(adc_calibration_init_status_get(ADC2));
adc_calibration_start(ADC2);
while(adc_calibration_status_get(ADC2));
} 哪位版主指导下哇 没人回答,我自己想办法解决了,GD的也这样。哎 我在STM32F103上试过多路AD采集的,有你所说的问题,原因是每个通道采样的间隔时间太短了,加长每次采样的间隔时间就问题解决了。 楼主,问题解决了吗?才看到你的问题。以下几个原因是比较容易导致数据偏差的
外部电路不恰当:AT与ST的ADC内部采样电容大小不同,对应的外部电路会存在差异,可以尝试按照DS上面的推荐值,做一个阻抗匹配。
通道充放电时间不充分:适当降低ADC时钟,保持最大采样周期,看看转换结果是否会有改善
供电电源不稳定:检查Vref部分的电路设计,看看是否是因为参考电压不稳定,其跳变同样会导致转换结果的偏差
页:
[1]