|
请教一下,FM33lC046N开发板,系统时钟64M,设置BSTIM32触发ADC采集,然后经DAM传输到RAM。采集2个通道,一个是参考电压,一个需要采样的ADC输入引脚,定时器设置4S采集一次,采集4次,16S后输出采集信息。不设置DMA时,可以按照定时器间隔采集输出。设置DMA传输后,4S后,就完成所有采样,将所有数据传输,感觉是连续发送了4次DMA请求。手册上32.4.12 DMA 单次模式下会一直重复搬运过程,才会导致DMA会将所有数据传输?
1.这两个函数是定时器和ADC初始化:
void AdcTrigTimerInit(void)
{
//定时器初始化数据结构定义
FL_BSTIM32_InitTypeDef TimerBaseInitStruct;
TimerBaseInitStruct.prescaler = 64000-1;
TimerBaseInitStruct.autoReload = 4000-1;
TimerBaseInitStruct.autoReloadState = FL_ENABLE;
TimerBaseInitStruct.clockSource = FL_RCC_BSTIM32_CLK_SOURCE_APB2CLK;
FL_BSTIM32_Init(BSTIM32,&TimerBaseInitStruct );
FL_BSTIM32_SetTriggerOutput(BSTIM32,FL_BSTIM32_TRGO_UPDATE);
FL_BSTIM32_ClearFlag_Update(BSTIM32);
FL_BSTIM32_Disable(BSTIM32);
}
void AdcInit(void)
{
FL_GPIO_InitTypeDef GPIO_InitStruct;
FL_ADC_CommonInitTypeDef ADC_CommonInitStruct;
FL_ADC_InitTypeDef defaultInitStruct;
FL_NVIC_ConfigTypeDef InterruptConfigStruct;
GPIO_InitStruct.pin = FL_GPIO_PIN_9;
GPIO_InitStruct.mode = FL_GPIO_MODE_ANALOG;
GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.pull = FL_DISABLE;
GPIO_InitStruct.remapPin = FL_DISABLE;
FL_GPIO_Init( GPIOC, &GPIO_InitStruct );
ADC_CommonInitStruct.clockSource =FL_RCC_ADC_CLK_SOURCE_RCHF;
ADC_CommonInitStruct.clockPrescaler = FL_RCC_ADC_PSC_DIV8;
FL_ADC_CommonInit(&ADC_CommonInitStruct);
defaultInitStruct.conversionMode = FL_ADC_CONV_MODE_SINGLE;
defaultInitStruct.autoMode = FL_ADC_SINGLE_CONV_MODE_AUTO;
defaultInitStruct.waitMode = FL_ENABLE;
defaultInitStruct.overrunMode = FL_ENABLE;
defaultInitStruct.scanDirection = FL_ADC_SEQ_SCAN_DIR_BACKWARD;
defaultInitStruct.externalTrigConv = FL_ADC_TRIGGER_EDGE_RISING;
defaultInitStruct.triggerSource = FL_ADC_TRGI_BSTIM1;
defaultInitStruct.fastChannelTime = FL_ADC_FAST_CH_SAMPLING_TIME_256_ADCCLK;
defaultInitStruct.lowChannelTime = FL_ADC_SLOW_CH_SAMPLING_TIME_256_ADCCLK;
defaultInitStruct.oversamplingMode = FL_DISABLE;
defaultInitStruct.overSampingMultiplier = FL_ADC_OVERSAMPLING_MUL_2X;
defaultInitStruct.oversamplingShift = FL_ADC_OVERSAMPLING_SHIFT_1B;
FL_ADC_Init(ADC,&defaultInitStruct );
FL_ADC_SetTriggerSource(ADC,FL_ADC_TRGI_BSTIM1);
FL_ADC_SetTriggerEdge(ADC,FL_ADC_TRIGGER_EDGE_RISING);
FL_ADC_EnableIT_EndOfConversion(ADC);
InterruptConfigStruct.preemptPriority = 0x02;
FL_NVIC_Init(&InterruptConfigStruct,ADC_IRQn );
}
2.这两个是DMA配置的,在需要开始采样的时候调用:
void ADC_DMA(uint16_t *buffer, uint32_t length)
{
FL_DMA_InitTypeDef DMA_InitStruct = {0};
FL_DMA_ConfigTypeDef DMA_ConfigStruct = {0};
DMA_InitStruct.periphAddress = FL_DMA_PERIPHERAL_FUNCTION1;
DMA_InitStruct.direction = FL_DMA_DIR_PERIPHERAL_TO_RAM;
DMA_InitStruct.memoryAddressIncMode = FL_DMA_MEMORY_INC_MODE_INCREASE;
DMA_InitStruct.dataSize = FL_DMA_BANDWIDTH_16B;
DMA_InitStruct.priority = FL_DMA_PRIORITY_HIGH;
DMA_InitStruct.circMode = FL_DISABLE;
FL_DMA_Init(DMA, &DMA_InitStruct, FL_DMA_CHANNEL_4);
DMA_ConfigStruct.memoryAddress = (uint32_t)buffer;
DMA_ConfigStruct.transmissionCount = length - 1;
FL_DMA_StartTransmission(DMA, &DMA_ConfigStruct, FL_DMA_CHANNEL_4);
FL_ADC_SetDMAMode(ADC,FL_ADC_DMA_MODE_SINGLE);
FL_ADC_EnableDMAReq(ADC);
FL_DMA_Enable(DMA);
}
uint16_t DMAResult[4];
void GetDMAChannelSample(uint32_t channel)
{
FL_NVIC_ConfigTypeDef InterruptConfigStruct;
FL_VREF_EnableVREFBuffer(VREF);//使能VREF BUFFER
FL_ADC_DisableSequencerChannel(ADC, FL_ADC_ALL_CHANNEL);//清空打开的通道
FL_ADC_EnableSequencerChannel(ADC, FL_ADC_INTERNAL_VREF1P2);//通道选择VREF
FL_ADC_EnableSequencerChannel(ADC, channel);//通道选择
ADC_DMA(DMAResult, 4);
InterruptConfigStruct.preemptPriority = 0x01;
FL_NVIC_Init(&InterruptConfigStruct,DMA_IRQn );
FL_DMA_EnableIT_TransferComplete(DMA,FL_DMA_CHANNEL_4);
FL_ADC_ClearFlag_EndOfConversion(ADC);//清标志
FL_ADC_Enable(ADC); // 启动ADC
mymemset((u8*)DMAResult,0,4*2);
iCnt =0;
FL_BSTIM32_ClearFlag_Update(BSTIM32);
//使能LGPTIM
FL_BSTIM32_Enable(BSTIM32);
}
3.DMA传输完成中断,传输完了就停止定时器,停止ADC
Y&H Wang:
void DMA_IRQHandler(void)
{
if(FL_DMA_IsEnabledIT_TransferComplete(DMA,FL_DMA_CHANNEL_4) && FL_DMA_IsActiveFlag_TransferComplete(DMA,FL_DMA_CHANNEL_4))
{
FL_DMA_ClearFlag_TransferHalfComplete(DMA,FL_DMA_CHANNEL_4);
FL_DMA_ClearFlag_TransferComplete(DMA, FL_DMA_CHANNEL_4);
FL_BSTIM32_Disable(BSTIM32);
FL_ADC_Disable(ADC); // 关闭ADC
FL_ADC_DisableSequencerChannel(ADC, FL_DMA_CHANNEL_4);//通道关闭
FL_ADC_DisableSequencerChannel(ADC, FL_ADC_INTERNAL_VREF1P2);//通道关闭VREF
FL_VREF_DisableVREFBuffer(VREF);//关闭VREF BUFFER
msg_send_msg(MSG_ADC_DMA,0);
}
}
|
|