DMA如何重启呢???

2019-07-21 03:18发布

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]
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。