案例 stm32单片机,adc的双通道+dma 内部温度
阅读原文时间:2022年01月29日阅读:1

可以这样理解

先配置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);

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章