历史上的今天
今天是:2025年03月12日(星期三)
2019年03月12日 | STM32F429HAL库ADCDMA学习笔记
2019-03-12 来源:eefocus
做了一个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 { 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有兴趣可以深入理解一下这个函数的用处。我也是简单学习一下就不在深究。到这配置就结束了
下一篇:STM32之端口复用与重映射
史海拾趣
|
我在一个项目设计中用到E2PROM存储,用的是atmel的28c64系列,同样的电路,用28C64可以保存下来上次断电前的输入内容,但是用到26C64B就无法保存,有谁能告诉我这是什么原因不?… 查看全部问答> |
|
快过年了,有些人也走了,公司显得有点冷清。 仔细看过去,研发人员还是一直的忙碌,生产维护的也在埋头苦干,那么那些、财务、行政等后勤人员,都在干什么呢?按理说年底,他们的事情很少,那他们来上班,都在干什么事情?若没事情,还不如让他 ...… 查看全部问答> |
|
Quartus II 9.0中用模块化进行设计,使用ROM做存储器,为什么编译老是在ROM这块出错? Quartus II 9.0中用模块化进行设计,使用ROM做存储器,为什么编译老是在ROM这块出错。我设置的ROM是6位地址输入,24位数据输出,同时还指定好了MIF文件,但是连接好原理图后,编译老是提示与ROM输出的线出错,即Error: Port \"G2AN\" of type 74138 ...… 查看全部问答> |




