问DMA传输ADC数据不稳定

2019-08-14 14:53发布

话不多说,上代码先。
#include "dma_adc.h"
#include "stm32f10x.h"

void MYDMA_ADC_Config(DMA_Channel_TypeDef* DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)
{
                ADC_InitTypeDef ADC_InitStructure;
        GPIO_InitTypeDef GPIO_InitStructure;
        DMA_InitTypeDef DMA_InitStructure;
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);        //使能DMA传输


       
  DMA_DeInit(DMA_CHx);   //将DMA的通道1寄存器重设为缺省值


        DMA_InitStructure.DMA_PeripheralBaseAddr = cpar;  //DMA外设基地址
        DMA_InitStructure.DMA_MemoryBaseAddr = cmar;  //DMA内存基地址
        DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;  //数据传输方向,从内存读取发送到外设
        DMA_InitStructure.DMA_BufferSize = cndtr;  //DMA通道的DMA缓存的大小
        DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  //外设地址寄存器不变
        DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;  //内存地址寄存器不变
        DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;  //数据宽度
        DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //数据宽度
        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(DMA_CHx, &DMA_InitStructure);  //根据DMA_InitStruct中指定的参数初始化DMA的通道USART1_Tx_DMA_Channel所标识的寄存器
        DMA_Cmd(DMA1_Channel1,ENABLE);
               
               
                RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB |RCC_APB2Periph_ADC1        , ENABLE );          //使能ADC1通道时钟
        RCC_ADCCLKConfig(RCC_PCLK2_Div6);   //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M

        //PA1 作为模拟通道输入引脚                        
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;                //模拟输入引脚
        GPIO_Init(GPIOA, &GPIO_InitStructure);       

        ADC_DeInit(ADC1);  //复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值

        ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;        //ADC工作模式:ADC1和ADC2工作在独立模式
        ADC_InitStructure.ADC_ScanConvMode = DISABLE;        //模数转换工作在单通道模式
        ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;        //模数转换工作在循环转换模式
        ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;        //转换由软件而不是外部触发启动
        ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;        //ADC数据右对齐
        ADC_InitStructure.ADC_NbrOfChannel = 1;        //顺序进行规则转换的ADC通道的数目
        ADC_Init(ADC1, &ADC_InitStructure);        //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器   
  ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_239Cycles5 );
        ADC_DMACmd(ADC1,ENABLE);
         
        ADC_Cmd(ADC1, ENABLE);        //使能指定的ADC1
               
        ADC_ResetCalibration(ADC1);        //使能复位校准  
         
        while(ADC_GetResetCalibrationStatus(ADC1));        //等待复位校准结束
       
        ADC_StartCalibration(ADC1);         //开启AD校准

        while(ADC_GetCalibrationStatus(ADC1));         //等待校准结束
       
       
        ADC_SoftwareStartConvCmd(ADC1, ENABLE);                //使能指定的ADC1的软件转换启动功能
       
       
}



查了些许资料,还是没有解决这个问题,当adc接地,传输adcx,本应该dma传输数据“0”吧,但一直非常不稳定,高的时候能跳变到十几,函数还用到了两个定时器,一个0.1ms一个100ms,不知有没有影响。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
5条回答
正点原子
1楼-- · 2019-08-14 19:51
 精彩回答 2  元偷偷看……
时冢不是泽
2楼-- · 2019-08-15 01:04
正点原子 发表于 2017-8-15 00:40
论坛搜索参考下别人的代码吧

呜...要是能在别人代码里看到解决方案,我就不会提问了。折腾了12小时了。现在感觉是main函数里的显示函数影响的。
wxjhby
3楼-- · 2019-08-15 06:05
只做ADC采集数据是否准确,只做ADC+DMA数据是否准确,如果加上了其他代码数据不准那就能说明是其他影响
meimengxing2014
4楼-- · 2019-08-15 08:41
你只是每次采集一个数据,一般的ADC都会采集一个数组的数据,然后进行滤波,滤波后的数据比较稳定的。你把AD的管脚接地,有十几的数据,这再正常不过了,3.3V对应的是4095,那十几只是对应的0.01V左右的电压,GND有微弱的电压很正常的
13696229579
5楼-- · 2019-08-15 11:20
我看看我的等级

一周热门 更多>