您好!
我一直在尝试通过将 FIFO 读取到 RAM 缓冲区来实现 ADC 读数的 DMA 传输。
我在这方面没有取得任何成功。 请帮帮我。
以下是我尝试用于实现目的的代码。
#define ADC_BUFFER_SIZE 128
#define MY_BUFF_SIZE 64
static uint16_t adc_samples [ADC_BUFFER_SIZE] = {};
static uint16_t my_buff [MY_BUFF_SIZE] = {};
void adc_dma_init(void);
void adc_start_dma_sampling(void);
void adc_dma_reenable(void);
void ADCIntHandler(void);
void main(void)
{
adc_dma_init();
adc_start_dma_sampling();
while(1)
{
// the flag is set in the interrupt handler
if (g_AdcDmaTfrDone)
{
g_AdcDmaTfrDone = false;
memcpy(my_buff, adc_samples, MY_BUFF_SIZE);
sleep(2);
// trigger the next set of adc data transfer
adc_dma_reenable();
}
}
return;
}
void adc_dma_init(void)
{
UDMACC32XX_init();
udma = UDMACC32XX_open();
uDMAChannelAssign(UDMA_CH15_ADC_CH1);
uDMAChannelControlSet(
UDMA_CH15_ADC_CH1|UDMA_PRI_SELECT,
UDMA_SIZE_16|UDMA_SRC_INC_NONE|UDMA_DST_INC_16|UDMA_ARB_1);
uDMAChannelTransferSet(
UDMA_CH15_ADC_CH1|UDMA_PRI_SELECT,
UDMA_MODE_BASIC,
(void*)(ADC_BASE+ADC_O_channel2FIFODATA),
adc_samples,
ADC_BUFFER_SIZE);
uDMAChannelEnable(UDMA_CH15_ADC_CH1);
uDMAEnable();
// Initialize the ADC
ADC_init();
ADC_Params adc_params;
ADC_Params_init(&adc_params);
adc_handle = ADC_open(CONFIG_ADC_0, &adc_params);
}
void adc_start_dma_sampling(void)
{
ADCChannelDisable(ADC_BASE, ADC_CH_1);
ADCDMAEnable(ADC_BASE, ADC_CH_1);
ADCIntRegister(ADC_BASE, ADC_CH_1, ADCIntHandler);
ADCIntClear(ADC_BASE, ADC_CH_1, ADC_DMA_DONE);
ADCIntEnable(ADC_BASE, ADC_CH_1, ADC_DMA_DONE);
ADCChannelEnable(ADC_BASE, ADC_CH_1);
uDMAChannelRequest(UDMA_CH15_ADC_CH1);
ADCEnable(ADC_BASE);
}
void adc_dma_reenable(void)
{
ADCIntEnable(ADC_BASE, ADC_CH_1, ADC_DMA_DONE);
uDMAChannelEnable(UDMA_CH15_ADC_CH1);
uDMAChannelRequest(UDMA_CH15_ADC_CH1);
ADCEnable(ADC_BASE);
}
void ADCIntHandler(void)
{
uint32_t ui32Mode;
uint32_t ui32Stat;
ui32Stat = ADCIntStatus(ADC_BASE, ADC_CH_1);
ADCIntClear(ADC_BASE, ADC_CH_1, ui32Stat);
ui32Mode = uDMAChannelModeGet(UDMA_CH15_ADC_CH1|UDMA_PRI_SELECT);
if(!uDMAChannelIsEnabled(UDMA_CH15_ADC_CH1))
{
// Turn off ADC and clear IRQ-Bit
ADCDisable(ADC_BASE);
ADCIntClear(ADC_BASE, ADC_CH_1, ADC_DMA_DONE);
ADCIntDisable(ADC_BASE, ADC_CH_1, ADC_DMA_DONE);
uDMAChannelTransferSet(
UDMA_CH15_ADC_CH1|UDMA_PRI_SELECT,
UDMA_MODE_BASIC,
(void*)(ADC_BASE+ADC_O_channel2FIFODATA),
adc_samples,
ADC_BUFFER_SIZE);
uDMAChannelEnable(UDMA_CH15_ADC_CH1);
g_AdcDmaTfrDone = true;
}
}
谢谢。
瓦萨夫