DMA传输可以提高程序运行效率,ADC多通道采样,通过DMA将采样结果传输至数组中,是较常见的一个应用。可以分为以下几个步骤来实现配置:1、配置GPIO,将GPIO配置成模拟模式;2、配置ADC的工作模式及ADC采样通道(某个I/O对应的ADC通道可以通过数据手册查看);3、配置DMA的工作模式及DMA的通道(具体是哪个DMA通道可以用来传输ADC的数据可以通过应用手册DMA章节查看)。参考代码如下:
GPIO_Config_T gpioConfig;
ADC_Config_T adcConfig;/** RCM Enable*/
RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_GPIOA);//使能时钟
RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_ADC1);
RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_SYSCFG);
/** GPIO Configuration */
gpioConfig.pin = GPIO_PIN_0;//AIN0
gpioConfig.mode = GPIO_MODE_AN;
gpioConfig.pupd = GPIO_PUPD_PU;
GPIO_Config(GPIOA, &gpioConfig);
gpioConfig.pin = GPIO_PIN_1;
GPIO_Config(GPIOA, &gpioConfig);//AIN1
gpioConfig.pin = GPIO_PIN_4;
GPIO_Config(GPIOA, &gpioConfig);//AIN4
/** ADC Configuration */
ADC_Reset();
ADC_ConfigStructInit(&adcConfig);
/** Set resolution*/
adcConfig.resolution = ADC_RESOLUTION_12B;
/** Set dataAlign*/
adcConfig.dataAlign = ADC_DATA_ALIGN_RIGHT;
/** Set scanDir*/
adcConfig.scanDir = ADC_SCAN_DIR_UPWARD;//由低通到向高通道扫描,即先采样低通道
/** Set convMode continous*/
adcConfig.convMode = ADC_CONVERSION_CONTINUOUS;//连续转换模式,启动后会一直自动转换
/** Set extTrigConv*/
adcConfig.extTrigConv = ADC_EXT_TRIG_CONV_TRG0;
/** Set TrigEdge*/
adcConfig.extTrigEdge = ADC_EXT_TRIG_EDGE_NONE;
ADC_Config(&adcConfig);
ADC_ConfigChannel(ADC_CHANNEL_0, ADC_SAMPLE_TIME_239_5);//PA0脚是ADC通道0
ADC_ConfigChannel(ADC_CHANNEL_1, ADC_SAMPLE_TIME_239_5);//PA1脚是ADC通道1
ADC_ConfigChannel(ADC_CHANNEL_4, ADC_SAMPLE_TIME_239_5);//PA4脚是ADC通道4
/** Calibration*/
ADC_ReadCalibrationFactor();
ADC_EnableDMA();
/** Enable ADC*/
ADC_DMARequestMode(ADC_DMA_MODE_CIRCULAR);//DMA一直传输
ADC_Enable();
/** Enable DMA clock */
RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_DMA1);
/** DMA Configure */
DMA_Config_T dmaConfig;
/** size of buffer*/
dmaConfig.bufferSize = 3;//3个ADC通道的值分别放在数组中的0、1、2三个单元
/** set memory Data Size*/
dmaConfig.memoryDataSize = DMA_MEMORY_DATASIZE_HALFWORD;
/** Set peripheral Data Size*/
dmaConfig.peripheralDataSize = DMA_PERIPHERAL_DATASIZE_HALFWORD;
/** Enable Memory Address increase*/
dmaConfig.memoryInc = DMA_MEMORY_INC_ENABLE;//存储数据的地址要加
/** Disable Peripheral Address increase*/
dmaConfig.peripheralInc = DMA_PERIPHERAL_INC_DISABLE;
/** Reset Circular Mode*/
dmaConfig.circular = DMA_CIRCULAR_ENABLE;
/** Disable M2M*/
dmaConfig.memoryTomemory = DMA_M2M_DISABLE;
/** set priority*/
dmaConfig.priority = DMA_PRIORITY_LEVEL_HIGHT;
/** read from peripheral*/
dmaConfig.direction = DMA_DIR_PERIPHERAL;
/** Set memory Address*/
dmaConfig.memoryAddress = (uint32_t)Buf;//数组首地址
/** Set Peripheral Address*/
dmaConfig.peripheralAddress = (uint32_t)&ADC->DATA;
DMA_Config(DMA1_CHANNEL_1,&dmaConfig);
/** Clear DMA TF flag*/
DMA_ClearIntFlag(DMA1_INT_FLAG_TF1);
/** Enable DMA Interrupt*/
DMA_EnableInterrupt(DMA1_CHANNEL_1,DMA_INT_TFIE);
NVIC_EnableIRQRequest(DMA1_CH1_IRQn,2);
DMA_Enable(DMA1_CHANNEL_1);
|