ADC采集数据,DMA传输,存储1024个数据后进行运算,运算结束后,怎样才能重新启动DMA呢???这是ADC和DMA的配置。。。
[mw_shl_code=c,true]/* Includes ------------------------------------------------------------------*/
#include "includes.h"
#include "ADC.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define ADC_CONV_COUNT 2048 //???? ADC_CONV_COUNT=64?,adc_value_final=sum>>6,???????????
#define IF1 ADC_Channel_10
#define IF2 ADC_Channel_11
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
__IO uint32_t adc_value[ADC_CONV_COUNT]; //__IO:volatile 静态作用就是指示编译器不要因优化而省略此指令,必须每次都直接读写其值。
/* Private function prototypes -----------------------------------------------*/
void ADC_Configuration(void)
{
/*双 ADC 常规同步模式*/
/*双 ADC 常规同步模式用于同时执行两个转换,以实现 ADC1 与 ADC2 的同步。每个 ADC
转换一个通道序列(已使能扫描并配置每个 ADC 的定序器)或者转换单个通道(已禁止扫
描)。可以从外部触发或通过软件启动转换。在多重 ADC 模式下,可在多模式数据寄存器
(ADC_CDR) 中读取转换的数据。可在多模式状态寄存器 (ADC_CSR) 中读取状态位*/
ADC_InitTypeDef ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
DMA_InitTypeDef DMA_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable ADCx, DMA and GPIO clocks ****************************************/
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE);
/* Configure ADC1 Channel pin as analog input ******************************/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 |GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIOC, &GPIO_InitStructure);
/* DMA2 Stream0 channel0 configuration **************************************/
DMA_DeInit(DMA2_Stream0);
while (DMA_GetCmdStatus(DMA2_Stream0)!= DISABLE){} //等待DMA可配置
DMA_InitStructure.DMA_Channel = DMA_Channel_0; //通道选择
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC->CDR; //DMA外设地址
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)adc_value; //DMA存储器0地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; //外设到存储器模式
DMA_InitStructure.DMA_BufferSize = ADC_CONV_COUNT; //数据传输量
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设非增量模式
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //存储器增量模式
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; //外设数据长度:32位
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; //存储器数据长度:32位
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; // 使用普通模式 DMA传输完1024个采样点(高16位为ADC2-IF2,低16位为ADC1-IF1)则不再进行DMA操作,需要手动从新开启
DMA_InitStructure.DMA_Priority = DMA_Priority_High; //高等优先级
/*可能需要FIFO拆包处理*/ DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; //失能FIFO
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; //选择FIFO阈值
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; //存储器突发单次传输
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; //外设突发单次传输
DMA_Init(DMA2_Stream0, &DMA_InitStructure); //初始化DMA Stream
DMA_Cmd(DMA2_Stream0, ENABLE); //使能DMA Stream
/* ADC Common Init **********************************************************/
/*设置ADC的通用控制寄存器CCR,配置ADC输入时钟分频,模式等*/
/*ADC_DMAAccessMode::DMA 模式 1 : 每发出一个 DMA 请求(一个数据项可用),就会传输一个表示 ADC转换的数据项的半字。
在双重 ADC 模式下,发出第一个请求时传输 ADC1 的数据,发出第二个请求时传输 ADC2 的数据,依次类推。
DMA 模式 2:每发送一个 DMA 请求(两个数据项可用),就会以字的形式传输表示两个 ADC 转换数据项的两个半字。
在双重 ADC 模式下,发出第一个请求时会传输 ADC2 和 ADC1 的数据( ADC2 数据占用高位半字, ADC1 数据占用低位半字),依此类推。*/
/*Tconv = 采样周期 + 12 个周期
示例:ADCCLK = 30 MHz 且采样时间 = 3 个周期时:
Tconv = 3 + 12 = 15 个周期 = 15/ADCCLK = 0.5 μs( APB2 为 60 MHz 时)*/
ADC_CommonInitStructure.ADC_Mode = ADC_DualMode_RegSimult;//双通道常规同步模式
// ADC_CommonInitStructure.ADC_TwoSamplingDelay =ADC_TwoSamplingDelay_5Cycles;//双重 /三重交替模式下可配置的转换间延迟 两次采样间隔为5个ADCCLK周期
ADC_CommonInitStructure.ADC_DMAAccessMode =ADC_DMAAccessMode_1;//ADC_DMA数据传输模式
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div8;//ADCCLK=PCLK2/8=84/8=10.5Mhz,ADCCLK<30Mhz稳定
ADC_CommonInit(&ADC_CommonInitStructure);
/* ADC1 configuration ------------------------------------------------------*/
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; //12位模式
ADC_InitStructure.ADC_ScanConvMode = DISABLE; //非扫描模式
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //开启连续转换
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; //禁止触发检测,使用软件触发
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //右对齐
ADC_InitStructure.ADC_NbrOfConversion = 1; //1个转换在规则序列中
ADC_Init(ADC1, &ADC_InitStructure); //ADC1初始化
/* ADC1 regular channel configuration *************************************/
ADC_RegularChannelConfig(ADC1, IF1 , 1, ADC_SampleTime_480Cycles); //Tcovn=????+12???
/* Enable ADC1 DMA */
ADC_DMACmd(ADC1, ENABLE);
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
/* ADC2的开启有ADC1来控制*/
/* ADC2 configuration ------------------------------------------------------*/
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; //12位模式
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 1;
ADC_Init(ADC2, &ADC_InitStructure);
/* ADC2 regular channels configuration */
ADC_RegularChannelConfig(ADC2, IF2 , 1, ADC_SampleTime_480Cycles); //Tcovn=480+12=500(T)
// /* Enable ADC2 external trigger conversion */
// ADC_ExternalTrigConvCmd(ADC2, ENABLE);
/* Enable ADC2 */
ADC_Cmd(ADC2, ENABLE);
// while (ADC_GetCmdStatus(DMA2_Stream0)!= DISABLE){} //等待DMA可配置
/* Start ADC Software Conversion */
ADC_SoftwareStartConv(ADC1); //此时同步开启ADC1和ADC2
}
[/mw_shl_code]
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
一周热门 更多>