DMA方式读取多通道ADC采样值
1 ADC配置
打开扫描模式,配置通道个数,打开连续模式,打开DMAContinuousRequests。
2 DMA配置
选择DMA2,Stream0,Channel0,方向外设到内存,外设不自增,内存自增,DMA循环模式。
3 连接ADC和DMA
/*ADC1与DMA2连接*/
__HAL_LINKDMA(&h_ADC1,DMA_Handle,h_DMA2_ADC1);
//h_ADC1.DMA_Handle = &h_DMA2_ADC1;
//h_DMA2_ADC1.Parent = &h_ADC1;
4 启动DMA和ADC
↓↓↓配置ADC和DMA代码
#include "main.h"
#include "ADC.h"
#include "DMA.h"
/*ADC1句柄*/
ADC_HandleTypeDef h_ADC1;
/*ADC通道配置结构体*/
ADC_ChannelConfTypeDef h_ADC1_Channel_Init;
/*DMA2句柄*/
DMA_HandleTypeDef h_DMA2_ADC1;
/*存储DMA取ADC1值*/
uint16_t ADC1_DMA_Buffer[4];
/*配置ADC1和DMA2*/
void ADC1_Init(void)
{
/*ADC1配置*/
__HAL_RCC_ADC1_CLK_ENABLE();
h_ADC1.Instance = ADC1;
h_ADC1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV8;
h_ADC1.Init.Resolution = ADC_RESOLUTION_12B;
h_ADC1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
h_ADC1.Init.ScanConvMode = ENABLE;
h_ADC1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
h_ADC1.Init.ContinuousConvMode = ENABLE;
h_ADC1.Init.NbrOfConversion = 4;
h_ADC1.Init.DiscontinuousConvMode = DISABLE;
h_ADC1.Init.NbrOfDiscConversion = 0;
h_ADC1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
h_ADC1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
h_ADC1.Init.DMAContinuousRequests = ENABLE;
HAL_ADC_Init(&h_ADC1);
/*ADC1通道配置*/
h_ADC1_Channel_Init.Channel = ADC_CHANNEL_1;
h_ADC1_Channel_Init.Rank = 1;
h_ADC1_Channel_Init.SamplingTime = ADC_SAMPLETIME_480CYCLES;
HAL_ADC_ConfigChannel(&h_ADC1,&h_ADC1_Channel_Init);
h_ADC1_Channel_Init.Channel = ADC_CHANNEL_2;
h_ADC1_Channel_Init.Rank = 2;
h_ADC1_Channel_Init.SamplingTime = ADC_SAMPLETIME_480CYCLES;
HAL_ADC_ConfigChannel(&h_ADC1,&h_ADC1_Channel_Init);
h_ADC1_Channel_Init.Channel = ADC_CHANNEL_4;
h_ADC1_Channel_Init.Rank = 3;
h_ADC1_Channel_Init.SamplingTime = ADC_SAMPLETIME_480CYCLES;
HAL_ADC_ConfigChannel(&h_ADC1,&h_ADC1_Channel_Init);
h_ADC1_Channel_Init.Channel = ADC_CHANNEL_6;
h_ADC1_Channel_Init.Rank = 4;
h_ADC1_Channel_Init.SamplingTime = ADC_SAMPLETIME_480CYCLES;
HAL_ADC_ConfigChannel(&h_ADC1,&h_ADC1_Channel_Init);
/*ADC1通道引脚配置*/
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitTypeDef GPIO_Init;
GPIO_Init.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_6;
GPIO_Init.Mode = GPIO_MODE_ANALOG;
GPIO_Init.Pull = GPIO_NOPULL;
GPIO_Init.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(GPIOA,&GPIO_Init);
/*DMA2配置*/
__HAL_RCC_DMA2_CLK_ENABLE();
h_DMA2_ADC1.Instance = DMA2_Stream0;
h_DMA2_ADC1.Init.Channel = DMA_CHANNEL_0;
h_DMA2_ADC1.Init.Direction = DMA_PERIPH_TO_MEMORY;
h_DMA2_ADC1.Init.PeriphInc = DMA_PINC_DISABLE;
h_DMA2_ADC1.Init.MemInc = DMA_MINC_ENABLE;
h_DMA2_ADC1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
h_DMA2_ADC1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
h_DMA2_ADC1.Init.Mode = DMA_CIRCULAR;
h_DMA2_ADC1.Init.Priority = DMA_PRIORITY_HIGH;
h_DMA2_ADC1.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
h_DMA2_ADC1.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_1QUARTERFULL;
h_DMA2_ADC1.Init.MemBurst = DMA_MBURST_SINGLE;
h_DMA2_ADC1.Init.PeriphBurst = DMA_PBURST_SINGLE;
HAL_DMA_Init(&h_DMA2_ADC1);
/*ADC1与DMA2连接*/
//__HAL_LINKDMA(&h_ADC1,DMA_Handle,h_DMA2_ADC1);
h_ADC1.DMA_Handle = &h_DMA2_ADC1;
h_DMA2_ADC1.Parent = &h_ADC1;
}
/*轮询模式启动ADC1*/
uint32_t ADC1_Start_GetValue(void)
{
HAL_ADC_Start(&h_ADC1);
HAL_ADC_PollForConversion(&h_ADC1,20);
return HAL_ADC_GetValue(&h_ADC1);
}
/*DMA模式启动ADC1*/
void ADC1_Start_DMA2(void)
{
HAL_DMA_Start(&h_DMA2_ADC1,(uint32_t)&h_ADC1.Instance->DR,(uint32_t)ADC1_DMA_Buffer,4);
HAL_ADC_Start_DMA(&h_ADC1,(uint32_t *)ADC1_DMA_Buffer, 4);
}
↓↓↓DMA获取结果
printf("ADCCH1=%f\n",((float)ADC1_DMA_Buffer[0])/4096);
printf("ADCCH2=%f\n",((float)ADC1_DMA_Buffer[1])/4096);
printf("ADCCH3=%f\n",((float)ADC1_DMA_Buffer[2])/4096);
printf("ADCCH4=%f\n",((float)ADC1_DMA_Buffer[3])/4096);