sevenwolf 发表于 2022-2-26 22:45

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通道

sevenwolf 发表于 2022-2-27 09:33

版主帮我分析下哇好像是DMA 连续扫描时的相互干扰,都是上一通道影响下一通道。我把Fad降到500K都不行。使用STM32F103就是好的

sevenwolf 发表于 2022-2-27 16:04

各位大佬帮忙看看,到底什么问题。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);
}

sevenwolf 发表于 2022-2-28 09:35

使用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));
}

sevenwolf 发表于 2022-2-28 09:38

sevenwolf 发表于 2022-2-28 09:40

哪位版主指导下哇

sevenwolf 发表于 2022-2-28 15:20

没人回答,我自己想办法解决了,GD的也这样。哎

chehao 发表于 2022-3-2 10:51

我在STM32F103上试过多路AD采集的,有你所说的问题,原因是每个通道采样的间隔时间太短了,加长每次采样的间隔时间就问题解决了。

hoop 发表于 2022-3-3 19:29

楼主,问题解决了吗?才看到你的问题。以下几个原因是比较容易导致数据偏差的
外部电路不恰当:AT与ST的ADC内部采样电容大小不同,对应的外部电路会存在差异,可以尝试按照DS上面的推荐值,做一个阻抗匹配。
通道充放电时间不充分:适当降低ADC时钟,保持最大采样周期,看看转换结果是否会有改善
供电电源不稳定:检查Vref部分的电路设计,看看是否是因为参考电压不稳定,其跳变同样会导致转换结果的偏差
页: [1]
查看完整版本: 403A 替代 STM32F103 问题