STM32F4 DMA+多通道ADC[STM32F4 DMA ADC]


前言

记录STM32F407 DMA+多路ADC配置


一、DMA简介

F4系列有2个DMA控制器,16路数据流(每个DMA占8个),每个数据流有8个通道(请求)。

1. DMA映射

根据功能外设选择对应DMA请求映射

MDA1

DMA2

2. DMA配置

可能的DMA配置

二、代码

1.源文件

void adc_dma_init(void)
{
	ADCInit_GPIO();
	ADCInit_ADC();
	ADCInit_DMA();
	
	ADC_SoftwareStartConv(ADC1);  /*启动软件转换*/
}

1 GPIO配置:模拟输入+不上拉

//
static void ADCInit_GPIO(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;
	
	RCC_AHB1PeriphClockCmd(ALL_GPIO_CLK, ENABLE);        //使能GPIO时钟
//CHANNEL1
    GPIO_InitStructure.GPIO_Pin = TEMP_CHANNEL_1_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;          //模拟输入
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;      //不带上下拉
    GPIO_Init(TEMP_CHANNEL_1_GPIO, &GPIO_InitStructure);  //初始化
	
//CHANNEL2
    GPIO_InitStructure.GPIO_Pin = TEMP_CHANNEL_2_PIN;
    GPIO_Init(TEMP_CHANNEL_2_GPIO, &GPIO_InitStructure);
}

2 ADC配置

static void ADCInit_ADC(void)
{
    ADC_CommonInitTypeDef ADC_CommonInitStructure;
    ADC_InitTypeDef       ADC_InitStructure;
    
	RCC_APB2PeriphClockCmd(ALL_ADC_CLK, ENABLE); //使能ADC时钟

    RCC_APB2PeriphResetCmd(ALL_ADC_CLK,ENABLE);  //ADC复位
    RCC_APB2PeriphResetCmd(ALL_ADC_CLK,DISABLE); //复位结束

    ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;  //独立模式
    ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; //两个采样阶段之间的延迟5个时钟(三重模式或双重模式下使用)
    ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; //DMA失能(对于多个ADC模式)
    ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;  //预分频4分频。ADCCLK=PCLK2/4=84/4=21Mhz,ADC时钟最好不要超过36Mhz 
    ADC_CommonInit(&ADC_CommonInitStructure);//初始化
    
    ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;//12位模式
    ADC_InitStructure.ADC_ScanConvMode = ENABLE;//扫描模式(多通道ADC采集要用扫描模式)    
    ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//连续转换
    ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; //软件触发
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//右对齐    
    ADC_InitStructure.ADC_NbrOfConversion = ADC_CHANNEL;    //x个转换在规则序列中
    ADC_Init(ADC1, &ADC_InitStructure);      //ADC初始化
    
    //连续模式下,通道的配置
    ADC_RegularChannelConfig(TEMP_CHANNEL_1_ADCx, TEMP_CHANNEL_1_ADC_CHLx, 1, ADC_SampleTime_15Cycles); 
    ADC_RegularChannelConfig(TEMP_CHANNEL_2_ADCx, TEMP_CHANNEL_2_ADC_CHLx, 2, ADC_SampleTime_15Cycles);
    
    ADC_Cmd(ADC1, ENABLE);//开启AD转换器
    ADC_DMACmd(ADC1, ENABLE);  //使能ADC_DMA
	ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE); //连续使能DMA
	
}

这里针对配置代码做下记录说明:

  1. ADC_ScanConvMode
    扫描模式:
    多通道 --> 扫描 ENABLE
    单通道 --> 单模式 DISABLE

  2. ADC_ContinuousConvMode
    连续转换:
    DMA:ENABLE
    不使用DMA:DISABLE

  3. ADC_NbrOfConversion
    规则通道转换数:即多少路ADC

3 DMA配置

static void ADCInit_DMA(void)
{
    DMA_InitTypeDef  DMA_InitStructure;
    
    //时钟
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
    
    //DMA设置
    DMA_InitStructure.DMA_Channel = DMA_Channel_0; //选择通道号
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR; //外围设备地址,ADC_DR_DATA规则数据寄存器 ADC1_BASE+0x4C 偏移4C对应规则寄存器
    DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)(u16 *)uAD_Buff; //DMA存储器地址,自己设置的缓存地址
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; //传输方向,外设->存储器
    DMA_InitStructure.DMA_BufferSize = ADC_CHANNEL; //DMA缓存大小,数据传输量32*8
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设是否为增量模式
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //存储器是否为增量模式
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //外设数据长度半个字(16位)
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //存储器数据长度半字(16位)
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //DMA模式,普通模式、循环模式,还有双缓冲模式,需要特殊设置
    DMA_InitStructure.DMA_Priority = DMA_Priority_High; //DMA优先级,高优先级
    DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; //不使用FIFO
    DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; //FIFO阈值
    DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; //存储器突发,单次传输
    DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; //外设突发,单次传输
    DMA_Init(DMA2_Stream0, &DMA_InitStructure); //初始化DMA2_Stream0
    
    //设置DMA中断                                
    DMA_Cmd(DMA2_Stream0, ENABLE); //使能DMA

}

这里针对配置代码做下记录说明:

  1. DMA_Channel
    DMA通道选择根据DMA请求映射表
    这里的ADC1对应DMA2通道0的数据流0 or 4

  2. DMA_PeripheralBaseAddr
    外设基地址
    ADC值取值为ADC的规则寄存器(DR),两种表达方式
    1 (uint32_t)&ADC1->DR, 2 ADC1_BASE+0x4C

  3. DMA_Memory0BaseAddr
    存储器的基地址:即变量地址

  4. DMA_PeripheralInc
    外设增量模式:需要外设地址自增的就使能,这里只需从DR寄存器取值,所以不自增

  5. DMA_MemoryInc
    内存增量模式:
    若是单变量就不自增,若是存储在数组,一般设置为自增模式

  6. DMA_Mode
    DMA模式
    循环模式:不停地将数据从外设搬到存储器

2.头文件

代码如下(示例):

#ifndef __BSP_ADC_H_
#define __BSP_ADC_H_

#include "sys.h"

/* PIN DEFINE BEGIN*/
#define  ADC_CHANNEL                        2

#define  TEMP_CHANNEL_1_GPIO_CLK            RCC_AHB1Periph_GPIOA
#define  TEMP_CHANNEL_1_ADC_CLK             RCC_APB2Periph_ADC1
#define  TEMP_CHANNEL_1_ADCx                ADC1
#define  TEMP_CHANNEL_1_GPIO                GPIOA
#define  TEMP_CHANNEL_1_PIN                 GPIO_Pin_2
#define  TEMP_CHANNEL_1_ADC_CHLx            ADC_Channel_2

#define  TEMP_CHANNEL_2_GPIO_CLK            RCC_AHB1Periph_GPIOA
#define  TEMP_CHANNEL_2_ADC_CLK             RCC_APB2Periph_ADC1
#define  TEMP_CHANNEL_2_ADCx                ADC1
#define  TEMP_CHANNEL_2_GPIO                GPIOA
#define  TEMP_CHANNEL_2_PIN                 GPIO_Pin_3
#define  TEMP_CHANNEL_2_ADC_CHLx            ADC_Channel_3
	
#define  ALL_GPIO_CLK     TEMP_CHANNEL_1_GPIO_CLK | TEMP_CHANNEL_2_GPIO_CLK
#define  ALL_ADC_CLK      TEMP_CHANNEL_1_ADC_CLK | TEMP_CHANNEL_2_ADC_CLK 
						
/* PIN DEFINE END*/


void adc_dma_init(void);

总结

STM32F407 DMA+多路ADC初始化笔记

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值