STM32F407中ADC1+DMA+USART2的问题。

2019-07-20 14:15发布

本帖最后由 春天里打滚儿 于 2017-5-28 22:55 编辑

小弟用STM32F407VG做单通道ADC的DMA采集与4G传输。从ADC1到存储器用DM2_Stream0,DMA_Channel_0传到变量ADC_ConvertedValue,没有问题。然后想通过4G模块发送出去。本来是可以用另一个DMA数据流直接将数据发送到串口的,但是4G模块一次最多只能传1024字节的数据。且写入速度不能太快,不然数据就会丢失。所以就只好先将采集到的数据通过DMA存储器到存储器的方式将数据保存下来,再每次512字节发送到4G模块。问题就出在从ADC_ConvertedValue到另一个变量的DMA上,数据拷贝不过去。我找了好多例子都没有发现这一块的例程,希望懂行的大佬们指点一下,感激不尽!
下面附上代码和说明:
设置一个定时器开启DMA2_Stream0的半传输完成和全传输完成中断:DMA_ITConfig(DMA2_Stream0,DMA_IT_TC | DMA_IT_HT,ENABLE);

然后配置并开启ADC1->Flash的传输
1、外设到存储器:ADC1->DMA2->Flash
#define LEN_ADC_BUF 20480
u16 ADC_ConvertedValue[LEN_ADC_BUF];
MYDMA_DAQ_Config(DMA2_Stream0,DMA_Channel_0,(u32)&(ADC1->DR),(u32)ADC_ConvertedValue,LEN_ADC_BUF);
函数:
void Adc_Init(void)
{
          GPIO_InitTypeDef      GPIO_InitStructure;        
          ADC_CommonInitTypeDef ADC_CommonInitStructure;
        ADC_InitTypeDef       ADC_InitStructure;
        
          /* Enable peripheral clocks *************************************************/
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
         
        /*Set GPIO*/        
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
        GPIO_Init(GPIOA,&GPIO_InitStructure);

        /*Set ADC1*/
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
        ADC_DeInit();
        
          /* ADC Common Init **********************************************************/
        ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
          ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_20Cycles;
          ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
          ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div8;
          ADC_CommonInit(&ADC_CommonInitStructure);

          /* ADC1 Init ****************************************************************/
          ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
          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(ADC1,&ADC_InitStructure);
        
        /* Enable ADC1 **************************************************************/
        ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 1, ADC_SampleTime_480Cycles);
        ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
        ADC_DMACmd(ADC1, ENABLE);        
         ADC_Cmd(ADC1, ENABLE);
}

void MYDMA_DAQ_Config(DMA_Stream_TypeDef *DMA_Streamx, u32 chx, u32 par, u32 mar, u16 ndtr)
{
        DMA_InitTypeDef  DMA_InitStructure;
        if((u32)DMA_Streamx>(u32)DMA2)
          {
                    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);
         }else  
          {
                    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1,ENABLE);
          }
        DMA_DeInit(DMA_Streamx);
        while (DMA_GetCmdStatus(DMA_Streamx) != DISABLE){}

        DMA_InitStructure.DMA_Channel = chx;
        DMA_InitStructure.DMA_PeripheralBaseAddr = par;
        DMA_InitStructure.DMA_Memory0BaseAddr = mar;
        DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
        DMA_InitStructure.DMA_BufferSize = ndtr;
        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(DMA_Streamx, &DMA_InitStructure);
}

2、存储器到存储器:Flash->DMA2->Flash
当DMA2_Stream0的半传输完成中断发生时,则通过DMA2_Stream7,DMA_Channel_4把ADC_ConvertedValue的前一半数据发送到Signal_HalfBefore;
MYDMA_DTR_Config(DMA2_Stream7,DMA_Channel_4,(u32)Signal_HalfBefore,(u32)&ADC_ConvertedValue[0],LEN_ADC_BUF/2);
当DMA2_Stream0全传输完成中断发生时,则通过DMA2_Stream6,DMA_Channel_5把ADC_ConvertedValue的后一半数据发送到Signal_HalfBehind;
MYDMA_DTR_Config(DMA2_Stream7,DMA_Channel_4,(u32)Signal_HalfBehind,(u32)&ADC_ConvertedValue[0],LEN_ADC_BUF/2);

当传输完成后再关闭DMA2_Stream0的半传输完成中断:DMA_ITConfig(DMA2_Stream0,DMA_IT_TC | DMA_IT_HT,DISABLE);
u8 Signal_HalfBefore[LEN_ADC_BUF];u8 Signal_HalfBehind[LEN_ADC_BUF];
void MYDMA_DTR_Config(DMA_Stream_TypeDef *DMA_Streamx, u32 chx, u32 par, u32 mar, u16 ndtr)
{
        DMA_InitTypeDef  DMA_InitStructure;
        if((u32)DMA_Streamx>(u32)DMA2)
        {
                    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);
        }else  
        {
                    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1,ENABLE);
        }
        DMA_DeInit(DMA_Streamx);
        while (DMA_GetCmdStatus(DMA_Streamx) != DISABLE){}
        DMA_InitStructure.DMA_Channel = chx;
        DMA_InitStructure.DMA_PeripheralBaseAddr = par;
        DMA_InitStructure.DMA_Memory0BaseAddr = mar;
        DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToMemory;
        DMA_InitStructure.DMA_BufferSize = ndtr;
        DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;
        DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
        DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
        DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
        DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
        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(DMA_Streamx, &DMA_InitStructure);
}
这样配置16位数组ADC_ConvertedValue的数据并不能拷贝到Signal_HalfBefore和Signal_HalfBehind两个8位的数组里。不知道有没有人遇到过这样的问题,求指点。



友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
2条回答
正点原子
1楼-- · 2019-07-20 20:05
 精彩回答 2  元偷偷看……
春天里打滚儿
2楼-- · 2019-07-20 21:56
正点原子 发表于 2017-5-29 12:37
帮顶

谢谢原子哥!

一周热门 更多>