可以这样理解
先配置adc :有几个通道就配置几个通道.
然后配置dma,dma是针对adc的,而不是针对通道的.
一开始我以为一个adc通道对应一个dma通道.(这里是错的,其实是我想复杂了)
一个adc,对应一个dma.
adc可以开多个通道.比如采集电池的电量是一个通道,采集单片机温度是另一个通道.
adc1的所有通道对应着dma的某一个通道.
然后开启后dma,就会依次把各通道的数据存入数组:
数组元素1: 通道1的数据
数组元素2: 通道2的数据
数组元素3: 通道3的数据
数组元素4: 通道4的数据
数组元素5: 通道5的数据
然后又会从头存,一直循环下去….
这样可以设置成 多维数组
比如 100行 5列的数组
然后dma传输长度设置成500;
这样每个通道的数据,就自动存入 a[100][5] 的数组中,且每一列代表一个通道,可以除以100进行平均
下面给出一个程序:
adc1开启有两个通道,
一个通道用于采集电量.
另一个通道用于采集单片机内部温度.
首先,配置采集电量引脚的:
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
//使用PC0做模拟输入
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC,&GPIO_InitStructure);
然后配置adc,adc中使用了两个通道,一个是采集电量,一个是采集内部温度:
static void ADC_Configuration(void)
{
ADC_InitTypeDef ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
/\* ADC Common Init \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/
ADC\_CommonInitStructure.ADC\_Mode = ADC\_Mode\_Independent; //独立工作模式
ADC\_CommonInitStructure.ADC\_Prescaler = ADC\_Prescaler\_Div2;
ADC\_CommonInitStructure.ADC\_DMAAccessMode = ADC\_DMAAccessMode\_Disabled;
ADC\_CommonInitStructure.ADC\_TwoSamplingDelay = ADC\_TwoSamplingDelay\_5Cycles;
ADC\_CommonInit(&ADC\_CommonInitStructure);
/\* ADC3 Init \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/
ADC\_InitStructure.ADC\_Resolution = ADC\_Resolution\_12b;
ADC\_InitStructure.ADC\_ScanConvMode = ENABLE; //扫描模式
ADC\_InitStructure.ADC\_ContinuousConvMode = ENABLE; //连续转换
ADC\_InitStructure.ADC\_ExternalTrigConvEdge = ADC\_ExternalTrigConvEdge\_None; //由软件触发转换
ADC\_InitStructure.ADC\_ExternalTrigConv = ADC\_ExternalTrigConv\_T1\_CC1; //外部触发源
ADC\_InitStructure.ADC\_DataAlign = ADC\_DataAlign\_Right; //数据右对其
ADC\_InitStructure.ADC\_NbrOfConversion = 2; //转换序列长度 因为有两个通道,这里是2
ADC\_Init(ADC1, &ADC\_InitStructure);
ADC\_TempSensorVrefintCmd(ENABLE); //使能内部温度传感器
//采集电压的通道
ADC\_RegularChannelConfig(ADC1, ADC\_Channel\_10, 1, ADC\_SampleTime\_480Cycles);
//内部温度的通道
ADC\_RegularChannelConfig(ADC1, ADC\_Channel\_16, 2, ADC\_SampleTime\_480Cycles);
/\* Enable DMA request after last transfer (Single-ADC mode) \*/
ADC\_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
/\* Enable ADC1 DMA \*/
ADC\_DMACmd(ADC1, ENABLE);
/\* Enable ADC1 \*/
ADC\_Cmd(ADC1, ENABLE);
ADC\_SoftwareStartConv(ADC1);
}
之后为adc的两个通道,配置一个dma.
ADCConvertedValue这个变量是一个二维数组,代表了两个通道,dma会把数据存入到这里.
/\* Enable DMA2 and GPIO clocks \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/
RCC\_AHB1PeriphClockCmd(RCC\_AHB1Periph\_DMA2, ENABLE);
/\* DMA2 Stream0 channel2 configuration \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/
DMA\_DeInit(DMA2\_Stream4);
DMA\_InitStructure.DMA\_Channel = DMA\_Channel\_0; //DMA通道
DMA\_InitStructure.DMA\_PeripheralBaseAddr = (uint32\_t)ADC1\_DR\_ADDRESS; //外设基地址
DMA\_InitStructure.DMA\_Memory0BaseAddr = (uint32\_t)&ADCConvertedValue; //数据存储区
DMA\_InitStructure.DMA\_DIR = DMA\_DIR\_PeripheralToMemory; //转换方向为外设到存储区
DMA\_InitStructure.DMA\_BufferSize = 200; //转换队列长度
DMA\_InitStructure.DMA\_PeripheralInc = DMA\_PeripheralInc\_Disable; //外设基地址固定不变
DMA\_InitStructure.DMA\_MemoryInc = DMA\_MemoryInc\_Enable; //数据存储区地址不变
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\_InitStructure.DMA\_FIFOMode = DMA\_FIFOMode\_Disable;
DMA\_InitStructure.DMA\_FIFOThreshold = DMA\_FIFOThreshold\_HalfFull;
DMA\_InitStructure.DMA\_MemoryBurst = DMA\_MemoryBurst\_Single;
DMA\_InitStructure.DMA\_PeripheralBurst = DMA\_PeripheralBurst\_Single;
DMA\_Init(DMA2\_Stream4, &DMA\_InitStructure);
DMA\_Cmd(DMA2\_Stream4, ENABLE);
手机扫一扫
移动阅读更方便
你可能感兴趣的文章