STM32F429HAL库ADCDMA学习笔记

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_36305492/article/details/78070514

 昨天做了一个ADC的程序一直想学习一下DMA的配置,我一直也是不懂DMA到底有什么用处,还是感觉很鸡肋。稍微配置了一下,我是这样理解DMA的。在配置了dma之后我们adc的数据不会再由cpu搬运,我们直接读取我们DMA数据是节省adc时间。直接看配置

void MY_ADC_Init(void)

ADC_ChannelConfTypeDef ADC1_ChanConf;

ADC1_Handler.Instance=ADC1;
 ADC1_Handler.Init.ClockPrescaler=ADC_CLOCK_SYNC_PCLK_DIV4;   //4分频,ADCCLK=PCLK2/4=90/4=22.5MHZ
    ADC1_Handler.Init.Resolution=ADC_RESOLUTION_12B;             //12位模式
    ADC1_Handler.Init.DataAlign=ADC_DATAALIGN_RIGHT;             //右对齐
    ADC1_Handler.Init.ScanConvMode=ENABLE;                      //非扫描模式
    ADC1_Handler.Init.EOCSelection=DISABLE;                      //关闭EOC中断
    ADC1_Handler.Init.ContinuousConvMode=ENABLE;                //开启连续转换
    ADC1_Handler.Init.NbrOfConversion=2;                         //2个转换在规则序列中 也就是只转换规则序列2 
    ADC1_Handler.Init.DiscontinuousConvMode=DISABLE;       //禁止不连续采样模式
    ADC1_Handler.Init.NbrOfDiscConversion=0;                     //不连续采样通道数为0
    ADC1_Handler.Init.ExternalTrigConv=ADC_SOFTWARE_START;       //软件触发
    ADC1_Handler.Init.ExternalTrigConvEdge=ADC_EXTERNALTRIGCONVEDGE_NONE;//使用软件触发
    ADC1_Handler.Init.DMAContinuousRequests=ENABLE;             //关闭DMA请求
    HAL_ADC_Init(&ADC1_Handler);                                 //初始化 
   ADC1_ChanConf.Channel= ADC_CHANNEL_5;                                   //通道
    ADC1_ChanConf.Rank=1;                                       //第1个序列,序列1
    ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_480CYCLES;        //采样时间
    ADC1_ChanConf.Offset=0;     /好像没用              
    HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_ChanConf);        //通道配置
 
ADC1_ChanConf.Channel= ADC_CHANNEL_4;                                   //通道
    ADC1_ChanConf.Rank=2;                                       //第1个序列,序列1
    ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_480CYCLES;        //采样时间
    ADC1_ChanConf.Offset=0;    
    HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_ChanConf);

 MY_ADC_DMA_Init(); 
}

__HAL_RCC_DMA2_CLK_ENABLE();

 DMA2_Handler.Instance      =DMA2_Stream0;   //数据流0                
    DMA2_Handler.Init.Channel  =DMA_CHANNEL_0;  //通道0                 
    DMA2_Handler.Init.Direction=DMA_PERIPH_TO_MEMORY; //数据传输方向:外设->内存
    DMA2_Handler.Init.PeriphInc=DMA_PINC_DISABLE;    //外设地址不变           
    DMA2_Handler.Init.MemInc=DMA_MINC_ENABLE;       //内存地址递增              
    DMA2_Handler.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD;//数据半字16位    
    DMA2_Handler.Init.MemDataAlignment=DMA_PDATAALIGN_HALFWORD;  //数据半字16位    
    DMA2_Handler.Init.Mode=DMA_CIRCULAR;  //循环模式                                                                            
    DMA2_Handler.Init.Priority=DMA_PRIORITY_MEDIUM;//DMA传输方式有关数据格式几次传输               
    DMA2_Handler.Init.FIFOMode=DMA_FIFOMODE_DISABLE;              
    DMA2_Handler.Init.FIFOThreshold=DMA_FIFO_THRESHOLD_FULL;     
    DMA2_Handler.Init.MemBurst=DMA_MBURST_SINGLE;                
    DMA2_Handler.Init.PeriphBurst=DMA_PBURST_SINGLE;            
    __HAL_LINKDMA(&ADC1_Handler,DMA_Handle,DMA2_Handler);     
    /* Configure DMA Stream source address */
    DMA2_Handler.Instance->PAR  = (u32)&ADC1->DR; //外设地址
    DMA2_Handler.Instance->M0AR = (vu32)ADC_DMA_ConvertedValue;//内存缓冲地址
    DMA2_Handler.Instance->NDTR =2;//数据长度
    HAL_DMA_Init(&DMA2_Handler);
HAL_DMA_Start (&DMA2_Handler,(u32)&ADC1->DR,(unsigned int)&ADC_DMA_ConvertedValue,2);//开启DMA 

}

基本配置就是这样我们在


void Get_Adc_Average(u16 *temp,u8 times)
{
u32 temp_val[2]={0};
u8 t;
for(t=0;t<times;t++)
{
HAL_ADC_Start_DMA(&ADC1_Handler,(uint32_t*)&ADC_DMA_ConvertedValue,2);
temp_val[0]+=ADC_DMA_ConvertedValue[0];
temp_val[1]+=ADC_DMA_ConvertedValue[1];
delay_ms(5);
}
temp[0]=temp_val[0]/times;
temp[1]=temp_val[1]/times;



void ADC_DMA_Open(void)
{
         //DMA config    
          HAL_ADC_Start(&ADC1_Handler);                               //开启ADC
          MY_ADC_DMA_Init();              
         //ADC
          HAL_ADC_Start_DMA(&ADC1_Handler,(uint32_t*)&ADC_DMA_ConvertedValue,2);        
}

我在采样时取了十次求均值滤波值处理一下好像每次采样都要

HAL_ADC_Start_DMA(&ADC1_Handler,(uint32_t*)&ADC_DMA_ConvertedValue,2);这和先开启否则不会传入DMA有兴趣可以深入理解一下这个函数的用处。我也是简单学习一下就不在深究。到这配置就结束了

ADC/DMA配置:stm32f429xx_hal_adc.h

完整资料我上传到我的资源里欢迎参考修改

 点击打开链接



猜你喜欢

转载自blog.csdn.net/qq_36305492/article/details/78070514