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.

[参考译文] EK-TM4C123GXL:发送 SPI 数据期间的 EK-TM4C123GXL 与模拟输入 rms -30dB 噪声相比

Guru**** 674950 points
Other Parts Discussed in Thread: EK-TM4C123GXL
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1217787/ek-tm4c123gxl-ek-tm4c123gxl-during-send-spi-data-than-have-on-analog-input-rms--30db-noise

器件型号:EK-TM4C123GXL

我需要使用全部4个 SPI 数据连接。

当通过 SPI 发送数据时、模拟输入采样期间的噪声大幅增加至 rms -30dB。

这是一个常见问题吗?

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

    您好!

     我不清楚你在想做什么。 您是否认为在使用 ADC 对模拟输入进行采样时使用的是具有4个引脚的 SPI? SPI 引脚运行时、噪声会耦合到 ADC 输入中?

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

    我使用4个 SPI GPIO 引脚发送数据。
    我已将它们配置如下:

    #define SSI_CLOCK (4800000)
    
    void init_SSI0()
    {
        // enable SSI1 Tx PA5 only
        
        MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI0);
        while(!MAP_SysCtlPeripheralReady(SYSCTL_PERIPH_SSI0));
        
        // port config
        MAP_GPIOPinConfigure(GPIO_PA5_SSI0TX);
        MAP_GPIOPinTypeSSI(GPIO_PORTA_BASE, GPIO_PIN_5);
        
        MAP_GPIOPadConfigSet(GPIO_PORTA_BASE, GPIO_PIN_5, 
                             GPIO_STRENGTH_4MA, GPIO_PIN_TYPE_STD);
        
        // SSI config
        MAP_IntDisable(INT_SSI0);
        MAP_SSIIntDisable(SSI0_BASE, SSI_TXFF | SSI_RXFF | SSI_RXTO | SSI_RXOR);
        MAP_SSIDisable(SSI0_BASE);
        MAP_SSIConfigSetExpClk(SSI0_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_1, 
                               SSI_MODE_MASTER, SSI_CLOCK, 8);
        
        // ------------------ //
        // Priority Levels
        // Priority 4 = 0xE0 ->lower
        // Priority 3 = 0x60
        // Priority 2 = 0x20
        // Priority 1 = 0x00 ->higher
        // ------------------ //
        
        MAP_IntPrioritySet(INT_SSI0, 0x00); // Priority 1 !!!
        MAP_IntEnable(INT_SSI0);
        MAP_SSIEnable(SSI0_BASE);
    }
    
    void init_SSI1()
    {
        // enable SSI1 Tx PF1 only
        
        MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI1);
        while(!MAP_SysCtlPeripheralReady(SYSCTL_PERIPH_SSI1));
        
        // port config
        MAP_GPIOPinConfigure(GPIO_PF1_SSI1TX);
        MAP_GPIOPinTypeSSI(GPIO_PORTF_BASE, GPIO_PIN_1);
        
        MAP_GPIOPadConfigSet(GPIO_PORTF_BASE, GPIO_PIN_1, 
                             GPIO_STRENGTH_4MA, GPIO_PIN_TYPE_STD);
        
        // SSI config
        MAP_IntDisable(INT_SSI1);
        MAP_SSIIntDisable(SSI1_BASE, SSI_TXFF | SSI_RXFF | SSI_RXTO | SSI_RXOR);
        MAP_SSIDisable(SSI1_BASE);
        
        MAP_SSIConfigSetExpClk(SSI1_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_1, 
                               SSI_MODE_MASTER, SSI_CLOCK, 8);
        
        // ------------------ //
        // Priority Levels
        // Priority 4 = 0xE0 ->lower
        // Priority 3 = 0x60
        // Priority 2 = 0x20
        // Priority 1 = 0x00 ->higher
        // ------------------ //
        
        MAP_IntPrioritySet(INT_SSI1, 0x00); // Priority 1 !!!
        MAP_IntEnable(INT_SSI1);
        MAP_SSIEnable(SSI1_BASE);
    }
    
    void init_SSI2()
    {
        // enable SSI2 Tx PB7 only
        
        MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI2);
        while(!MAP_SysCtlPeripheralReady(SYSCTL_PERIPH_SSI2));
        
        // port config
        MAP_GPIOPinConfigure(GPIO_PB7_SSI2TX);
        MAP_GPIOPinTypeSSI(GPIO_PORTB_BASE, GPIO_PIN_7);
        
        MAP_GPIOPadConfigSet(GPIO_PORTB_BASE, GPIO_PIN_7, 
                             GPIO_STRENGTH_4MA, GPIO_PIN_TYPE_STD);
        
        // SSI config
        MAP_IntDisable(INT_SSI2);
        MAP_SSIIntDisable(SSI2_BASE, SSI_TXFF | SSI_RXFF | SSI_RXTO | SSI_RXOR);
        MAP_SSIDisable(SSI2_BASE);
        
        MAP_SSIConfigSetExpClk(SSI2_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_1, 
                               SSI_MODE_MASTER, SSI_CLOCK, 8);
        
        // ------------------ //
        // Priority Levels
        // Priority 4 = 0xE0 ->lower
        // Priority 3 = 0x60
        // Priority 2 = 0x20
        // Priority 1 = 0x00 ->higher
        // ------------------ //
        
        MAP_IntPrioritySet(INT_SSI2, 0x00); // Priority 1 !!!
        MAP_IntEnable(INT_SSI2);
        MAP_SSIEnable(SSI2_BASE);
    }
    
    void init_SSI3()
    {
        // enable SSI3 Tx PD3 only
        
        MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI3);
        while(!MAP_SysCtlPeripheralReady(SYSCTL_PERIPH_SSI3));
        
        // port config
        MAP_GPIOPinConfigure(GPIO_PD3_SSI3TX);
        MAP_GPIOPinTypeSSI(GPIO_PORTD_BASE, GPIO_PIN_3);
        
        MAP_GPIOPadConfigSet(GPIO_PORTD_BASE, GPIO_PIN_3, 
                             GPIO_STRENGTH_4MA, GPIO_PIN_TYPE_STD);
        
        // SSI config
        MAP_IntDisable(INT_SSI3);
        MAP_SSIIntDisable(SSI3_BASE, SSI_TXFF | SSI_RXFF | SSI_RXTO | SSI_RXOR);
        MAP_SSIDisable(SSI3_BASE);
        
        MAP_SSIConfigSetExpClk(SSI3_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_1, 
                               SSI_MODE_MASTER, SSI_CLOCK, 8);
        
        // ------------------ //
        // Priority Levels
        // Priority 4 = 0xE0 ->lower
        // Priority 3 = 0x60
        // Priority 2 = 0x20
        // Priority 1 = 0x00 ->higher
        // ------------------ //
        
        MAP_IntPrioritySet(INT_SSI3, 0x00); // Priority 1 !!!
        MAP_IntEnable(INT_SSI3);
        MAP_SSIEnable(SSI3_BASE);
    }

    i uDMA 部件:

    void init_uDMA_SSI0()
    {
        // signal 0
        // uDMA Channel 11
        MAP_SSIDMADisable(SSI0_BASE, SSI_DMA_RX | SSI_DMA_TX);
        
        MAP_uDMAChannelAssign(UDMA_CH11_SSI0TX);
        MAP_uDMAChannelAttributeDisable(11, 
                                        UDMA_ATTR_ALTSELECT | 
                                        UDMA_ATTR_HIGH_PRIORITY | 
                                        UDMA_ATTR_REQMASK | 
                                        UDMA_ATTR_USEBURST);
        
        MAP_uDMAChannelControlSet(11 | UDMA_PRI_SELECT, 
                                  UDMA_SIZE_8 | UDMA_SRC_INC_8 | 
                                  UDMA_DST_INC_NONE | UDMA_ARB_4);
        
        MAP_uDMAChannelControlSet(11 | UDMA_ALT_SELECT, 
                                  UDMA_SIZE_8 | UDMA_SRC_INC_8 | 
                                  UDMA_DST_INC_NONE | UDMA_ARB_4);
        
        //MAP_uDMAChannelAttributeEnable(11, UDMA_ATTR_USEBURST | UDMA_ATTR_HIGH_PRIORITY);
        MAP_SSIDMAEnable(SSI0_BASE, SSI_DMA_TX);
        MAP_SSIEnable(SSI0_BASE);
    }
    
    void init_uDMA_SSI1()
    {
        // signal 1
        // uDMA Channel 25
        MAP_SSIDMADisable(SSI1_BASE, SSI_DMA_RX | SSI_DMA_TX);
        
        MAP_uDMAChannelAssign(UDMA_CH25_SSI1TX);
        MAP_uDMAChannelAttributeDisable(25, 
                                        UDMA_ATTR_ALTSELECT | 
                                        UDMA_ATTR_HIGH_PRIORITY | 
                                        UDMA_ATTR_REQMASK | 
                                        UDMA_ATTR_USEBURST);
        
        MAP_uDMAChannelControlSet(25 | UDMA_PRI_SELECT, 
                                  UDMA_SIZE_8 | UDMA_SRC_INC_8 | 
                                  UDMA_DST_INC_NONE | UDMA_ARB_4);
        
        MAP_uDMAChannelControlSet(25 | UDMA_ALT_SELECT, 
                                  UDMA_SIZE_8 | UDMA_SRC_INC_8 | 
                                  UDMA_DST_INC_NONE | UDMA_ARB_4);
        
        //MAP_uDMAChannelAttributeEnable(25, UDMA_ATTR_USEBURST | UDMA_ATTR_HIGH_PRIORITY);
        MAP_SSIDMAEnable(SSI1_BASE, SSI_DMA_TX);
        MAP_SSIEnable(SSI1_BASE);
    }
    
    void init_uDMA_SSI2()
    {
        // signal 2
        // uDMA Channel 13
        MAP_SSIDMADisable(SSI2_BASE, SSI_DMA_RX | SSI_DMA_TX);
        
        MAP_uDMAChannelAssign(UDMA_CH13_SSI2TX);
        MAP_uDMAChannelAttributeDisable(13, 
                                        UDMA_ATTR_ALTSELECT | 
                                        UDMA_ATTR_HIGH_PRIORITY | 
                                        UDMA_ATTR_REQMASK | 
                                        UDMA_ATTR_USEBURST);
        
        MAP_uDMAChannelControlSet(13 | UDMA_PRI_SELECT, 
                                  UDMA_SIZE_8 | UDMA_SRC_INC_8 | 
                                  UDMA_DST_INC_NONE | UDMA_ARB_4);
        
        MAP_uDMAChannelControlSet(13 | UDMA_ALT_SELECT, 
                                  UDMA_SIZE_8 | UDMA_SRC_INC_8 | 
                                  UDMA_DST_INC_NONE | UDMA_ARB_4);
        
        //MAP_uDMAChannelAttributeEnable(13, UDMA_ATTR_USEBURST | UDMA_ATTR_HIGH_PRIORITY);
        MAP_SSIDMAEnable(SSI2_BASE, SSI_DMA_TX);
        MAP_SSIEnable(SSI2_BASE);
    }
    
    void init_uDMA_SSI3()
    {
        // signal 3
        // uDMA Channel 15
        MAP_SSIDMADisable(SSI3_BASE, SSI_DMA_RX | SSI_DMA_TX);
        
        MAP_uDMAChannelAssign(UDMA_CH15_SSI3TX);
        MAP_uDMAChannelAttributeDisable(15, 
                                        UDMA_ATTR_ALTSELECT | 
                                        UDMA_ATTR_HIGH_PRIORITY | 
                                        UDMA_ATTR_REQMASK | 
                                        UDMA_ATTR_USEBURST);
        
        MAP_uDMAChannelControlSet(15 | UDMA_PRI_SELECT, 
                                  UDMA_SIZE_8 | UDMA_SRC_INC_8 | 
                                  UDMA_DST_INC_NONE | UDMA_ARB_4);
        
        MAP_uDMAChannelControlSet(15 | UDMA_ALT_SELECT, 
                                  UDMA_SIZE_8 | UDMA_SRC_INC_8 | 
                                  UDMA_DST_INC_NONE | UDMA_ARB_4);
        
        //MAP_uDMAChannelAttributeEnable(15, UDMA_ATTR_USEBURST | UDMA_ATTR_HIGH_PRIORITY);
        MAP_SSIDMAEnable(SSI3_BASE, SSI_DMA_TX);
        MAP_SSIEnable(SSI3_BASE);
    }

    使用 uDMA 通过 SPI 发送数据。 在 SRAM 中准备数据。

    void start_uDMA_SSI0()
    {
        MAP_uDMAChannelTransferSet(11 | UDMA_PRI_SELECT, 
                                   UDMA_MODE_PINGPONG, &uDMABufferSSI0_PRI, 
                                   (void *)(SSI0_BASE + SSI_O_DR), 
                                   SSI_TRANSFERSIZE);
        
        MAP_uDMAChannelEnable(11 | UDMA_PRI_SELECT);
        uDMABufferStateSSI0_PRI = EMPTYING;
        uDMABufferModeSSI0 = PING;
        
        MAP_uDMAChannelTransferSet(11 | UDMA_ALT_SELECT, 
                                   UDMA_MODE_PINGPONG, &uDMABufferSSI0_ALT, 
                                   (void *)(SSI0_BASE + SSI_O_DR), 
                                   SSI_TRANSFERSIZE);
        
        MAP_uDMAChannelEnable(11 | UDMA_ALT_SELECT);
        uDMABufferStateSSI0_ALT = EMPTYING;
        uDMABufferModeSSI0 = PONG;
    }
    
    void start_uDMA_SSI1()
    {
        MAP_uDMAChannelTransferSet(25 | UDMA_PRI_SELECT, 
                                   UDMA_MODE_PINGPONG, &uDMABufferSSI1_PRI, 
                                   (void *)(SSI1_BASE + SSI_O_DR), 
                                   SSI_TRANSFERSIZE);
        
        MAP_uDMAChannelEnable(25 | UDMA_PRI_SELECT);
        uDMABufferStateSSI1_PRI = EMPTYING;
        uDMABufferModeSSI1 = PING;
        
        MAP_uDMAChannelTransferSet(25 | UDMA_ALT_SELECT, 
                                   UDMA_MODE_PINGPONG, &uDMABufferSSI1_ALT, 
                                   (void *)(SSI1_BASE + SSI_O_DR), 
                                   SSI_TRANSFERSIZE);
        
        MAP_uDMAChannelEnable(25 | UDMA_ALT_SELECT);
        uDMABufferStateSSI1_ALT = EMPTYING;
        uDMABufferModeSSI1 = PONG;
    }
    
    void start_uDMA_SSI2()
    {
        MAP_uDMAChannelTransferSet(13 | UDMA_PRI_SELECT, 
                                   UDMA_MODE_PINGPONG, &uDMABufferSSI2_PRI, 
                                   (void *)(SSI2_BASE + SSI_O_DR), 
                                   SSI_TRANSFERSIZE);
        
        MAP_uDMAChannelEnable(13 | UDMA_PRI_SELECT);
        uDMABufferStateSSI2_PRI = EMPTYING;
        uDMABufferModeSSI2 = PING;
        
        MAP_uDMAChannelTransferSet(13 | UDMA_ALT_SELECT, 
                                   UDMA_MODE_PINGPONG, &uDMABufferSSI2_ALT, 
                                   (void *)(SSI2_BASE + SSI_O_DR), 
                                   SSI_TRANSFERSIZE);
        
        MAP_uDMAChannelEnable(13 | UDMA_ALT_SELECT);
        uDMABufferStateSSI2_ALT = EMPTYING;
        uDMABufferModeSSI2 = PONG;
    }
    
    void start_uDMA_SSI3()
    {
        MAP_uDMAChannelTransferSet(15 | UDMA_PRI_SELECT, 
                                   UDMA_MODE_PINGPONG, &uDMABufferSSI3_PRI, 
                                   (void *)(SSI3_BASE + SSI_O_DR), 
                                   SSI_TRANSFERSIZE);
        
        MAP_uDMAChannelEnable(15 | UDMA_PRI_SELECT);
        uDMABufferStateSSI3_PRI = EMPTYING;
        uDMABufferModeSSI3 = PING;
        
        MAP_uDMAChannelTransferSet(15 | UDMA_ALT_SELECT, 
                                   UDMA_MODE_PINGPONG, &uDMABufferSSI3_ALT, 
                                   (void *)(SSI3_BASE + SSI_O_DR), 
                                   SSI_TRANSFERSIZE);
        
        MAP_uDMAChannelEnable(15 | UDMA_ALT_SELECT);
        uDMABufferStateSSI3_ALT = EMPTYING;
        uDMABufferModeSSI3 = PING;
    }

    然后、我一起开始4个 SPI 流:

    void startDMABufferSSI()
    {
        start_uDMA_SSI0();
        MAP_SysCtlDelay(70);
        
        start_uDMA_SSI1();
        MAP_SysCtlDelay(70);
        
        start_uDMA_SSI2();
        MAP_SysCtlDelay(70);
        
        start_uDMA_SSI3();
        
        resetCode = 1;
    }

    之所以会导入较小的延迟、是因为可能是 SS1在发送完成之前停止。

    我不知道为什么、但这是另一个问题。

    当数据发送完成时、将准备新数据并且发送在循环中再次开始。

    以下是 中断处理程序

    void uDMASSI0IntHandler(void)
    {
        MAP_SSIIntClear(SSI0_BASE, SSI_RXTO | SSI_RXOR); // Do I have to do that?
        MAP_uDMAIntClear(11); // Do I have to do that?
        
        if (MAP_uDMAChannelModeGet(11 | UDMA_PRI_SELECT) == UDMA_MODE_STOP)
        {
            uDMABufferStateSSI0_PRI = EMPTY;
        }
        
        if (MAP_uDMAChannelModeGet(11 | UDMA_ALT_SELECT) == UDMA_MODE_STOP)
        {
            uDMABufferStateSSI0_ALT = EMPTY;
        }
    }
    
    void uDMASSI1IntHandler(void)
    {
        MAP_SSIIntClear(SSI1_BASE, SSI_RXTO | SSI_RXOR); // Do I have to do that?
        MAP_uDMAIntClear(25); // Do I have to do that?
        
        if (MAP_uDMAChannelModeGet(25 | UDMA_PRI_SELECT) == UDMA_MODE_STOP)
        {
            uDMABufferStateSSI1_PRI = EMPTY;
        }
        
        if (MAP_uDMAChannelModeGet(25 | UDMA_ALT_SELECT) == UDMA_MODE_STOP)
        {
            uDMABufferStateSSI1_ALT = EMPTY;
        }
    }
    
    void uDMASSI2IntHandler(void)
    {
        MAP_SSIIntClear(SSI2_BASE, SSI_RXTO | SSI_RXOR); // Do I have to do that?
        MAP_uDMAIntClear(13); // Do I have to do that?
        
        if (MAP_uDMAChannelModeGet(13 | UDMA_PRI_SELECT) == UDMA_MODE_STOP)
        {
            uDMABufferStateSSI2_PRI = EMPTY;
        }
        
        if (MAP_uDMAChannelModeGet(13 | UDMA_ALT_SELECT) == UDMA_MODE_STOP)
        {
            uDMABufferStateSSI2_ALT = EMPTY;
        }
    }
    
    void uDMASSI3IntHandler(void)
    {
        MAP_SSIIntClear(SSI3_BASE, SSI_RXTO | SSI_RXOR); // Do I have to do that?
        MAP_uDMAIntClear(15); // Do I have to do that?
        
        if (MAP_uDMAChannelModeGet(15 | UDMA_PRI_SELECT) == UDMA_MODE_STOP)
        {
            uDMABufferStateSSI3_PRI = EMPTY;
        }
        
        if (MAP_uDMAChannelModeGet(15 | UDMA_ALT_SELECT) == UDMA_MODE_STOP)
        {
            uDMABufferStateSSI3_ALT = EMPTY;
            
            // enable timer for reset code
            MAP_TimerEnable(WTIMER5_BASE, TIMER_B);
        }
    }

    在通过 SPI 发送数据的同时、还记录一个模拟输入。

    触发来自计时器

    #define ADC_SAMPLING_RATE (44100)
    
    void init_TIMER_2()
    {
        MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER2);
        while(!MAP_SysCtlPeripheralReady(SYSCTL_PERIPH_TIMER2));
        
        // Timer 2A is PB0 trigger for ADC0 SS3
        // Timer 2B is PB1 not used
        
        MAP_TimerConfigure(TIMER2_BASE, TIMER_CFG_SPLIT_PAIR | 
                           TIMER_CFG_A_PERIODIC | TIMER_CFG_B_ONE_SHOT);
        
        // Timer 2A
        // set ADC0 SS3 sampling rate
        MAP_TimerLoadSet(TIMER2_BASE, TIMER_A,
                         (SysCtlClockGet()/ADC_SAMPLING_RATE) - 1);
        
        // Timer 2A
        // enable the ADC trigger output for Timer A.
        MAP_TimerControlTrigger(TIMER2_BASE, TIMER_A, true);
        
        // Timer 2A
        // enable timer done interrupt
        MAP_TimerIntEnable(TIMER2_BASE, TIMER_TIMA_TIMEOUT);
    }

    使用 uDMA 进行录制

    void init_uDMA_MIC0()
    {
        // adc mic setup
        // uDMA Channel 17
        MAP_uDMAChannelAssign(UDMA_CH17_ADC0_3);
        
        MAP_uDMAChannelAttributeDisable(17,
                                        UDMA_ATTR_ALTSELECT | 
                                        UDMA_ATTR_HIGH_PRIORITY | 
                                        UDMA_ATTR_REQMASK);
        
        MAP_uDMAChannelControlSet(17 | UDMA_PRI_SELECT,
                                  UDMA_SIZE_16 | UDMA_SRC_INC_NONE | 
                                  UDMA_DST_INC_16 | UDMA_ARB_1);
        
        MAP_uDMAChannelControlSet(17 | UDMA_ALT_SELECT, 
                                  UDMA_SIZE_16 | UDMA_SRC_INC_NONE | 
                                  UDMA_DST_INC_16 | UDMA_ARB_1);
        
        MAP_uDMAChannelAttributeEnable(17, UDMA_ATTR_USEBURST);
    }

    ADC 设置为:

    void init_ADC0()
    {
        MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
        while(!MAP_SysCtlPeripheralReady(SYSCTL_PERIPH_ADC0));
        
        ADCClockConfigSet(ADC0_BASE, ADC_CLOCK_SRC_PIOSC | 
                          ADC_CLOCK_RATE_HALF, 1);
        
        SysCtlDelay(10);
    }
    
    void init_ADC0_MIC0()
    {
        MAP_GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_2);
        
        MAP_IntDisable(INT_ADC0SS3);
        MAP_ADCIntDisable(ADC0_BASE, 3);
        MAP_ADCSequenceDisable(ADC0_BASE, 3);
        
        MAP_ADCSequenceConfigure(ADC0_BASE, 3, ADC_TRIGGER_TIMER, 0);
        
        MAP_ADCSequenceStepConfigure(ADC0_BASE, 3, 0, ADC_CTL_CH5 | ADC_CTL_IE | 
                                     ADC_CTL_END);
        
        // ------------------ //
        // Priority Levels
        // Priority 4 = 0xE0 ->lower
        // Priority 3 = 0x60
        // Priority 2 = 0x20
        // Priority 1 = 0x00 ->higher
        // ------------------ //
        
        MAP_IntPrioritySet(INT_ADC0SS3, 0xE0); // Priority 4 !!!
    }

    启动 uDMA 通道:

    void start_uDMA_ADC0_SS3()
    {
        if (mic0BufferState_PRI == EMPTY)
        {
            MAP_uDMAChannelTransferSet(17 | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, 
                                       (void *)(ADC0_BASE + ADC_O_SSFIFO3), 
                                       &mic0Buffer_PRI, ADC_SAMPLES);
            
            MAP_uDMAChannelEnable(17 | UDMA_PRI_SELECT);
            mic0BufferState_PRI = FILLING;
        }
        
        if (mic0BufferState_ALT == EMPTY)
        {
            MAP_uDMAChannelTransferSet(17 | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, 
                                       (void *)(ADC0_BASE + ADC_O_SSFIFO3), 
                                       &mic0Buffer_ALT, ADC_SAMPLES);
            
            MAP_uDMAChannelEnable(17 | UDMA_ALT_SELECT);
            mic0BufferState_ALT = FILLING;
        }
    }

    开始停止 SS3

    void start_ADC0_SS3()
    {
        MAP_ADCSequenceEnable(ADC0_BASE, 3);
        MAP_ADCIntClear(ADC0_BASE, 3);
        MAP_ADCSequenceOverflowClear(ADC0_BASE, 3);
        MAP_ADCSequenceUnderflowClear(ADC0_BASE, 3);
        MAP_ADCSequenceDMAEnable(ADC0_BASE, 3);
        MAP_ADCIntEnable(ADC0_BASE, 3); // Do I have to do that?
        MAP_IntEnable(INT_ADC0SS3); // Do I have to do that?
        
        MAP_TimerEnable(TIMER2_BASE, TIMER_A);
    }
    
    void stop_ADC0_SS3()
    {
        MAP_TimerDisable(TIMER2_BASE, TIMER_A);
        
        MAP_IntDisable(INT_ADC0SS3);
        MAP_ADCIntDisable(ADC0_BASE, 3);
        MAP_ADCSequenceDisable(ADC0_BASE, 3);
        MAP_ADCSequenceOverflowClear(ADC0_BASE, 3);
        MAP_ADCSequenceUnderflowClear(ADC0_BASE, 3);
        MAP_ADCIntClear(ADC0_BASE, 3);
        MAP_ADCSequenceDisable(ADC0_BASE, 3);
    }

    记录会再次开始并循环进行。 通常我不使用函数 STOP_ADC0_SS3()

    这是中断处理程序

    void ADC0SS3IntHandler(void)
    {
        MAP_ADCIntClear(ADC0_BASE, 3); // Do I have to do that?
        MAP_uDMAIntClear(17); // Do I have to do that?
        
        if (MAP_uDMAChannelModeGet(17 | UDMA_PRI_SELECT) == UDMA_MODE_STOP)
        {
            mic0BufferState_PRI = FULL;
        }
        
        if (MAP_uDMAChannelModeGet(17 | UDMA_ALT_SELECT) == UDMA_MODE_STOP)
        {
            mic0BufferState_ALT = FULL;
        }
    }

    每次通过 SPI 发送数据时、样本中都会产生强烈的噪声。

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

    您好!

     虽然我不能真正为您解决任何噪声问题、但我有一些可能会导致您看到的噪声的评论。  

     -我看到你在4.8Mhz 下运行4个 SPI 模块。 这会产生 SSO (同步开关输出)、后者会汲取大量电流并影响电压供应。 正确的去耦电容及其放置对于高速运行至关重要。

    #define SSI_CLOCK (4800000)

     -您正在使用 LaunchPad 板。 为简单起见、LaunchPad 将 ADC 的 VDDA 连接到 VDD。 换句话说、 数字电源上的任何噪声都会耦合到 ADC 的模拟电源、这将影响 ADC 的精度。 如果您要设计自己的电路板、我建议您将电源分为数字域和模拟域。 ADC VREFP 和 VREFN 在内部连接到 VDDA 和 GNDA。 VDD/GND 上的任何噪声或纹波都将跟随 VREF、从而跟随精度。  

     -我看到您将 CH5用于 ADC。 如果您愿意做一个实验、您可以尝试不同的 ADC 通道、或许可以用远离 SSI 模块的引脚来尝试、或降低 SSI_CLOCK 速度、看看它是否能缓解您的这一发现。 除此之外,我没有太多的机会。  

    MAP_ADCSequenceStepConfigure (ADC0_BASE、3、0、ADC_CTL_CH5 | ADC_CTL_IE |
    ADC_CTL_END);

    在创建自己的设计时、请仔细查看第4.5节中的 ADC 设计注意事项以及文档其余部分中的最佳设计实践。  

    https://www.ti.com/lit/pdf/spma059

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

    我已经对它进行了测试。 如果我发送时只有一个 SSI、2或3或4、几乎没有区别。 噪声已经出现在一次数据传输中、并被每次进一步的数据传输放大约5-6dB。

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

    我有另一个 EK-TM4C123GXL。
    如果我使用一个板进行 SPI 传输、使用另一个板记录样本。 然后、我能否将两个电路板彼此分离、从而不传输噪声?
    但板之间需要一个数据接口。 以便我可以传输数据。 我需要在电路板之间使用3-5个 GPIO 端口作为输入或输出。

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

    您好!

    如果我使用一个板进行 SPI 传输,而使用另一个板记录样本。 然后,我能否将两块主板彼此分开以便不传输噪声?

    我认为这会有所帮助、但我相信使用 VDDA 为 ADC 提供专用电源的分离电源轨将为您提供最佳性能。 您是否计划最终设计自己的电路板?

    3.5.4分离电源轨和接地

    Tiva C 系列微控制器设计为使用直接连接到同一+3.3V 电源的 VDD 和 VDDA 引脚工作。 一些应用可能会调整 VDDA 与 VDD 的间隔、从而允许插入滤波器以提高模拟性能。 在决定分离这些电源轨之前、应检查器件的电源架构、以确定每个电源为哪些片上模块供电。 器件数据表中包含一张展示电源架构的绘图。 滤波器选项包括与低值电阻器或电感器/铁氧体磁珠连接的滤波电容器、以构成低通滤波器。 如果 VDD 和 VDDA 引脚分开、设计人员必须确保在 VDD 之前或与 VDD 同时施加 VDDA 电源、并确保在 VDD 之后或与 VDD 同时移除 VDDA。 如果要选择 VDDA 作为 ADC 的基准源、则在使用单独的 VDDA 电源轨供电并在 VDDA 和 GNDA 之间使用0.01uF 和1uF 电容器(CREF)进行滤波时、ADC 将实现更好的性能。 GND 和 GNDA 引脚应始终连接在一起-最好连接到实心接地平面或覆铜。

    另请检查您的 PC 是否为电路板提供稳定的5V 电压。 同一台 PC 上的不同 PC 或不同 USB 端口是否会有所不同?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    请同时检查您的 PC 是否为电路板提供稳定的5V 电压。 同一台 PC 上的不同 PC 或不同 USB 端口是否会有所不同?

    我不使用 PC 上的 USB 作为电源。 我使用 https://www.meanwell.com/productPdf.aspx?i=410#1提供的230V 至5V 电源
    RS 100-5。

    您是否打算最终设计您自己的电路板?

    还没有。

    2年前、我开始嵌入式编程。 我喜欢它。 我的下一个目标是更深入地介绍 DSP。 为此,我买了这本书:

    bcs.wiley.com/.../Books
    它使用的正是这个板。
    带有音频编解码器的电路板正在重建中。
    这也是我使用2块电路板并不坏的原因。
    但在本书中、他还使用2个 SSI 来构建 I2S 数据传输。 我觉得这也很有趣。

    但我的问题又是。 在4.8Mhz 下使用1个或4个 SSI 无关紧要。 使用 SSI 时是否总是会出现此类噪声?
    或者、这是否正是因为我使用传输线路、并以这种方式滥用 SSI 连接?

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

    我只能说串扰 随传输频率的变化而变化、较高的频率会产生更多的干扰。  在较低的 SPI 时钟频率下、我预计 ADC SPI 上产生的任何噪声都 将降低。 ADC 的精度将受到 VDDA 的提供方式以及附近数字布线的单端输入上的噪声的影响。 与差分输入相比、单端输入对电路板和布线噪声更敏感。 单端输入在很大程度上取决于 电路板布局 设计的清洁程度。 如果电路板上的输入信号没有很好地隔离、则可能会在 ADC 输出端看到更高的噪声。 我已经建议、可以通过分离 ADC 的 VDDA 来提高 ADC 精度、并且可以使用差分 ADC 模式。 至于 LaunchPad、它就是现在的样子。