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.

[参考译文] TM4C129ENCPDT:即使硬件过采样设置为最大值、ADC 也会产生很大的噪声

Guru**** 2501695 points
Other Parts Discussed in Thread: TM4C129ENCPDT

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1549675/tm4c129encpdt-adc-very-noisy-even-if-hardware-oversample-set-to-maximum

器件型号:TM4C129ENCPDT


工具/软件:

我有一个 TM4C129ENCPDT 处理器以 60MHz 采样电压运行、形成铅酸电池、样本非常尖峰。

我使用精密 3V 基准、并在 15MHz 上运行 ADC 时钟。

启用硬件过采样或增加采样保持周期似乎没有什么区别。

以下是使用 15MHz 采样时钟且无硬件过样(蓝色)时的默认样本设置捕获、然后是使用 32 个硬件样本(橙色)时的相同波形样本。

如果我将外部 Arduino 处理器连接到相同的电压、我会得到一个干净的波形、请参见下面的蓝色波形。

我添加了一些代码、允许我指定 ADC 时钟并根据我的系统时钟 60MHz 计算适当的分频值

ADCdivisor = ui32SysClock / ADC_CLK_SPEED;
ADCrate    = ADC_CLOCK_RATE_FULL;
ADCclock   = ui32SysClock / ADCdivisor;
if (ADCdivisor > 64)
{
	ADCrate    = ADC_CLOCK_RATE_HALF;
	ADCdivisor = ui32SysClock / ADC_CLK_SPEED / 2;
	ADCclock   = ui32SysClock / ADCdivisor / 2;
	if (ADCdivisor > 64)
	{
		ADCrate    = ADC_CLOCK_RATE_FOURTH;
		ADCdivisor = ui32SysClock / ADC_CLK_SPEED / 4;
		ADCclock   = ui32SysClock / ADCdivisor / 4;
		if (ADCdivisor > 64)
		{
			ADCrate    = ADC_CLOCK_RATE_EIGHTH;
			ADCdivisor = ui32SysClock / ADC_CLK_SPEED / 8;
			if (ADCdivisor > 64)
			{
				ADCdivisor = 64;
			}
			ADCclock   = ui32SysClock / ADCdivisor / 8;
		}
	}
}
else if (ADCdivisor == 0)
{
	ADCdivisor = 1;	
	ADCclock   = ui32SysClock;
}
rprintf("Sysclock %d Divisor %d ADC Clock %d\r\n", ui32SysClock, ADCdivisor,  ADCclock);
// ADC Clock can only be set on 
ADCClockConfigSet(ADC0_BASE, ADC_CLOCK_SRC_PLL | ADCrate,  ADCdivisor);

ADC 初始化为

// Initialisation
ADCClockConfigSet(ADC0_BASE, ADC_CLOCK_SRC_PLL | ADCrate, ADCdivisor);
ADCHardwareOversampleConfigure(ADC0_BASE, 32);
ADCSequenceDisable(ADC0_BASE, 1);
ADCSequenceConfigure(ADC0_BASE, 1, ADC_TRIGGER_PROCESSOR, 0);
ADCSequenceStepConfigure(ADC0_BASE, 1, 0, ADC_CTL_CH13 | ADC_CTL_IE | ADC_CTL_END); // Battery Volts
ADCSequenceEnable(ADC0_BASE, 1); //Enable the ADC

采样循环重复以下内容:

ADCIntClear(ADC0_BASE, 1);          //Clear Interrupt to proceed to next data capture
ADCProcessorTrigger(ADC0_BASE, 1);  //Ask processor to trigger ADC
if (ADCIntStatus(ADC0_BASE, 1, false))
{
    ADCSequenceDataGet(ADC0_BASE, 1, RawAnalogOther);
}

我尝试一次只更改一个参数、但没有看到尖峰有任何改善。

我按如下方式应用采样保持:

ADCSequenceStepConfigure(ADC0_BASE, 1, 0, ADC_CTL_CH13 | ADC_CTL_SHOLD_16);
并按如下方式调整硬件平均值:
ADCHardwareOversampleConfigure(ADC0_BASE, 32);
但是、0 和 64 的过采样会提供相同的噪声输出、采样保持 0 将提供与采样保持 256 相同的输出。
即使较慢的采样时钟也会产生相同水平的尖峰。

硬件过采样 0...64 几乎没有区别

ADC_CTL_shold 2...256 没有什么区别。

从 1MHz 到 10MHz 的时钟速度几乎没有区别。

有趣的是、当我为时钟设置 15MHz 或更高频率时、电压输出从 910 下降到 524、这似乎表明采样保持时间不够长。

不过、电压在 4 个时钟的采样保持时间或 256 个时钟的采样保持时间内保持在这个半电平、无论我使用什么采样保持时间、电压都保持在半电平。

将时钟向下更改为 10MHz、即使采样保持时间为 4 个时钟、电压也是正确的。

看起来没有应用采样保持。

对于如何提高输出有何建议?

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

    您好、

     我想您未能指定要使用的样本序列发生器。 有四个样本序列发生器可供选择。 有关详细信息、请参阅数据表。  

    假设您要使用样本序列发生器 3 在 AIN0 上对模拟输入进行采样。 您可以 按如下所示调用 ADCSequenceStepConfigure。 请参阅 C:\ti\TivaWare_C_Series-2.2.0.295\examples\peripherals\adc\single_end.c 中的完整示例源代码

    ADCSequenceStepConfigure (ADC0_BASE、3、0、ADC_CTL_CH0 | ADC_CTL_IE |
    ADC_CTL_END);

    有关详细信息、请参阅外设驱动程序用户指南。  

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

    我错过了执行此操作的代码行。 我使用序列发生器 1 读取模拟信道 13。

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

    您好、

     您是否添加了对  ADCSequenceStepConfigure() 的调用、结果是什么? 我不清楚你为什么拒绝我的回答。  

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

    您好 Charles

    很抱歉混淆。 我不小心在原始代码中留下了一行。

    我已经在原来的问题中添加了这一点,感谢让我知道我错过了它。

    我拒绝回答的原因是、如果没有这条线路、ADC 根本就不会进行采样。  这是一个剪切和粘贴问题代表我,它不是在问题. 我试图理解为什么输出如此嘈杂、即使我添加了硬件均值计算功能或增加采样保持周期、捕获的波形看起来有噪声、但使用相同的输入电路从 Arduino 测得的相同电压抖动要小得多。

    我希望 100%确定我正确地应用了滤波器。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我拒绝回答的原因是没有这一行 ADC 根本不会采样。

    正确。 如果没有调用  ADCSequenceStepConfigure、您还没有完全配置 ADC。  

    我试图理解为什么输出如此嘈杂、即使我添加了硬件均值计算或增加了采样保持周期、捕获的波形看起来很嘈杂、

    您是否说在调用  ADCSequenceStepConfigure 后仍然收到嘈杂的数据? 我仍然不清楚你在这里的发言。 如果您尚未调用 ADCSequenceStepConfigure、则无需研究 ADC 捕获不正确数据的原因。 ADC 甚至不知道要使用哪个采样序列发生器以及要对数据进行采样的 ADC 通道。 如果您已调用 ADCSequenceStepConfigure、但仍然收到嘈杂/不正确的数据、我们可以进行调查。

    我会建议您:

     - 尝试示例代码并确认您是否可以获得正确的数据。 这将验证软件。

     -在 Launchpad 上运行您自己的代码。 这将验证硬件。

     

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

    在默认示例设置下获取 atod 值时没有问题。  正是像采样保持这样的东西似乎不起作用。 例如、默认使用 piosc、它是 16MHz 并提供合理的值、但如果我使用分频器值将 PLL 缩放至 16M、则模拟样本从 904 下降到 540、并且更改采样保持周期不起作用。 我希望有人在这些事情上有更多的经验可以告诉我为什么会这样。

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

    您好、

     我在这里提出了一些意见和问题。

     1.首先、当您将 PLL 指定为 ADC 的时钟源时、 ui32SysClock 不会馈送到 ADC 以在分频器之后生成 ADDCLK。 而是馈送到 ADC 的 PLL VCO、在分频器后产生 ADCCLK。 PLL VCO 输出取决于您如何配置系统时钟。  如果您使用 TivaWare 配置 120MHz 的系统时钟、则 PLL VCO 将为 240MHz。 换句话说、无论系统时钟是什么、它都是馈送到 ADC 的固定 240Mhz。 即使您使系统时钟等于 16MHz、也会将用于 ADC 的 VCO 输出仍为 240MHz。 请参阅数据表和时钟树图。

    ■μ s 分频 PLL VCO 。 PLL VCO 频率可配置为生成高达 32MHz 的时钟
    转换率为 2Msps 时。 ADCCC 寄存器中的 CS 字段必须编程为
    0x0 用于选择 PLL VCO、CLKDIV 字段用于为设置合适的时钟分频器
    所需的频率。

    ■16MHz PIOSC. 使用 PIOSC 可提供接近 1MSPS 的转换率。 使用 PIOSC
    要为 ADC 计时、请首先为 PLL 加电、然后在的 CS 位字段中启用 PIOSC
    ADCCC 寄存器、然后禁用 PLL。
    ■MOSC。 MOSC 时钟源必须为 16MHz 以实现 1MSPS 的转换速率、为 32MHz
    2Msps 转换速率。

     2. 如果您使用最新的 TivaWare SDK、任何示例都将调用以下 API 来配置系统时钟。 您可以看到 VCO 是 240MHz。  

    ui32SysClock = SysCtlClockFreqSet (SysCtl_XTAL_25MHz |
    SYSCTL_OSC_MAIN |
    SysCtl_USE_PLL |
    SYSCTL_ CFG_VCO_240 )、120000000);

     3、 ADCClockConfigSet  API 不会改变采样保持时间。 您的语句 ADCClockConfigSet (ADC0_BASE、ADC_CLOCK_SRC_PLL | ADCrate、ADCdivisor ) 用于配置 ADC 源时钟。 正如我提到的、无论  ui32SysClock 与什么一起返回、ADC_CLOCK_SRC_PLL 都等于 240MHz。 ADCrate 用于控制向应用程序提供样本的频率。 ADCdivisor 将 PLL VCO 分频以定义 ADCCLK 频率、这两个频率与采样保持时间无关。  

     4、当 调用 ADCSequenceStepConfigure 时,采样保持时间会自动编程。 您可以查看 ADCSequenceStepConfigure API 的源代码。   用户实际上并不需要手动更改采样/保持。

     5、 我认为您的问题与对 PLL VCO (240MHz) 的误解比采样保持更多。 从下表中可以看到、要实现 1Msps、您需要 4 个 以 16MHz 运行的 ADCCLK 周期来进行采样/保持。  如果您要调用 ADCClockConfigSet (ADC0_BASE、ADC_CLOCK_SRC_PLL | ADCrate、1) 等器件、则实际上是将 ADCCLK 编程为 240Mhz、如 240 除以 1。 这当然是不正确的。  ADC 无法以 240Mhz 时钟运行。 要使用 PLL VCO 实现 16MHz 的 ADCCLK、您需要调用 ADCClockConfigSet (ADC0_BASE、ADC_CLOCK_SRC_PLL | ADCrate、15) 等 API。

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

    感谢您的回答。 这使我得到了正确的答案。  我按照您的建议进一步研究了 PLL VCO、并找到了 TM4C129  

    传递 SysCtlClockFreqSet 函数一个参数以设置 PLL VCO 频率。  这提供了以下选项  
    SYSCTL_CFG_VCO_320 或  SYSCTL_CFG_VCO_480、可设置 320MHz 或 480MHz 的频率。
    我在各个采样阶跃中设置的采样保持周期没有影响、因为 4 个时钟就足够了、因此测量的电压没有改善。