TM4C123GH6PM的ADC数据用uDMA乒乓模式传输不成功,请帮忙看看哪里配置错误,谢谢!

2019-03-24 09:00发布

我的问题中定时器触发ADC转换,转换完后用uDMA将数据搬至缓存区。用乒乓模式,配置了主/副控制结构体。定时器触发是成功的,单独配置下能使ADC正确转换。主要是uDMA搬移数据只能进一次ADC外设中断,即只能搬一次数据。进中断时主/副控制结构体同时会判断传输结束,而不是手册上的无限循环:
1.png
  1. 程序代码:

  2. //*************************************************程序变量设置*****************************************************

  3. #define ADC0_BUF_SIZE        1024

  4. uint32_t Adc0_Val_RA[ADC0_BUF_SIZE];
  5. uint32_t Adc0_Val_RB[ADC0_BUF_SIZE];

  6. //*************************************************uDMA初始化*****************************************************

  7. uint8_t ucDMAControlTable[1024];//通道控制表
  8. extern uint32_t Adc0_Val_RA[ADC0_BUF_SIZE];
  9. extern uint32_t Adc0_Val_RB[ADC0_BUF_SIZE];
  10. void MyDma_Init(void)
  11. {
  12. SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
  13. uDMAEnable();
  14. uDMAControlBaseSet(ucDMAControlTable);
  15. //-------------------------
  16. uDMAChannelAttributeDisable(UDMA_CHANNEL_ADC0, UDMA_ATTR_ALL);//失能通道的所有特性
  17. uDMAChannelAttributeEnable(UDMA_CHANNEL_ADC0,UDMA_ATTR_USEBURST|UDMA_ATTR_HIGH_PRIORITY);//使能猝发与高优先级
  18. //-------------------------
  19. uDMAChannelControlSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT,
  20.         UDMA_SIZE_32 |  UDMA_SRC_INC_NONE |UDMA_DST_INC_32 | UDMA_ARB_8);
  21. uDMAChannelControlSet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT,
  22.         UDMA_SIZE_32 |  UDMA_SRC_INC_NONE |UDMA_DST_INC_32 | UDMA_ARB_8);
  23. //-------------------------
  24. uDMAChannelTransferSet(UDMA_CHANNEL_ADC0| UDMA_PRI_SELECT,
  25.         UDMA_MODE_PINGPONG,  (void *)(ADC0_BASE+ADC_O_SSFIFO0), Adc0_Val_RA,ADC0_BUF_SIZE);
  26. uDMAChannelTransferSet(UDMA_CHANNEL_ADC0| UDMA_ALT_SELECT,
  27.         UDMA_MODE_PINGPONG,  (void *)(ADC0_BASE+ADC_O_SSFIFO0), Adc0_Val_RB,ADC0_BUF_SIZE);
  28. uDMAChannelEnable(UDMA_CHANNEL_ADC0);
  29. }
  30. //***********************************************ADC初始化与中断***************************************************

  31. void Adc0_Init(void)
  32. {
  33. SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
  34. SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
  35. GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_3);
  36. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  37. ADCSequenceConfigure(ADC0_BASE,0,ADC_TRIGGER_TIMER, 0);//定时器触发ADC转换
  38. ADCSequenceStepConfigure(ADC0_BASE, 0, 0,  ADC_CTL_CH0);
  39. ADCSequenceStepConfigure(ADC0_BASE, 0, 1,  ADC_CTL_CH0);
  40. ADCSequenceStepConfigure(ADC0_BASE, 0, 2,  ADC_CTL_CH0);
  41. ADCSequenceStepConfigure(ADC0_BASE, 0, 3,  ADC_CTL_CH0);
  42. ADCSequenceStepConfigure(ADC0_BASE, 0, 4,  ADC_CTL_CH0);
  43. ADCSequenceStepConfigure(ADC0_BASE, 0, 5,  ADC_CTL_CH0);
  44. ADCSequenceStepConfigure(ADC0_BASE, 0, 6,  ADC_CTL_CH0);
  45. ADCSequenceStepConfigure(ADC0_BASE, 0, 7,  ADC_CTL_CH0|ADC_CTL_END|ADC_CTL_IE);//使得uDMA仲裁大小为8
  46. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  47. ADCSequenceDMAEnable(ADC0_BASE, 0);//使能DMA传输
  48. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  49. ADCIntRegister(ADC0_BASE,0,ADC0IntHandler);
  50. ADCIntEnable(ADC0_BASE, 0);
  51. ADCIntEnableEx(ADC0_BASE,ADC_INT_DMA_SS0);//代表DMA触发
  52. // IntEnable(INT_ADC0SS0);
  53. // ADCIntClear(ADC0_BASE, ui32SequenceNum);
  54. ADCSequenceEnable(ADC0_BASE, 0);
  55. //****************************
  56. extern uint32_t Adc0_Val_RA[ADC0_BUF_SIZE];
  57. extern uint32_t Adc0_Val_RB[ADC0_BUF_SIZE];
  58. void ADC0IntHandler(void)
  59. {
  60.    ADCIntClearEx(ADC0_BASE, ADC_INT_DMA_SS0);
  61.   
  62.   if(uDMAChannelModeGet(UDMA_CHANNEL_ADC0| UDMA_PRI_SELECT) == UDMA_MODE_STOP)
  63.    {
  64.   uDMAChannelTransferSet(UDMA_CHANNEL_ADC0| UDMA_PRI_SELECT,
  65.         UDMA_MODE_PINGPONG,  (void *)(ADC0_BASE+ADC_O_SSFIFO0), Adc0_Val_RA,ADC0_BUF_SIZE);
  66.    }
  67.   
  68.   if(uDMAChannelModeGet(UDMA_CHANNEL_ADC0| UDMA_ALT_SELECT) == UDMA_MODE_STOP)
  69.    {
  70.   uDMAChannelTransferSet(UDMA_CHANNEL_ADC0| UDMA_ALT_SELECT,
  71.         UDMA_MODE_PINGPONG,  (void *)(ADC0_BASE+ADC_O_SSFIFO0), Adc0_Val_RB,ADC0_BUF_SIZE);
  72.    }
  73. }
  74. //*********************************************************main.c**************************************************************
  75. int main(void)
  76. {
  77. //~~~~~~~~~~~~~~~~~~~
  78. SysCtlClockSet(SYSCTL_SYSDIV_2_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ);
  79. //~~~~~~~~~~~~~~~~~~~
  80. Adc0_Init(0);
  81. MyDma_Init();
  82. My_Timer_Trigger_Init();//定时器触发ADC转换
  83. IntMasterEnable();
  84. while(1)
  85. {
  86. }
  87. }
复制代码

此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
1条回答
azhiking
2019-03-24 15:16
乒完成的时候要设置乓的相关信息,看你的中断处理里面只有单次的乒乓,这样的话肯定不会持续进行dma数据传输了。乒完成的时候,设置乒的数据储存,同时设置乓的信息;反之亦然,你试试看。

一周热门 更多>

相关问题

    相关文章