工具/软件:Code Composer Studio
**编辑**请参阅页面底部的工作示例
您好!
我正在尝试使用 修改 后的 UDMA_DEMO 通过 ADC 学习 DMA。 但我对如何完成读数感到有点困惑、并在将 ADC 缓冲区大小设置为2时遇到一些问题。
#include "config/config.h"
#pragma DATA_ALIGN (dmaControlTable、1024)
uint8_t dmaControlTable[1024];
#define MEM_buffer_size 8
静态 uint16_t g_adcBufA[MEM_buffer_size];
静态 uint16_t g_adcBufB[MEM_buffer_size];
静态 uint32_t g_uDMAErrCount;
void CONFIG_ADC0DMA (void)
{
ROM_GPIOPinTypeADC (GPIO_PORTK_base、GPIO_PIN_0 | GPIO_PIN_1);
ROM_ADCSequenceConfigure (ADC0_BASE、1、ADC_TRIGGER_Always、0);
ROM_ADCSequenceStepConfigure (ADC0_BASE、1、0、ADC_CTL_CH16);
ROM_ADCSequenceStepConfigure (ADC0_BASE、1、1、ADC_CTL_CH17 | ADC_CTL_IE | ADC_CTL_END);
//(320MHz PLL/2)/ 5 = 32MHz = 2MSPS
ADCClockConfigSet (ADC0_BASE、ADC_CLOCK_SRC_PLL | ADC_CLOCK_RATE_FULL、5);
//rom_ADCHardwareOversampleConfigure (ADC0_BASE、64);
ROM_ADCSequenceEnable (ADC0_BASE、1);
ROM_ADCSequenceDMAEnable (ADC0_BASE、1);
ROM_uDMAChannelAttributeDisable (UDMA_CHANGE_ADC1、
UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |
UDMA_ATTR_HIGH_PRIOR|
UDMA_ATTR_REQMASK);
ROM_uDMAChannelAttributeEnable (UDMA_CHANGE_ADC1、UDMA_ATTR_USEBURST);
ROM_uDMAChannelControlSet (UDMA_CHANGE_ADC1 | UDMA_PRI_SELECT、
UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 |
UDMA_ARB_1);
ROM_uDMAChannelControlSet (UDMA_CHANGE_ADC1 | UDMA_ALT_SELECT、
UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 |
UDMA_ARB_1);
ROM_uDMAChannelTransferSet (UDMA_CHANGE_ADC1 | UDMA_PRI_SELECT、
UDMA_MODE_PINGONG、
(void *)(ADC0_BASE + ADC_O_SSFIFO1)、
G_adcBufA、MEM_buffer_size);
ROM_uDMAChannelTransferSet (UDMA_CHANGE_ADC1 | UDMA_ALT_SELECT、
UDMA_MODE_PINGONG、
(void *)(ADC0_BASE + ADC_O_SSFIFO1)、
G_adcBufB、MEM_buffer_size);
ROM_uDMAChannelEnable (UDMA_CHANGE_ADC1);
ROM_ADCIntEnableEx (ADC0_BASE、ADC_INT_DMA_SS1);
ROM_IntEnable (INT_ADC0SS1);
}
int main (void)
{
uint32_t g_cpuFrequency = SysCtlClockFreqSet ((SYSCTL_XTAL_25MHz | SYSCTL_OSC_MAIN |
SYSCTL_USE_PLL | SYSCTL_CFG_VCO_320)、120000000);
ROM_FPUEnable();
ROM_FPULazyStackingEnable();
ROM_IntMasterDisable();
initPeripheral();
CONFIG_UART2 (921600、g_cpuFrequency);
UARTprintf ("\033[2J\033[H");
ROM_IntEnable (INT_UDMAERR);
ROM_uDMAEnable();
ROM_uDMAControlBaseSet (dmaControlTable);
CONFIG_ADC0DMA();
ROM_IntMasterEnable();
for (;;)
{
UARTprintf ("ADC 读数 A:%u %u %u %u %u %u %u %u 错误计数:%u\n"、g_adcBufA[0]、g_adcBufA[1]、
G_adcBufA[2]、g_adcBufA[3]、g_adcBufA[4]、g_adcBufA[5]、g_adcBufA[6]、 G_adcBufA[7]、g_uDMAErrCount);
UARTprintf ("ADC 读数 B:%u %u %u %u %u %u %u %u 错误计数:%u\n"、g_adcBufB[0]、g_adcBufB[1]、
G_adcBufB[2]、g_adcBufB[3]、g_adcBufB[4]、g_adcBufB[5]、g_adcBufB[6]、 G_adcBufB[7]、g_uDMAErrCount);
//UARTprintf ("ADC 读取 A:%u %u 错误计数:%u\n"、g_adcBufA[0]、g_adcBufA[1]、g_uDM勘 误计数);
//UARTprintf ("ADC 读数 B:%u %u 错误计数:%u\n"、g_adcBufB[0]、g_adcBufB[1]、g_uDMAErrCount);
ROM_SysCtlDelay ((g_cpuFrequency/3)*0.1);
}
}
void ADC0SS1IntHandler (void)
{
uint32_t ui32模式;
//limpa interrupção caada pero dma
ADCIntClearEx (ADC0_BASE、ADC_INT_DMA_SS1);
ui32Mode = ROM_uDMAChannelModeGet (UDMA_CHANGE_ADC1 | UDMA_PRI_SELECT);
if (ui32Mode = uDMA_MODE_STOP)
ROM_uDMAChannelTransferSet (UDMA_CHANGE_ADC1 | UDMA_PRI_SELECT、
UDMA_MODE_PINGONG、
(void *)(ADC0_BASE + ADC_O_SSFIFO1)、
G_adcBufA、MEM_buffer_size);
ui32Mode = ROM_uDMAChannelModeGet (UDMA_CHANGE_ADC1 | UDMA_ALT_SELECT);
if (ui32Mode = uDMA_MODE_STOP)
ROM_uDMAChannelTransferSet (UDMA_CHANGE_ADC1 | UDMA_ALT_SELECT、
UDMA_MODE_PINGONG、
(void *)(ADC0_BASE + ADC_O_SSFIFO1)、
G_adcBufB、MEM_buffer_size);
}
void uDMAErrorHandler (void)
{
uint32_t ui32Status;
ui32Status = ROM_uDMAErrorStatusGet ();
if (ui32状态)
{
ROM_uDMAErrorStatusClear ();
G_uDMAErrCount++;
}
}
我正在尝试从引脚 PK0 (GND)和 PK1 (3V3)读取数据。 我要将 g_adcBufA 和 g_adcBufB 大小设置为8、并在每个大小上获得[4095 0 4095 0 4095 0 4095 0]。 看起来它正在读取[PK1 PK0 PK1 PK0 PK1 PK0 PK1 PK0]。
SS1的 FIFO 深度为4、可以保存4个读数。 但我使用的缓冲区有8个位置、它们交替填充 PK1和 PK0读数。
问题:
g_adcBufA 不应该保持前两个值并在其余值中打印其他内容?
为什么不能使用两个值的缓冲器? 它仅在8分钟内工作。 我需要立即得到结果、无需等待缓冲区填充8次、我就可以处理数据。
乒乓模式是否是将 DMA 与 ADC 结合使用的最佳方式? 我听说我可以使用散聚模式、但似乎相当复杂、不确定复杂性是否会弥补性能增益(我对 DMA 完全不了解、只在 STM32板上工作一次、它有一个相当不错的名为 STM32CubeMX 的软件、在后台执行所有操作)。