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.

[参考译文] TM4C1290NCPDT:ADC 代码

Guru**** 2455360 points


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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/636676/tm4c1290ncpdt-adc-code

器件型号:TM4C1290NCPDT

您好!

 我想在一秒(1ksps)内从 ADC 通道读取1024个样本、我正在使用 tm4c129电路板、我已经完成了以下代码、但我在一秒内只获得75个样本、因此有人可以帮助我获得该输出、 我最近开始使用这个板,我在这里附上了代码。

#include
#include
#include
#include "inc/hw_memmap.h"
#include "driverlib/adc.h"
#include "driverlib/adc.c"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
#include "driverlib/interrupt.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "driverlib/uart.c"
#include "utils/uartstdio.h"
#include "driverlib/hibernate.h"


uint32_t g_ui32SysClock;
//
//
//! 添加到组 ADC_Examples_list
//!

单端 ADC (single_ended)


//!
//! 此示例展示了如何将 ADC0设置为单端输入并采用
//! AIN0/PE7上的单个采样。
//!
//! 此示例使用以下外设和 I/O 信号。 您必须执行的操作
//! 查看这些内容并根据您自己的董事会的需要进行更改:
//! - ADC0外设
//! - GPIO 端口 E 外设(用于 AIN0引脚)
//! AIN0 - PE7
//!
//! 以下 UART 信号仅配置为显示控制台
//! 消息。 操作时不需要这些
//! ADC。
//! UART0外设
//! - GPIO 端口 A 外设(用于 UART0引脚)
//! - UART0RX - PA0
//! - UART0TX - PA1
//!
//! 此示例使用以下中断处理程序。 来使用该示例
//! 在您自己的应用程序中、您必须将这些中断处理程序添加到
//! 矢量表。
//! -无。
//
//

//
//
//此函数将 UART0设置为用于控制台显示信息
//因为示例正在运行。
//
//
无效
配置 UART0 (空)

//
//启用 UART 使用的 GPIO 外设。
//
SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA);

//
//启用 UART0
//
SysCtlPeripheralEnable (SYSCTL_Periph_UART0);

//
//为 UART 模式配置 GPIO 引脚。
//
GPIOPinConfigure (GPIO_PA0_U0RX);
GPIOPinConfigure (GPIO_PA1_U0TX);
GPIOPinTypeUART (GPIO_Porta_base、GPIO_PIN_0 | GPIO_PIN_1);

//
//初始化控制台 I/O 的 UART
//
UARTStdioConfig (0、9600、g_ui32SysClock);


//
//
//为单端输入和单个采样配置 ADC0。 一次
//样本就绪,将设置中断标志。 使用轮询方法、
//数据将被读取,然后通过 UART0显示在控制台上。
//
//
内部
main (空)

//0
//该数组用于存储从 ADC FIFO 读取的数据。 它
//必须与正在使用的序列发生器的 FIFO 一样大。 此示例
//使用 FIFO 深度为1的序列3。 如果是另一个序列
//与更深的 FIFO 一起使用,则必须更改数组大小。
//
uint32_t pui32ADC0Value[1];


//
//使用 PLL 将时钟设置为以20MHz (200MHz/10)运行。 时间
//使用 ADC,您必须使用 PLL 或提供16 MHz 时钟
//源。
// TODO:必须更改 SYSCTL_XTAL_VALUE 以匹配的值
板上的//晶体。
//
G_ui32SysClock = SysCtlClockFreqSet ((SYSCTL_XTAL_25MHz |
SYSCTL_OSC_MAIN | SYSCTL_USE_PLL |
SYSCTL_CFG_VCO_480)、120000000);
//
//设置用于显示消息的串行控制台。 这是
//仅用于此示例程序,ADC 操作不需要。
//
配置 UART0();

//
//在控制台上显示设置。
//

//
//必须启用 ADC0外设才能使用。
//
SysCtlPeripheralEnable (SYSCTL_Periph_ADC0);


SysCtlPeripheralEnable (SYSCTL_Periph_GPIOE);


GPIOPinTypeADC (GPIO_Porte _BASE、GPIO_PIN_3);


ADCSequenceConfigure (ADC0_BASE、0、ADC_TRIGGER_PROCESSOR、0);


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

ADCSequenceEnable (ADC0_BASE、0);


ADCIntClear (ADC0_BASE、0);

SysCtlPeripheralEnable (SYSCTL_Periph_HIBERNATE);
HibernateEnableExpClk (SYSCTL_OSC_EXT32);
HibernateClockConfig (HIBERNATE_OSC_HIGRHIVE);
HibernateRTCDisable();

HibernateRTCSet (0);//此代码用于时间戳
HibernateRTCEnable();

unsigned long long sec = HibernateRTCGet ();
unsigned int subsec = HibernateRTCSSGet ();

while (sec<1)//我想将样本采集到最长1秒的时间


ADCProcessorTrigger (ADC0_BASE、0);


while (!ADCIntStatus (ADC0_BASE、0、false))


ADCIntClear (ADC0_BASE、0);

ADCSequenceDataGet (ADC0_BASE、0、pui32ADC0Value);

SEC = HibernateRTCGet ();
subsec = HibernateRTCSSGet ();

UARTprintf ("AIN0 =%4D\n"、pui32ADC0Value[0]);

while (1);

提前感谢。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!
    我认为它可能与 UARTprintf 语句有关、因为从 UART 发送数据需要一些时间。 我认为您配置的波特率越慢(代码中为9600)、完成 UARTprintf API 所需的时间就越慢。 尝试注释掉 UARTprintf、看看它是否会产生一些影响。 您可以尝试递增软件计数器、而不是 UARTprintf、并查看一秒钟内得到的计数。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    大家好,感谢您的回复,我按照您的要求更改了代码,我添加了一些其他行,将数据保存在数组中,如下面的代码所示,当我将200放入数组大小时,它工作正常, 但是、如果我更改为超过300、则会出现无限循环(faultIsr 函数)、我就不知道它与存储器大小有关的原因了?、请帮助我在几秒钟内获得1024个样本。

    #include
    #include
    #include
    #include "inc/hw_memmap.h"
    #include "driverlib/adc.h"
    #include "driverlib/adc.c"
    #include "driverlib/gpio.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/uart.h"
    #include "driverlib/uart.c"
    #include "utils/uartstdio.h"
    #include "driverlib/hibernate.h"


    uint32_t g_ui32SysClock;
    //
    //
    //! 添加到组 ADC_Examples_list
    //!

    单端 ADC (single_ended)


    //!
    //! 此示例展示了如何将 ADC0设置为单端输入并采用
    //! AIN0/PE7上的单个采样。
    //!
    //! 此示例使用以下外设和 I/O 信号。 您必须执行的操作
    //! 查看这些内容并根据您自己的董事会的需要进行更改:
    //! - ADC0外设
    //! - GPIO 端口 E 外设(用于 AIN0引脚)
    //! AIN0 - PE7
    //!
    //! 以下 UART 信号仅配置为显示控制台
    //! 消息。 操作时不需要这些
    //! ADC。
    //! UART0外设
    //! - GPIO 端口 A 外设(用于 UART0引脚)
    //! - UART0RX - PA0
    //! - UART0TX - PA1
    //!
    //! 此示例使用以下中断处理程序。 来使用该示例
    //! 在您自己的应用程序中、您必须将这些中断处理程序添加到
    //! 矢量表。
    //! -无。
    //
    //

    //
    //
    //此函数将 UART0设置为用于控制台显示信息
    //因为示例正在运行。
    //
    //
    无效
    配置 UART0 (空)

    //
    //启用 UART 使用的 GPIO 外设。
    //
    SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA);

    //
    //启用 UART0
    //
    SysCtlPeripheralEnable (SYSCTL_Periph_UART0);

    //
    //为 UART 模式配置 GPIO 引脚。
    //
    GPIOPinConfigure (GPIO_PA0_U0RX);
    GPIOPinConfigure (GPIO_PA1_U0TX);
    GPIOPinTypeUART (GPIO_Porta_base、GPIO_PIN_0 | GPIO_PIN_1);

    //
    //初始化控制台 I/O 的 UART
    //
    UARTStdioConfig (0、9600、g_ui32SysClock);



    //
    //
    //为单端输入和单个采样配置 ADC0。 一次
    //样本就绪,将设置中断标志。 使用轮询方法、
    //数据将被读取,然后通过 UART0显示在控制台上。
    //
    //
    内部
    main (空)

    //0
    //该数组用于存储从 ADC FIFO 读取的数据。 它
    //必须与正在使用的序列发生器的 FIFO 一样大。 此示例
    //使用 FIFO 深度为1的序列3。 如果是另一个序列
    //与更深的 FIFO 一起使用,则必须更改数组大小。
    //
    uint32_t pui32ADC0Value[1];
    uint32_t data[200]; //存储 ADC 结果
    int cnt=0 //对未获取的样本进行计数


    //
    //使用 PLL 将时钟设置为以20MHz (200MHz/10)运行。 时间
    //使用 ADC,您必须使用 PLL 或提供16 MHz 时钟
    //源。
    // TODO:必须更改 SYSCTL_XTAL_VALUE 以匹配的值
    板上的//晶体。
    //
    G_ui32SysClock = SysCtlClockFreqSet ((SYSCTL_XTAL_25MHz |
    SYSCTL_OSC_MAIN | SYSCTL_USE_PLL |
    SYSCTL_CFG_VCO_480)、120000000);
    //
    //设置用于显示消息的串行控制台。 这是
    //仅用于此示例程序,ADC 操作不需要。
    //
    配置 UART0();

    //
    //在控制台上显示设置。
    //


    //
    //必须启用 ADC0外设才能使用。
    //
    SysCtlPeripheralEnable (SYSCTL_Periph_ADC0);


    SysCtlPeripheralEnable (SYSCTL_Periph_GPIOE);


    GPIOPinTypeADC (GPIO_Porte _BASE、GPIO_PIN_3);


    ADCSequenceConfigure (ADC0_BASE、3、ADC_TRIGGER_PROCESSOR、0);


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

    ADCSequenceEnable (ADC0_BASE、3);


    ADCIntClear (ADC0_BASE、3);

    SysCtlPeripheralEnable (SYSCTL_Periph_HIBERNATE);
    HibernateEnableExpClk (SYSCTL_OSC_EXT32);
    HibernateClockConfig (HIBERNATE_OSC_HIGRHIVE);
    HibernateRTCDisable();

    HibernateRTCSet (0); //此代码用于时间戳
    HibernateRTCEnable();

    unsigned long long sec = HibernateRTCGet ();
    unsigned int subsec = HibernateRTCSSGet ();



    while (sec<1) //我想将样本采集到最长1秒的时间


    ADCProcessorTrigger (ADC0_BASE、3);


    while (!ADCIntStatus (ADC0_BASE、3、false))




    ADCIntClear (ADC0_BASE、3);

    ADCSequenceDataGet (ADC0_BASE、3、pui32ADC0Value);

    data[cnt]=pui32ADC0Value[0];

    SEC = HibernateRTCGet ();
    subsec = HibernateRTCSSGet ();

    CNT++;




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

    如果您的目标是查看一秒内可以采集多少个样本、那么您只需注释掉 DATA[cnt]=pui32ADC0Value[0]、然后找出 cnt 的值。 我想您遇到的是堆栈溢出。 在实际应用中、您会在采样数据传入时对其进行处理。 您不会仅存储所有 ADC 采样数据(即1000个数据)而不对其进行处理。 为了避免硬件故障、您可以增大堆栈大小、也可以将 cnt 设置为全局变量。 但最后、片上 SRAM 是受限的、如果不断增大阵列的大小、您最终会再次溢出堆栈或 SRAM。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    谢谢您的回答,我尝试使用计数器,它显示了我得到的204796个样本,但正如您所说,我需要处理 ADC 样本数据以存储在数组中,所以请告诉我如何操作。 我需要将每个 ADC 样本和时间戳存储在数组中、您能给我提供帮助吗
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我不明白您的应用为什么需要存储每个 ADC 样本及其时间戳。 您不能仅仅存储无限个样本。 您需要释放存储器、以便它可以存储新数据。 为什么不像蝴蝶或乒乓方式那样以两个缓冲器(两个数组)存储? 假设一个缓冲器是100个样本。 在处理一个缓冲器时、ADC 可以采集样本并将结果存储在另一个缓冲器中。 您将在这两个数组之间来回切换。 您也可以考虑使用 DMA 来改善数据传输、但我将要求您首先使用 CPU 来实现它。 在您使一切正常工作后、您可以继续提高效率。 一天结束时、您只能存储所有 ADC 样本。 在某种程度上、您需要处理它们并忘记它们、以便新数据可以进入缓冲区。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Charles、

    第一、"高:(潮汐和(后)棒球季的成就)"给我们在休斯顿/周边地区的朋友。

    海报宣布"1K 模拟读数/秒"-但从未描述过要测量的信号-这可能(完全)否定该测量速率下的任何测量精度的机会。   还必须考虑"模拟前端"的质量-它也保持沉默。

    我们没有被告知此1K/秒要求的持续时间-它是"仅一次"还是周期性(未指定)、也许是连续的?   难道并非所有这些事实都要求"将海报的雷达"--并通常"比现在快"而不是晚"提出?

    我们注意到、我们的海报选择了"休眠 RTC 时钟"来确定他的1ms 间隔。   如果需要精确的计时- MCU 的计时器远超您的要求-您是否同意?   从计时器生成 ADC 触发器可能会"完全消除"任何对"时间戳"的需求、因为每个 ADC 测量值都将以精确的1ms 间隔间隔间隔间隔间隔间隔进行间隔。   只要"第一个转换事件"链接到实时"、所有其他转换事件就会按照"锁步"的要求加快、简化并大大减少"对额外 SRAM 的需求"。

    虽然这个项目显然是"基于理论"的-"现实世界"方面应该得到(一些)考虑-您不同意吗?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好,感谢您回复我的查询,您能否使用计时器发送任何示例代码,我们如何每秒获得1024个样本, 正如 charales 回复中提到的、如何在 ADC 转换的同时处理 ADC 结果、请帮助我了解一些深入的概念、但我仍然想获得这个输出
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 CB1、
    感谢您推荐1ms 计时器来获取1000个样本。

    Rupendra、
    我们还没有现成的示例(使用计时器以乒乓缓冲方式触发 ADC)。 您必须投入一定的精力来实现这一点。 对于设置计时器、您可以参考中的计时器示例 /examples/peripherals/timers. 下面的 POST 是一个良好的起点、因为 POST 显示了一些使用计时器触发 ADC 的代码。 我建议您从计时器项目开始。 在将定时器代码与 ADC 代码集成之前、请尝试了解使用定时器的机制。

    e2e.ti.com/.../361896