打印
[AT32F403/403A]

403A 替代 STM32F103 问题

[复制链接]
1047|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 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输入/////////////////
PA2  ADCIN1         REF   2.5V
PA3  ADCIN2         TEMP
PA4  ADCIN4         AN1
PA5  ADCIN5         AN2
PA6  ADCIN6         AN3
PA7  ADCIN7         AN4
PC4  ADCIN14        AN5
PC5  ADCIN15        AN6
PB0  ADCIN8                      AN7                               
PB1  ADCIN9         AN8
*/

//  ADC_SampleTime_239Cycles5  239.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);
}

/**
  * @brief  adc configuration.
  * @param  none
  * @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));
}

使用特权

评论回复
5
sevenwolf|  楼主 | 2022-2-28 09:38 | 只看该作者

使用特权

评论回复
6
sevenwolf|  楼主 | 2022-2-28 09:40 | 只看该作者
哪位版主指导下哇

使用特权

评论回复
7
sevenwolf|  楼主 | 2022-2-28 15:20 | 只看该作者
没人回答,我自己想办法解决了,GD的也这样。哎

使用特权

评论回复
8
chehao| | 2022-3-2 10:51 | 只看该作者
我在STM32F103上试过多路AD采集的,有你所说的问题,原因是每个通道采样的间隔时间太短了,加长每次采样的间隔时间就问题解决了。

使用特权

评论回复
9
hoop| | 2022-3-3 19:29 | 只看该作者
楼主,问题解决了吗?才看到你的问题。以下几个原因是比较容易导致数据偏差的
外部电路不恰当:AT与ST的ADC内部采样电容大小不同,对应的外部电路会存在差异,可以尝试按照DS上面的推荐值,做一个阻抗匹配。
通道充放电时间不充分:适当降低ADC时钟,保持最大采样周期,看看转换结果是否会有改善
供电电源不稳定:检查Vref部分的电路设计,看看是否是因为参考电压不稳定,其跳变同样会导致转换结果的偏差

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

17

主题

72

帖子

1

粉丝