本帖最后由 春天里打滚儿 于 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位的数组里。不知道有没有人遇到过这样的问题,求指点。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
谢谢原子哥!
一周热门 更多>