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.

[参考译文] TM4C123GH6PM:差分模式下的 TM4C123 ADC

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/721700/tm4c123gh6pm-tm4c123-adc-in-differential-mode

器件型号:TM4C123GH6PM
主题中讨论的其他器件: TM4C123

大家好、

使用 TM4C123GH6PM 定制板的 IAM。 IAM 尝试在差分模式下使用内部 ADC、但在某种程度上、当我使用多个 ADC 引脚时、我的 ADC 输出不能正确。

我遵循 ADC 差分示例、它适用于使用采样序列发生器0的单通道。

但是,当我将多个引脚与采样序列发生器2一起使用时,ADC FIFO 结果不正确,因为 IAM 仅在上获得信号   

ui32ADC0Value[0] 
ui32ADC0Value[1]显示的结果不正确。 

IA 将首先测试两个输入通道。


 以下是我的代码。 IAM 使用计时器触发 ADC、采样率为256Hz

#include 
#include 
#include 
#include 
#include "inc/tm4c123ghp6.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_gpio.h"
#include "driverlib/pinc.h"
#driverlib/samplesido.dipt.ide"


#include "driverlib/outputt.ido#include "out32"






;#driveript/outputt.idio.idt.idt.ide"#include "out32_outputt/udesnategr.idio.idt.ide"#include "outputt.idr32_outputt.idr.idr.idr.idr.idr.idr.idr.idr.idr.ide"#include "out32_outputt.idr.idr.idr.idr.idr.idr.idr.idr.idr.idr.idr.idr.idr.idr.idr.idr.idt.idr.idr.idr./






void Timer0IntHandler (void)
{
TimerIntClear (TIMER0_BASE、TIMER_TINA_TIMEOUT);
//GPIOPinWrite (GPIO_PORTB_BASE、GPIO_PIN_3、0xFF);
ADCSequenceConfigure (ADC0_BASE、2、ADC_TRIGGER_TIMER、0);

//m=m+1;
}


int main (void)
{



// uint32_t ui32ADC0Value[8];
uint32_t ui32Period;




SysCtlClockSet (SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHz);// 80MHz 时钟

ui32SysClkFreq = 8000000;

/******* 引脚 INTILIAZATION ********* /

SysCtlPeripheralEnable (SYSCTL_Periph_GPIOE);

while (!(SysCtlPeripheralReady (SYSCTL_Periph_GPIOE)));

GPIOPinTypeADC (GPIO_Porte _BASE、GPIO_PIN_3|GPIO_PIN_2|GPIO_PIN_1_GPIO_PIN_0);

SysCtlPeripheralEnable (SYSCTL_Periph_GPIOD);

while (!(SysCtlPeripheralReady (SYSCTL_Periph_GPIOD)));

HWREG (GPIO_PORTD_BASE_GPIO_O_O_LOCK)= GPIO_LOCK_KEY;

HWREG (GPIO_PORTD_BASE_GPIO_O_O_CR)|= GPIO_PIN_7;

GPIOPinTypeADC (GPIO_PORTD_base、GPIO_PIN_3|GPIO_PIN_2|GPIO_PIN_1_GPIO_PIN_0);

/******* ADC INTILIAZATION ********** /

SysCtlPeripheralDisable (SYSCTL_Periph_ADC0);

SysCtlPeripheralReset (SYSCTL_Periph_ADC0);

SysCtlPeripheralEnable (SYSCTL_Periph_ADC0);

while (!(SysCtlPeripheralReady (SYSCTL_Periph_ADC0)));



ADCSequenceDisable (ADC0_BASE、2);

ADCSequenceStepConfigure (ADC0_BASE、2、0、ADC_CTL_D|ADC_CTL_CH0);
ADCSequenceStepConfigure (ADC0_BASE、2、1、ADC_CTL_D|ADC_CTL_CH1);
ADCSequenceStepConfigure (ADC0_BASE、2、ADC_CTL_D|ADC_CTL_CH2);
ADCSequenceStepConfigure (ADC0_BASE、2、3、ADC_CTL_D|ADC_CTL_CH3|ADC_CTL_IE|ADC_CTL_END);

ADCSequenceEnable (ADC0_BASE、2);

/******* TIMER0 INTILIAZATION ******** /
SysCtlPeripheralEnable (SYSCTL_Periph_TIMER0);

TimerConfigure (TIMER0_BASE、TIMER_CFG_PERIODICASE);

ui32Period = 80000000/256;

TimerLoadSet (TIMER0_BASE、TIMER_A、ui32Period-1);

TimerControlTrigger (TIMER0_BASE、TIMER_A、TRUE);

IntEnable (INT_TIMER0A);

TimerIntEnable (TIMER0_BASE、TIMER_TINA_TIMEOUT);

TimerEnable (TIMER0_BASE、TIMER_A);
IntMasterEnable();

while (1)
{
ADCIntClear (ADC0_BASE、2);


while (!ADCIntStatus (ADC0_BASE、2、false))
{
}
ADCSequenceDataGet (ADC0_BASE、2、ui32ADC0Value);
outputsamples1 = ui32ADC0Value[0];
outputsamples2 = ui32ADC0Value[1];
outputsamples3 = ui32ADC0Value[2];
outputsamples4 = ui32ADC0Value[3];

}
} 

请建议解决方案。

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

    您好、Sumit、

     该值比预期的值多大?

     我不确定您是否已达到以下勘误表。 对于实验、您能否尝试不使用 PE3并查看它是否起作用?

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

    我尝试不使用 PE3引脚、但它没有产生任何影响。

    第一个 FIFO (即 ui32ADC0Value[0])的输出也会传入另一个 FIFO 中。

    我的设置是 IAM 在不同的引脚 PE1、PE0 (CH1)和 PD3、PD2 (CH2)上提供不同频率(10Hz 和60Hz)的两个正弦波。 但是、在两个通道中、输出是相同的。 连接到 PE1、PE0 (CH1)的正弦波也会显示在第二个通道(CH2)中、因为当我更改 PE1、PE0信号的频率时、PD3、PD2的信号也会相应地发生变化。 但是、如果我更改其自己的频率或振幅、则 PD3、PD2信号没有变化。

    我在这里真的迷路了!! 是否有在差分模式下使用多个 ADC 引脚的示例?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 USER="Sumit Mourya]ADCSequenceDataGet (ADC0_BASE、2、ui32ADC0Value);[/引用]

    “最终”参数(正确)不应该是“ &ui32ADC0Value”?

    此外-您(真的)是否向 MCU 提供"适当平衡"的差分信号?   您能否描述(如何)您"创建和/或提供"此类信号?   这些信号必须保持在 MCU 的共模电压范围内-但实际上应该是"可作为基准的"-而不是"接地参考的"。

    您必须注意、"在差分模式下-这2个通道中的每个通道之间的"差异"必须保持为 适当的"等于或小于 VDD 或 VDDA"。  (即、这些模拟通道中的任何一个都不能超过 VDD 或 VDDA 的一半。)

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

    在合规期间、它会向我发出警告。

    说明资源路径位置类型
    "uint32_t (*)[4]”类型的#169-D 参数与"uint32_t *"类型的参数main.c/PC COMM第204行C/C++问题不兼容
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    是的、IAM 提供正确的输入、因为当我使用单通道 FIFO (采样序列发生器0)测试不同的输入时、IAM 会针对不同类型的输入获得正确的结果。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    那么-您是如何确定它的、
    uint32_t ui32ADC0Value[4];是否正确?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    问题是 ADC 仅提供一个 FIFO ui32ADC0Value[0]的输出。 ui32ADC0Value[1]的作用就像它的开路信号一样。 它未读取第二个通道上的输入。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 user="Sumit Mourya"]对于不同类型的输入,IAM 获得正确的结果。

    您将"提供"您的"信仰"(正确结果)、以代替真实的证据!   这不是有效的参数。

    怀疑您的"正弦波"是单端的-不是差分的。  (差分正弦波看起来呈180°异相、需要(适当)模拟处理来生成此类信号。

    尽管如此-您的代码(已识别)不正确。  (最终参数-如前所述)

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    当我在 CH0 (PE3和 PE2)上连接一个假设为20Hz 的正弦波时,我在输出中得到20Hz 的实际信号。 现在,当我在 CH0 (PE3和 PE2)上连接100Hz 的正弦波时,我再次将正确的100Hz 信号作为输出。

    现在、当我在 CH0 (PE3、PE2)上连接20Hz、在 CH1 (PE1、PE0)上连接100Hz 时、我只会在两个通道上获得20Hz 的输出信号!! 如果我相反地在 CH0上连接100Hz、在 CH1上连接20Hz、那么我将仅获得100Hz 作为输出。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!

    我甚至尝试在差分模式下使用多个 ADC 引脚记录我的 ECG、脉冲、呼吸类型生物电势信号。 在单通道中、我将正确获取我的 ECG、脉冲、呼吸所有信号。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    差分信号"极抗噪声"-在医疗应用中永远不会采用单端测量!

    ADC 旨在测量电压电平-但您只报告频率测量! 减去您的详细信息-这表示对(任何) ADC 的操作"缺乏理解"。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!

    我不在此讨论您或我对 ADC 或差分信号的理解程度。 您在我的代码中的建议是给我警告错误、这是不正确的。

    我只想问一个使用多个通道的差分 ADC 模式示例。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢您(现在)列出"有限条件"-在此条件下您请求帮助!   (外交-不是太多-证据。)
    尽管如此:

    请尝试用 uint32_t ui32ADC0Value[4]替换(您的) uint32_t ui32ADC0Value 并报告...   承认[4]的重要性,但正在寻求进一步的见解。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    如果我用 uint32_t ui32ADC0Value[4]替换 uint32_t ui32ADC0Value,我将如何区分或存储变量中的不同 FIFO 值?

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

    我已经使用了挖掘 K&R -和"重新阅读第5.3章节"指针和数组"。

    先前的方向-采用  从此 供应商 的"外设驱动程序库-用户指南!"中流出(直接)的 ui32ADC0Value (&U)

    我(现在)认为上述内容应改为* ui32ADC0Value。   

    K&R 注意到,后续赋值: (假设)  x = * ui32ADC0Value  将 把 ui32ADC0Value[0]的内容复制 到 x 中

    请尝试一下-并报告。   如果成功-供应商的'PDL 用户指南'中提供的示例 出错-(我们的)共同努力显示了这种错误-此处...

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

    您好!

    您好!
    ui32ADC0Value 是一个包含4个元素的数组、因此它是一个指针。 因此、ADCSequenceDataGet 行(ADC0_BASE、2、ui32ADC0Value)正常。

    我将再次读取您的代码。 还会回来的

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

    您好!

    您能更改一下

    发件人:

                  ADCSequenceStepConfigure (ADC0_BASE、2、0、ADC_CTL_D|ADC_CTL_CH0);

                  ADCSequenceStepConfigure (ADC0_BASE、2、1、ADC_CTL_D|ADC_CTL_CH1);

                  ADCSequenceStepConfigure (ADC0_BASE、2、ADC_CTL_D|ADC_CTL_CH2);

                  ADCSequenceStepConfigure (ADC0_BASE、2、3、ADC_CTL_D|ADC_CTL_CH3|ADC_CTL_IE|ADC_CTL_END);

    至:

                  ADCSequenceStepConfigure (ADC0_BASE、2、0、ADC_CTL_D|ADC_CTL_CH0);

                  ADCSequenceStepConfigure (ADC0_BASE、2、1、ADC_CTL_D|ADC_CTL_CH1|ADC_CTL_IE|ADC_CTL_CTL_END);

    请阅读 driverlib 用户指南中有关差分模式的说明。 ADC_CTL_CHO 用于 AIN0/AIN1对、而 ADC_CTL_CH1用于 AIN2/AIN3对。

    ui32Step 参数决定了 ADC 在何时捕获样本的顺序
    触发发生。 对于第一个采样序列发生器、它的范围可以是0到7、从0到3
    对于第二个和第三个采样序列发生器、第四个采样序列发生器只能为零。

    差分模式仅适用于相邻的通道对(例如0和1)。 通道选择
    必须是要采样的通道对的编号(例如、ADC_CTL_CH0表示0和1、或)
    ADC_CTL_CH1表示2和3)或未定义的结果由 ADC 返回。 此外、IF 差分
    当温度传感器被采样时、选择 MODE、返回未定义的结果
    电压。

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

    AHA -很好地让"供应商参与" (我的一半草坪现在(几乎)被割了!)

    但查尔斯-您必须注意- 只有 您的"非常详细的感觉" (在被告知此类问题后)才会透露此类"意外组合!"    为了捍卫这份原始海报-您的建议"立即唤醒"-然而(几乎)每个人都可能会遇到这样(高)的细节。   (不是差分 ADC 示例-像"一样"的(不必要)"求值者)   (我们知道您没有工作、但仍在...)

    但请注意 、变量确实  显示在 PDL 用户指南中-也显示在早期 Stellaris 用户指南中-并且(确实)显示在与 K&R 的"我读"冲突中

    附件- PDL 用户指南的"真实副本"、ADC 示例:  ("冲突"显示在此 (粘贴) PDL 代码的最后一行中!)

    (三
    uint32_t ui32Value;
    //
    //启用 ADC0模块。
    //
    SysCtlPeripheralEnable (SYSCTL_Periph_ADC0);
    //
    //等待 ADC0模块准备就绪。
    //
    while (!SysCtlPeripheralReady (SYSCTL_Periph_ADC0))


    //
    //启用第一个采样序列发生器,以便在发生处理器触发时捕获通道0的值。
    //
    ADCSequenceConfigure (ADC0_BASE、0、ADC_TRIGGER_PROCESSOR、0);
    ADCSequenceStepConfigure (ADC0_BASE、0、0、ADC_CTL_IE | ADC_CTL_END | ADC_CTL_CH0);
    ADCSequenceEnable (ADC0_BASE、0);
    //
    //触发采样序列。
    //
    ADCProcessorTrigger (ADC0_BASE、0);
    //
    //等待采样序列完成。
    //
    while (!ADCIntStatus (ADC0_BASE、0、false))


    //
    //从 ADC 读取值。
    //
    ADCSequenceDataGet (ADC0_BASE、0、\ui32Value);

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

    在下面显示的代码中、ui32Value 是一个无符号整数变量、因此、&ui32Value 是变量的指针。
    uint32_t ui32Value;

    在 OP 代码中、他具有:
    uint32_t ui32ADC0Value[4];

    ui32ADC0Value 声明为数组。 在第99页的 K&R 中,它指出数组的名称是初始元素位置(指针)的同义词。 因此、ui32ADC0Value[0]等效于 ui32ADC0Value。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    抱歉-我无法完全理解 PDL 示例是否正确或错误的"是或在哪里"。 而且-我已将海报从 ui32ADC0Value 中移除[4]-但仍然如此-他报告了"代码浪费"。

    注意-最初将海报(仅限) ui32ADC0Value -(减去 PDL &)-用于编译器的 squark。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 CB1、
    两者都正确。 PDL 中显示的示例声明一个无符号 int 变量、而海报的原始代码声明一个4元素数组。 我说的是、数组本身相当于指针。 如果要声明 PDL 示例中所示的 int 变量、则需要使用&进行拼写检查、使其成为指针。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Charles、

    我已经尝试过这样做。 我已经尝试使用差分对0和1 (PE3、PE2- PE1、PE0)以及差分对1和2 (PE1、PE0-PD3、PD2)。

    ADCSequenceStepConfigure (ADC0_BASE、2、0、ADC_CTL_D|ADC_CTL_CH0);

    ADCSequenceStepConfigure (ADC0_BASE、2、1、ADC_CTL_D|ADC_CTL_CH1|ADC_CTL_IE|ADC_CTL_CTL_END);



    ADCSequenceStepConfigure (ADC0_BASE、2、0、ADC_CTL_D|ADC_CTL_CH1);

    ADCSequenceStepConfigure (ADC0_BASE、2、1、ADC_CTL_D|ADC_CTL_CH2|ADC_CTL_IE|ADC_CTL_IE|ADC_CTL_END);


    但问题仍然相同。 您能否尝试在差分模式下使用 ADC 的多个引脚并查看您获得的结果?

    您以前是否听说过此问题或尝试使用过此问题?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Charles、

    现在好了-谢谢。 这里有“任何”的前身-(很漂亮)早。

    海报的原始代码包含:

    uint32_t ui32ADC0Value[4];
    //并随后跟随该操作
    ADCSequenceDataGet (ADC0_BASE、2、ui32ADC0Value);

    并且-该代码正确地管理了指针... 然而、海报报告说它未能产生正确的 ADC 值! 然后、在某个地方-我"失去了"代码正确性的事实-从未/从未感应到差分模式将被"压缩"-正如您发现和展示的那样。

    同样、为了帮助所有未来的"其他人"-谁可能发动这样的差别竞争-您的"示例"代码(此处)应该很容易找到/提供-
    恐怕(其他)无电客户端用户-进入差动 ADC 模式(beckoning) Cliff-side!   (这是一条(非常)长的路-向下!)

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

    使用以下代码、您从 ui32ADC0Value[0]和 ui32ADC0Value[1]中读取了什么内容? 您之前是否曾说过 ui32ADC0Value[0]将返回与 AIN0/AIN1对对应的正确值、但 ui32ADC0Value[1]将显示为 ADC 输入为开路。

    ADCSequenceStepConfigure (ADC0_BASE、2、0、ADC_CTL_D|ADC_CTL_CH0);

    ADCSequenceStepConfigure (ADC0_BASE、2、1、ADC_CTL_D|ADC_CTL_CH1|ADC_CTL_IE|ADC_CTL_CTL_END);

    2.如果您按如下所示的顺序颠倒、您将从 ui32ADC0Value[0]和 ui32ADC0Value[1]中读取什么内容? ui32ADC0Value[0]是否仍会显示与 AIN2/AIN3对相对应的正确值?

    ADCSequenceStepConfigure (ADC0_BASE、2、0、ADC_CTL_D|ADC_CTL_CH1);

    ADCSequenceStepConfigure (ADC0_BASE、2、1、ADC_CTL_D|ADC_CTL_CH0|ADC_CTL_IE|ADC_CTL_END);

    3.当您调用 ADCSequenceDataGet 时,它返回了什么? API 将返回复制到缓冲区的样本数。

    4.我不确定您在下面的定时器中断 ISR 中尝试执行什么操作。 为什么要在此处更改 ADC 触发器类型? 线路 ADCSequenceConfigure (ADC0_BASE、2、ADC_TRIGGER_TIMER、0)应该是 ADC 初始化的一部分。 为什么要等到计时器中断 ISR 进行配置。 尽管这可能不是问题的原因、但请将此行移至进行 ADC 初始化的位置。

    空 Timer0IntHandler (空)

    TimerIntClear (TIMER0_BASE、TIMER_TINA_TIMEOUT);
    //GPIOPinWrite (GPIO_PORTB_BASE、GPIO_PIN_3、0xFF);
    ADCSequenceConfigure (ADC0_BASE、2、ADC_TRIGGER_TIMER、0);

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

    您好、Charles、

    只是想更新我的问题已解决。 我最初编写的代码是正确的。 在我的.Net 代码中分析 ADC 的输出时出现问题。

    我想回答您的第四个问题、即我通过计时器触发 ADC、因为我已将 ADC 的采样率调整为256Hz。 如果我执行处理器触发、则 TM4C123中的采样率将默认为1MSPS。

    因此、我将计时器计数保持为 MCU 时钟/256 (时钟/所需的采样率)。 因此、每次触发计时器中断时、它都会进一步触发 ADC 进行转换。

    感谢您的建议!

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Sumit、
    很高兴您的问题得到解决。