我的问题中定时器触发ADC转换,转换完后用uDMA将数据搬至缓存区。用乒乓模式,配置了主/副控制结构体。定时器触发是成功的,单独配置下能使ADC正确转换。主要是uDMA搬移数据只能进一次ADC外设中断,即只能搬一次数据。进中断时主/副控制结构体同时会判断传输结束,而不是手册上的无限循环:
程序代码:
//*************************************************程序变量设置*****************************************************
#define ADC0_BUF_SIZE 1024
uint32_t Adc0_Val_RA[ADC0_BUF_SIZE];
uint32_t Adc0_Val_RB[ADC0_BUF_SIZE];
//*************************************************uDMA初始化*****************************************************
extern uint32_t Adc0_Val_RA[ADC0_BUF_SIZE];
extern uint32_t Adc0_Val_RB[ADC0_BUF_SIZE];
{
SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
uDMAEnable();
uDMAControlBaseSet(ucDMAControlTable);
//-------------------------
uDMAChannelAttributeDisable(UDMA_CHANNEL_ADC0, UDMA_ATTR_ALL);//失能通道的所有特性
uDMAChannelAttributeEnable(UDMA_CHANNEL_ADC0,UDMA_ATTR_USEBURST|UDMA_ATTR_HIGH_PRIORITY);//使能猝发与高优先级
//-------------------------
uDMAChannelControlSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT,
UDMA_SIZE_32 | UDMA_SRC_INC_NONE |UDMA_DST_INC_32 | UDMA_ARB_8);
uDMAChannelControlSet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT,
UDMA_SIZE_32 | UDMA_SRC_INC_NONE |UDMA_DST_INC_32 | UDMA_ARB_8);
//-------------------------
uDMAChannelTransferSet(UDMA_CHANNEL_ADC0| UDMA_PRI_SELECT,
UDMA_MODE_PINGPONG, (void *)(ADC0_BASE+ADC_O_SSFIFO0), Adc0_Val_RA,ADC0_BUF_SIZE);
uDMAChannelTransferSet(UDMA_CHANNEL_ADC0| UDMA_ALT_SELECT,
UDMA_MODE_PINGPONG, (void *)(ADC0_BASE+ADC_O_SSFIFO0), Adc0_Val_RB,ADC0_BUF_SIZE);
}
//***********************************************ADC初始化与中断***************************************************
{
SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_3);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ADCSequenceConfigure(ADC0_BASE,0,ADC_TRIGGER_TIMER, 0);//定时器触发ADC转换
ADCSequenceStepConfigure(ADC0_BASE, 0, 1, ADC_CTL_CH0);
ADCSequenceStepConfigure(ADC0_BASE, 0, 2, ADC_CTL_CH0);
ADCSequenceStepConfigure(ADC0_BASE, 0, 3, ADC_CTL_CH0);
ADCSequenceStepConfigure(ADC0_BASE, 0, 4, ADC_CTL_CH0);
ADCSequenceStepConfigure(ADC0_BASE, 0, 5, ADC_CTL_CH0);
ADCSequenceStepConfigure(ADC0_BASE, 0, 6, ADC_CTL_CH0);
ADCSequenceStepConfigure(ADC0_BASE, 0, 7, ADC_CTL_CH0|ADC_CTL_END|ADC_CTL_IE);//使得uDMA仲裁大小为8
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ADCSequenceDMAEnable(ADC0_BASE, 0);//使能DMA传输
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ADCIntRegister(ADC0_BASE,0,ADC0IntHandler);
ADCIntEnable(ADC0_BASE, 0);
ADCIntEnableEx(ADC0_BASE,ADC_INT_DMA_SS0);//代表DMA触发
// IntEnable(INT_ADC0SS0);
// ADCIntClear(ADC0_BASE, ui32SequenceNum);
ADCSequenceEnable(ADC0_BASE, 0);
extern uint32_t Adc0_Val_RA[ADC0_BUF_SIZE];
extern uint32_t Adc0_Val_RB[ADC0_BUF_SIZE];
void ADC0IntHandler(void)
{
ADCIntClearEx(ADC0_BASE, ADC_INT_DMA_SS0);
if(uDMAChannelModeGet(UDMA_CHANNEL_ADC0| UDMA_PRI_SELECT) == UDMA_MODE_STOP)
{
uDMAChannelTransferSet(UDMA_CHANNEL_ADC0| UDMA_PRI_SELECT,
UDMA_MODE_PINGPONG, (void *)(ADC0_BASE+ADC_O_SSFIFO0), Adc0_Val_RA,ADC0_BUF_SIZE);
}
if(uDMAChannelModeGet(UDMA_CHANNEL_ADC0| UDMA_ALT_SELECT) == UDMA_MODE_STOP)
{
uDMAChannelTransferSet(UDMA_CHANNEL_ADC0| UDMA_ALT_SELECT,
UDMA_MODE_PINGPONG, (void *)(ADC0_BASE+ADC_O_SSFIFO0), Adc0_Val_RB,ADC0_BUF_SIZE);
}
}
{
//~~~~~~~~~~~~~~~~~~~
SysCtlClockSet(SYSCTL_SYSDIV_2_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ);
//~~~~~~~~~~~~~~~~~~~
Adc0_Init(0);
MyDma_Init();
My_Timer_Trigger_Init();//定时器触发ADC转换
IntMasterEnable();
while(1)
{
}
}