打印
[应用相关]

STM32F429HAL库ADCDMA学习笔记

[复制链接]
4224|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
磨砂|  楼主 | 2018-11-13 11:53 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
昨天做了一个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有兴趣可以深入理解一下这个函数的用处。我也是简单学习一下就不在深究。到这配置就结束了


沙发
mmuuss586| | 2018-12-23 17:52 | 只看该作者
感谢分享

使用特权

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

本版积分规则

85

主题

3886

帖子

2

粉丝