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.

[参考译文] 回复:回复:CCS/DK-TM4C129X:对六个 ADC 转换进行排序

Guru**** 2481875 points


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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/704796/re-re-ccs-dk-tm4c129x-sorting-six-adc-conversions

Bob、您好!

我很抱歉,因为我没有尽快回复。 我生病了一段时间... 是的、连续转换是可以接受的、因为它的时间偏移非常小。 我花了一些时间来实施您的建议并成功实施。 我使用乒乓模式从序列发生器0 FIFO 中捕获6个 ADC 样本、在 DMA 配置中输入1024的传输大小、并且能够以大约7.8uS 的偏移对6个通道进行采样、因为我将采样率设置为128KHz… 我要将1024大小的乒乓缓冲器分为6个分别为128大小的独立缓冲器、并对其中每个缓冲器执行 FFT。 结果几乎正确。 但缓冲器排序不正确、结果在缓冲器中不断变化。。。就像向3个输入提供方波、向3个输入提供正弦波... 我希望各自的缓冲器具有该波形...但它会发生变化...首先它具有方形、然后是正弦波...就像这样...因为我没有使用散聚。 下面是 SS0的配置方式以及如何从乒乓缓冲器(未排序)获取数据:

ADCSequenceStepConfigure (ADC0_BASE、0、0、ADC_CTL_CH2);
ADCSequenceStepConfigure (ADC0_BASE、0、1、ADC_CTL_CH3);
ADCSequenceStepConfigure (ADC0_BASE、0、2、ADC_CTL_CH0);
ADCSequenceStepConfigure (ADC0_BASE、0、3、ADC_CTL_CH1);
ADCSequenceStepConfigure (ADC0_BASE、0、4、ADC_CTL_CH14);
ADCSequenceStepConfigure (ADC0_BASE、0、5、ADC_CTL_CH15 | ADC_CTL_IE |
ADC_CTL_END);   

提取:

对于(m = 0;m < 128;m++)
{
fftin1[m]= g_ui8RxBufB[6*m];

fftin2[m]= g_ui8RxBufB[6*m+1];

fftin3[m]= g_ui8RxBufB[6*m+2];

fftin4[m]= g_ui8RxBufB[6*m+3];

fftin5[m]= g_ui8RxBufB[6*m+4]; 
fftin6[m]= g_ui8RxBufB[6*m+5]; }

但在上面,您说过使用散聚模式对6个不同缓冲区中的样本进行排序以进行开槽。 老实说,我现在不知道这种模式。 我将从数据表中了解这种模式,并尝试为此编写一些代码....

感谢您的所有帮助、...只是有一个小问题需要问...如果您或阅读此内容的任何其他人可以提供一些有关实施散聚的示例。

此致、

Harshul Agarwal

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

    我还有一个问题。 当我在单个序列发生器0上实现6个通道(无散聚)时、这是正常的。 但在此之前、我想使用3个序列发生器 SS0、1、2并在序列发生器中各放置2-2个通道、然后使用乒乓模式来捕获数据、这种情况并不能正常工作。 我不知道为什么这不起作用。 在此之前、我使用2个通道输入(注释掉所有其他序列发生器部件)单独测试了 SS0、1、2、每个序列发生器为2个通道提供了正确的输出。 但是、当将所有这些组合在一起以获取6个输入时、缓冲器未正确填充。

    我将 SS0的优先级设置为0、SS1的优先级设置为1、SS2的优先级设置为2。 但结果中、只有序列发生器2正确填充。 原因可能是什么? 我将随附此部件的代码: e2e.ti.com/.../7750.3seqcombined.c

    因此、我跳过了这种方法、然后继续仅使用1个序列发生器0和样本...如果有人可以澄清上述代码的原因以及可以采取哪些措施使其正常工作...只是为了澄清。

    谢谢、

    Harshul

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Harshul、
    您的排序可能无法正常工作、因为您的缓冲区大小(1024)不是6的偶数倍。 缓冲器大小为768、可分为6个缓冲器、每个缓冲器128个样本。 使用1024的缓冲区大小意味着当 DMA 开始填充第二个缓冲区时、存储的前两个值将是样本5和6、而不是样本1和2。 (第一个缓冲区将包含170次采样1、2、3、4、5、6;然后采样1、2、3、4。 (170*6)+4=1024。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    是的、你是对的。 我尝试将所有8个输入用于 序列发生器0、以便最后两个通道接地。 那么、使用以下代码从缓冲区中提取数据:

    对于(m = 0;m < 128;m++)
    {
    fftin1[m]= g_ui8RxBufB[8*m];
    
    fftin2[m]= g_ui8RxBufB[8*m+1];
    
    fftin3[m]= g_ui8RxBufB[8*m+2];
    
    fftin4[m]= g_ui8RxBufB[8*m+3];
    
    fftin5[m]= g_ui8RxBufB[8*m+4];
    
    fftin6[m]= g_ui8RxBufB[8*m+5];
    } 

    即使这样也不会产生正确的结果。 排序仍然不正确?

    ADC 序列发生器配置:

    ADCSequenceConfigure (ADC0_BASE、0、ADC_TRIGGER_TIMER、0);
    
    ADCSequenceStepConfigure (ADC0_BASE、0、0、ADC_CTL_CH2);
    ADCSequenceStepConfigure (ADC0_BASE、0、1、ADC_CTL_CH3);
    ADCSequenceStepConfigure (ADC0_BASE、0、2、ADC_CTL_CH0);
    ADCSequenceStepConfigure (ADC0_BASE、0、3、ADC_CTL_CH1);
    ADCSequenceStepConfigure (ADC0_BASE、0、4、ADC_CTL_CH14);
    ADCSequenceStepConfigure (ADC0_BASE、0、5、ADC_CTL_CH15);
    ADCSequenceStepConfigure (ADC0_BASE、0、6、ADC_CTL_CH12);
    ADCSequenceStepConfigure (ADC0_BASE、0、7、ADC_CTL_CH13 | ADC_CTL_IE |
    ADC_CTL_END);
    

    此致、

    Harshul

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    "移动到仅使用1个序列发生器0和采样"

    现在是否已充分理解此处讨论的内容不能解决您的问题(原始问题?) 问题? 也就是说、没有哪种方法可以同时提供6个 ADC? 事实上,情况正好相反:您所说的是按顺序获取6个 ADC 输入(如***不能***同时获取)。

    只是想指出、如果错过了最初的目标、
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    是的、我知道最多可以同时对2个输入进行采样。 我和我的高级主管讨论了这个问题、他说按顺序是可以的、因为这样会有非常少的冒犯。 因此、我继续操作、仅使用1个序列发生器。

    现在、我有一个问题。 在 ADC 中断处理程序中、如果我注释掉检查缓冲区是否已满的部分、然后重新启用缓冲区进行 nxt 传输、则缓冲区会被一次性填充、并且正确填充和排序。 但是、我需要持续地使用这种数据、以便我可以定期处理和显示这些数据。 但通过注释、缓冲区中的数据会不断变化。 我正在处理处理程序中的数据:

    void ADCseq0Handler()
    
    {
    uint32_t ui32模式;
    uint32_t d、m;
    
    //清除由 DMA 引起的 ADC 序列0中断
    ADCIntClearEx (ADC0_BASE、ADC_INT_DMA_SS0);
    
    
    //检查 uDMA 主控制结构当前模式
    ui32Mode = uDMAChannelModeGet (UDMA_CHANGE_ADC0 | UDMA_PRI_SELECT);
    
    //如果 UDMA 主控制结构体完成了数据传输,请重新启用它
    if (ui32Mode = uDMA_MODE_STOP)
    {
    //6个采样输入从乒乓缓冲器中提取
    对于(m = 0;m < 128;m++)
    {
    fftin1[m]= g_ui8RxBufA[8*m];
    
    fftin2[m]= g_ui8RxBufA[8*m+1];
    
    fftin3[m]= g_ui8RxBufA[8*m+2];
    
    fftin4[m]= g_ui8RxBufA[8*m+3];
    
    fftin5[m]= g_ui8RxBufA[8*m+6];
    
    fftin6[m]= g_ui8RxBufA[8*m+7];
    }
    FFT();
    uDMAChannelTransferSet (UDMA_CHANGE_ADC0 | UDMA_PRI_SELECT、
    
    UDMA_MODE_PINGONG、
    
    (void *)(ADC0_BASE + ADC_O_SSFIFO0)、
    
    G_ui8RxBufA、MEM_buffer_size);
    
    uDMAChannelEnable (UDMA_CHANGE_ADC0);
    
    }
    
    //检查 uDMA 次级控制结构电流模式
    ui32Mode = uDMAChannelModeGet (UDMA_CHANGE_ADC0 | UDMA_ALT_SELECT);
    
    //如果 UDMA 次级控制结构体完成了数据传输,请重新启用它
    if (ui32Mode = uDMA_MODE_STOP)
    
    {
    uDMAChannelTransferSet (UDMA_CHANGE_ADC0 | UDMA_ALT_SELECT、
    
    UDMA_MODE_PINGONG、
    
    (void *)(ADC0_BASE + ADC_O_SSFIFO0)、
    
    G_ui8RxBufB、MEM_buffer_size);
    
    uDMAChannelEnable (UDMA_CHANGE_ADC0);
    
    }
    }
    
    void FFT()
    {
    uint32_t i;
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    (uint32_t j、k;for (i = 0;i < 128;i++){testInput_F32_10kHz[2 * i]=(testat32_t) fftin1[i];//else testInput_F32_10kHz[2
    
    ;float32_I +1]= 0;testin2*1032_I =1032_I =1032_1*3*3*1[floati]+[f32_1*1032_1*1*1*1*1*1*1*1*1*1*1*1*1*1*1*1*1*1*1*1*1*1*1*1*1*1*1*1*1*1*1*1*1*1*1*1*1*1*1*1*1*0*0*1*1*0*0*0*1*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*
    
    
    //else
    testInput_F32_10khz4[2*I + 1]= 0;
    
    testInput_F32_10khz5[2*i]=(float32_t) fftin6[i];
    //else
    testInput_F32_10khz5[2*I +1]= 0;
    }
    //通过
    32位 FFT_CFtFlag_ARM (* F32_F32_FtFtFtFtFlag_Ft32_FtFtFtFtFtFt32_FtFtFtFtFtFtFtFtFt32_FtFtFtFt)处理数据
    ; testInput_F32_10khz1、ifftFlag、doBitReverse);
    ARM_CFFT_F32 (&ARM_CFFT_SR_F32_len128、testInput_F32_10khz2、 ifftFlag、doBitReverse);
    arm_CFFT_F32 (&arm_CFFT_SR_F32_len128、testInput_F32_10khz3、ifftFlag、 doBitReverse);
    arm_CFFT_F32 (&arm_CFFT_SR_F32_len128、testInput_F32_10khz4、ifftFlag、doBitReverse);
    ARM_CFFT_F32 (&ARM_CFFT_SR_F32_len128、testInput_F32_10khz5、ifftFlag、doBitReverse);
    //通过复数幅度模块处理数据以
    计算每个 bin 的幅度*/
    ARM_cmplx_mag_F32 (testInput_F32_10kHz、Output1kHz、Output1_TestSize、Output32_Ft32_MG_1);testInput_Output32_Output1
    fftSize);
    arm_cmplx_mag_F32 (testInput_F32_10khz2、testOutput2、fftSize);
    arm_cmplx_mag_F32 (testInput_F32_10khz3、 testOutput3、fftSize);
    arm_cmplx_mag_F32 (testInput_F32_10khz4、testOutput4、fftSize);
    arm_cmplx_mag_F32 (testInput_F32_10khz5、testOutput5、fftSize);
    TestOutput[0]= 0;
    testOutput1[0]= 0;
    testOutput2[0]= 0;
    testOutput3[0]= 0;
    testOutput4[0]= 0;
    testOutput5[0]= 0;
    //计算 maxValue 并返回相应的 bin 值*/
    arm_max_F32 (TestOutput、fftSize、&Value、&testIndex);
    arm_max_F32 (maxOutput1、maxOutput1 fftSize、maxValue1、&testIndex1);
    arm_max_F32 (testOutput2、fftSize、 maxValue2、&testIndex2);
    arm_max_F32 (testOutput3、fftSize、&maxValue3、 &testIndex3);
    arm_max_F32 (testOutput4、fftSize、&maxValue4、&testIndex4);
    arm_max_F32 (testOutput5、fftSize、&maxValue5、&testIndexx5);
    
    maxValue =(maxValue*3.3/64.0)/4096.0;
    maxValue1 =(maxValue1 * 3.3/64.0)/4096.0;
    maxValue2 =(maxValue2 * 3.3/64.0)/4096.0;
    maxValue3 =(maxValue3 * 3.3/64.0)/4096.0;
    maxValue4 =(maxValue4 * 3.3/64.0)/4096.0
    =(maxValue3 * 3.3/64.0
    );maxValue5 =(max404.0) 

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

    "所以、我继续只使用1个序列发生器。"

    在这种情况下、如果您使用正确的主题行启动新主题、可能会对您的原因有所帮助:如果有人跳过此讨论、因为他们认为该主题毫无帮助、这并不奇怪。

    通过设置正确的主题行、您将有更好的机会让更多的人参与帮助您找到问题的解决方案。

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

    [引用用户="Danny F]现在是否充分理解此处讨论的内容不是解决您的(原始?)问题? 问题? IE、所有方法都不会同时提供6个 ADC?[/QUERT]

    虽然这(几乎)是正确的-没有(第一个 I)、然后(您)注意到六个独立(外部) ADC IC (甚至6个 MCU)(如果它们可以正确地"同步")可以实现海报的目标吗?

    "立即质疑(仅限)同步 ADC 转换"(严格)要求的问题-并生成"无海报响应!"   

    该线程已进一步转移到数据排序工作中、正如您所注意到的、"需要六个线程"已经"很长-离开了大楼!"

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

    进行 FFT 计算所需的时间是否可能长于 ADC/uDAM 填充缓冲器的时间? 您可能需要将 FFT 计算移出中断例程。 如果在 ADC/UDMA 填满第二个缓冲区时仍在中断例程中、您将会错过样本、因为您不会及时重新启动 UDMA。 通过使用静态易失性标志来显示缓冲器状态、您可以将 FFT 计算移至主函数的无限循环中。 (有关使用静态易失性标志的示例、请参阅附加的工程。) 您可能需要切换一些 I/O 引脚以测量 FFT 计算所需的时间、并将其与 UDMA 中断之间的时间进行比较。

    /cfs-file/__key/communityserver-discussions-components-files/908/0564.ADCwDMA.zip

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我继续将这一主题拆分、并按照 Danny 和 CB1的建议重新命名。 第一部分是:
    e2e.ti.com/.../703428
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Bob、

    向您致敬-多个"编码钥匙/辅助工具/方法"存在-您的(灵感)发帖!    太棒了!    我们特别注意:(并且愿意-如果(仍然)有可能...)

    Bob 的指导原则非常简洁、"在使用 µDMA 填充多个(此处两个)缓冲区的同时、进行合理密集的计算"。

    • 将 FFT (或其他)计算移中断例程。  
    • 在"ISR"(可能)中长时间"延迟"将导致"重复采样"-因为 UDMA 可能  会"及时"重新启动。
    • 使用"静态易失性标志"来显示缓冲器状态-可以  更好地将 FFT 计算(或其他)置于 无限循环中-在 'main'中。
    • "切换 I/O 引脚"可立即 测量计算的执行时间( 此处为 FFT 持续时间) 、并便于 将该时间与 μ µDMA 中断之间的时间进行比较。

    我已随意(非常轻微)重新措辞-并将您的导游安排在年轻人青睐的"子弹"中。    (员工和我感谢您周到而有效的努力...)    (本指南将"侵入"我们的"操作手册"。)

    如果这种"整合"违反了一些(鲜为人知的)规则/法规- PM ME -我将"轮档"。    (实践良好的目的地-(大部分) CB1工作...)

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

    很抱歉、每个人都在这个主题中制造混乱。

    非常感谢 Bob 澄清了可能是问题的原因。 我一定会浏览您所连接的示例项目、并尝试使用静态易失性标志、并将我的 FFT 例程移至 while 循环。 如果我取得任何进展、我肯定会在该主题中更新。  

    谢谢你

    Harshul

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您必须确保'FFT 例程'(while 循环)是'在任何 ISR 之外'。
    您已经"无乱"、而是"吻"规定每个线程(仅)一个主题推力、证明"理解最简单、最高效"、并在(稍后)"插入"时找到。 祝您有机会...
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    从 ISR 内部运行长例程通常是不明智的-这样做毫无意义。

    至于 FFT 例程、您应该使用仿真值对其进行调试。 例如、在已知频率/振幅参数内生成一组数据、以便您确定 FFT 例程是否返回正确的值。

    现在、你只是有太多东西卷积在一起、无法知道是什么问题。

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

    嘿 CB1、我现在已经确保了我的 FFT 例程不在中断处理程序中。 我修改了代码并使用了 Bob 建议的静态易失性标志(感谢 Bob :D),现在我能够生成所需的输出。 感谢大家的到来和对我的帮助。

    是的、Buena suerte MI Amigo!!

    此致、
    Harshul

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    是的、Danny、这是一种错误的方法。 现在、我已经正确实现了它。 在到达该6通道处理之前、我已经测试了所有内容。 我测试了 FFT 例程、具有 DMA 的单通道 ADC、2个通道及其 FFT (在 ISR 中正常工作、过程很小)。 因此、对于6个通道、我没有想到它、并且毫无考虑地将 FFT 例程放入 ISR 中。

    此致、
    Harshul