This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TM4C1294KCPDT:从 ADS8900查询数据时出现问题

Guru**** 2527880 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/996433/tm4c1294kcpdt-problem-aquiring-data-from-ads8900

器件型号:TM4C1294KCPDT

您好!

在我的设计中、我需要以500kSPS 的速率从 ADS8900读取数据并将其传输到 Tiva MCU。

我想使用 uDMA 在没有中断的情况下实现它、因为在采集期间 MCU 应处理数据。

任务是:每次我生成一个 CONVST 脉冲时、I neet 开始查询下一个样本、总共4100个样本、然后触发数据处理。

因此、我需要我的计时器通过 UDMA 触发3字节 SSI 传输、并使用另一个通道传输由 SSI 触发的4100 * 3字节。

首先、我在 uDMAChannelEnable 例程中看到一个错误-它可以像看起来一样清洗其他通道使能

HWREG(UDMA_ENASET) = 1 << ui8ChannelNum;

但接下来我看不到任何到 SSI 的传输。 以下是我的代码:

    SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI1);
    GPIOPinConfigure(GPIO_PE4_SSI1XDAT0);
    GPIOPinConfigure(GPIO_PE5_SSI1XDAT1);
    GPIOPinConfigure(GPIO_PB5_SSI1CLK);
    GPIOPinTypeSSI(GPIO_PORTB_BASE, GPIO_PIN_5);
    GPIOPinTypeSSI(GPIO_PORTE_BASE, GPIO_PIN_4);
    GPIOPinTypeSSI(GPIO_PORTE_BASE, GPIO_PIN_5);
    SSIConfigSetExpClk(SSI1_BASE, g_ui32SysClock, SSI_FRF_MOTO_MODE_0, SSI_MODE_MASTER, 22000000, 8);
    SSIAdvModeSet(SSI1_BASE, SSI_ADV_MODE_READ_WRITE);
    SSIAdvFrameHoldEnable(SSI1_BASE);
    SSIEnable(SSI1_BASE);
    SSIDMAEnable(SSI1_BASE, SSI_DMA_RX);

    uDMAEnable();
    uDMAControlBaseSet(pui8ControlTable);
    uDMAChannelAssign(UDMA_CH10_SSI1RX);
    uDMAChannelAssign(UDMA_CH0_TIMER4A);
#define UDMA_CHANNEL_TMR4A  UDMA_CHANNEL_USBEP1RX
    uDMAChannelAttributeDisable(UDMA_CHANNEL_TMR4A, UDMA_ATTR_ALTSELECT | UDMA_ATTR_HIGH_PRIORITY |
                                UDMA_ATTR_REQMASK);
    uDMAChannelControlSet(UDMA_CHANNEL_TMR4A | UDMA_PRI_SELECT, UDMA_SIZE_32 | UDMA_SRC_INC_32 | UDMA_DST_INC_NONE | UDMA_ARB_1);
    uDMAChannelTransferSet(UDMA_CHANNEL_TMR4A | UDMA_PRI_SELECT, UDMA_MODE_AUTO,
                           (void *)ADCReq, (void *)(SSI1_BASE + SSI_O_DR), 3);
    uDMAChannelAttributeEnable(UDMA_CHANNEL_TMR4A, UDMA_ATTR_USEBURST);


    uDMAChannelAttributeDisable(UDMA_CHANNEL_SSI1RX, UDMA_ATTR_ALTSELECT | UDMA_ATTR_HIGH_PRIORITY |
                                UDMA_ATTR_REQMASK);
    uDMAChannelControlSet(UDMA_CHANNEL_SSI1RX | UDMA_PRI_SELECT, UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARB_1);
    uDMAChannelTransferSet(UDMA_CHANNEL_SSI1RX | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG,
                           (void *)(SSI1_BASE + SSI_O_DR), (void *)ADCData1, 4100 * 3);
    uDMAChannelControlSet(UDMA_CHANNEL_SSI1RX | UDMA_ALT_SELECT, UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARB_1);
    uDMAChannelTransferSet(UDMA_CHANNEL_SSI1RX | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG,
                           (void *)(SSI1_BASE + SSI_O_DR), (void *)ADCData2, 4100 * 3);
    HWREG(UDMA_ENASET) = (1 << UDMA_CHANNEL_TMR4A) + (1 << UDMA_CHANNEL_SSI1RX);

    GPIOPinTypeTimer(GPIO_PORTL_BASE, GPIO_PIN_4 | GPIO_PIN_5);
    GPIOPinConfigure(GPIO_PL4_T0CCP0);
    GPIOPinConfigure(GPIO_PL5_T0CCP1);
    TimerConfigure(TIMER0_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PWM | TIMER_CFG_B_PWM);
    TimerLoadSet(TIMER0_BASE, TIMER_A, g_ui32SysClock / 500000);
    TimerMatchSet(TIMER0_BASE, TIMER_A, TimerLoadGet(TIMER0_BASE, TIMER_A) - 10);
    //TimerDMAEventSet(TIMER0_BASE, TIMER_DMA_TIMEOUT_A);

    TimerLoadSet(TIMER0_BASE, TIMER_B, g_ui32SysClock / 500000);
    TimerMatchSet(TIMER0_BASE, TIMER_B, 100);
    TimerControlLevel(TIMER0_BASE, TIMER_B, true);

    TimerEnable(TIMER0_BASE, TIMER_BOTH);

    SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER4);
    TimerConfigure(TIMER4_BASE, TIMER_CFG_PERIODIC);
    TimerLoadSet(TIMER4_BASE, TIMER_A, g_ui32SysClock / 500000);
    TimerDMAEventSet(TIMER4_BASE, TIMER_DMA_TIMEOUT_A);
    TimerEnable(TIMER4_BASE, TIMER_A);

Timer 0A 用于 CONVST 生成、Timer 0B 用于 CS 生成、而 Timer 4应触发 UDMA 传输到 SSI、但不会。

出什么问题了?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    这不是 uDMAChannelEnable()例程中的错误。 在 DMAENASET 寄存器中写入0不会清除该位。 从 数据表中

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    但调试器显示位已清除。

    无论如何、这不是问题、因为我使用直接寄存器写入来启用两个通道。

    问题是为什么根本不触发到 SSI 的传输?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    更新:

    定时器通道的使能位在定时器使能后立即清零。 为什么?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    好的、我解决了这个问题。

    这有点奇怪、但下面是代码片段:

    uint32_t DMASave[4];
    
    tDMAControlTable MyTaskList[] =
    {
     uDMATaskStructEntry(3, UDMA_SIZE_8, UDMA_SRC_INC_8, ADCReq, UDMA_DST_INC_NONE, SSI1_BASE + SSI_O_DR, UDMA_ARB_4, UDMA_MODE_PER_SCATTER_GATHER),
     uDMATaskStructEntry(4, UDMA_SIZE_32, UDMA_SRC_INC_32, DMASave, UDMA_DST_INC_32, pui8ControlTable, UDMA_ARB_1, UDMA_MODE_MEM_SCATTER_GATHER)
    };
    
    
    UDMA 初始化:

        uDMAEnable();
        uDMAControlBaseSet(pui8ControlTable);
        uDMAChannelAssign(UDMA_CH10_SSI1RX);
        uDMAChannelAssign(UDMA_CH0_TIMER4A);
    
        uDMAChannelAttributeDisable(0, UDMA_ATTR_ALTSELECT | UDMA_ATTR_HIGH_PRIORITY |
                                    UDMA_ATTR_REQMASK);
        /*uDMAChannelControlSet(0 | UDMA_PRI_SELECT, UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_NONE | UDMA_NEXT_USEBURST | UDMA_ARB_1);
        uDMAChannelTransferSet(0 | UDMA_PRI_SELECT, UDMA_MODE_BASIC,
                                   (void *)ADCReq, (void *)(SSI1_BASE + SSI_O_DR), 30);*/
    
        uDMAChannelScatterGatherSet(0, 2, MyTaskList, true);
    
        uDMAChannelAttributeEnable(0, UDMA_ATTR_USEBURST);
        memcpy(DMASave, pui8ControlTable, 16);
        uDMAChannelEnable(0);
    

    这起作用了。

    但我还有另一个问题、一个问题将为它创建另一个主题。