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/TM4C123GH6PM:无法以所需的速率触发 ADC

Guru**** 2454880 points


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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/631388/ccs-tm4c123gh6pm-unable-to-trigger-the-adc-at-desired-rate

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

工具/软件:Code Composer Studio

大家好、

我正在尝试使用 CPU 计时器控制 ADC 触发。

我的时钟设置为80MHz

"SysCtlClockSet (SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHz | SYSCTL_OSC_MAIN);"

我尝试以1MHz 的频率触发计时器 int

"TimerLoadSet (TIMER0_BASE、TIMER_A、SysCtlClockGet ()/80);"

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


//初始化 ADC
SysCtlPeripheralEnable (SYSCTL_Periph_GPIOE);// ADC 输入引脚
SysCtlPeripheralEnable (SYSCTL_Periph_ADC0);//ADC 外设
SysCtlPeripheralEnable (SYSCTL_Periph_TIMER0);

用于 ADC 通道的//引脚
GPIOPinTypeADC (GPIO_Porte _BASE、GPIO_PIN_3);//设置通道1的 GPIO_E3
ADCSequenceConfigure (ADC0_BASE、3、ADC_TRIGGER_TIMER、0);//序列发生器0
ADCSequenceStepConfigure (ADC0_BASE、3、0、ADC_CTL_CH0 | ADC_CTL_IE | ADC_CTL_END);

TimerConfigure (TIMER0_BASE、TIMER_CFG_PERIODICASE);
TimerLoadSet (TIMER0_BASE、TIMER_A、SysCtlClockGet ()/80);//1MHz
TimerEnable (TIMER0_BASE、TIMER_A);
TimerControlTrigger (TIMER0_BASE、TIMER_A、TRUE);

ADCSequenceEnable (ADC0_BASE、3);
ADCIntEnable (ADC0_BASE、3);

while (1)
{
TimerEnable (TIMER0_BASE、TIMER_A);
ADCIntClear (ADC0_BASE、3);
ADCIntEnable (ADC0_BASE、3);

//ADCIntClear (ADC0_BASE、3);
while (!ADCIntStatus (ADC0_BASE、3、0));

ADCSequenceDataGet (ADC0_BASE、3、&value);
ADCIntDisable (ADC0_BASE、3);

if (i<2048)
{
Data0[i++]=值;
}
} 


这是正确的方法吗?

如何检查计时器的触发频率?  

我尝试使用 ADC 输出填充2048尺寸的数组-我的 ADC 输入是由频率为100KHz 的函数发生器生成的正弦波

因此、理想情况下、每个正弦周期应具有10个样本。 因此、每个周期在数组中应占据10个位置。 整个2048个数组应包含204个"理想"正弦周期。 这不是发生的。

我很困惑我是否以1MHz 的频率触发 ADC?:(

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Rohan、
    由于您要使用 TIMER_A、因此应更改为 TimerConfigure (TIMER0_BASE、TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PERIODICASE)、然后重试。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Charles、

    我尝试更改为"TimerConfigure (TIMER0_BASE、TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PERIODICASE)" 、但仍然没有得到良好的结果。

    我正在尝试使用  板载 ADC (采样率1MSPS -"TimerLoadSet (TIMER0_BASE、TIMER_A、SysCtlClockGet ()/80)")采集100KHz 正弦波(目前)

    我要附上数据数组的图形屏幕截图、其中我要存储 ADC 输出。 数据数组为2048点。

    请提出可能出错的问题?

    添加以下源代码

    #include 
    #include 
    #include "inc/hw_ints.h"
    #include "inc/hw_memmap.h"
    //#include "inc/hw_types.h"
    #include "driverlib/debug.h"
    #include "driverlib/adc.h"
    //#include "driverlib/fpu.h"
    
    #include "driverlib/trabs.t#driver32.t/intru.ide";"driver32.t_intu.ide"#include "driverlib_untrab.ide";#t/trab.idt/u.idt/u.idt.idt.idr32_inth
    
    
    #include "nat_u.ide"/u.idr.idr.ide"#t.idr.idr.idr./u.idr.idr.idr.idr.idr.idr.idr.idr./u.idr.idr.idr.idr.idr.idr.idr.idr.idr.idr.idr.idr.idr.idr.idr.idr.
    
    
    
    
    
    
    
    
    
    
    
    uint32_t phase = 0;
    float x=1000;
    
    extern int QuadratureTable[360];
    extern float B[257];
    
    void Timer0IntHandler (void)
    {
    //i++;
    TimerIntClear (TIMER0_BASE、TIMER_TINA_TIMEOUT);
    }
    
    void RequireON (void)
    {
    uint32_t 值;
    
    TimerEnable (TIMER0_BASE、TIMER_A);
    ADCIntClear (ADC0_BASE、3);
    ADCIntEnable (ADC0_BASE、3);
    
    //ADCIntClear (ADC0_BASE、3);
    while (!ADCIntStatus (ADC0_BASE、3、0));
    
    ADCSequenceDataGet (ADC0_BASE、3、&value);
    ADCIntDisable (ADC0_BASE、3);
    
    if (i<2048)
    {
    Data0[i++]=值;
    
    }
    
    //return (value);
    }
    
    void main(){
    
    SysCtlClockSet (SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHz | SYSCTL_OSC_MAIN);//时钟设置为80MHz
    //SysCtlClockSet (SYSCTL_OSC_MAIN);
    
    
    //初始化 ADC
    SysCtlPeripheralEnable (SYSCTL_Periph_GPIOE);// ADC 输入引脚
    SysCtlPeripheralEnable (SYSCTL_Periph_ADC0);//ADC 外设
    SysCtlPeripheralEnable (SYSCTL_Periph_TIMER0);
    
    用于 ADC 通道的//引脚
    GPIOPinTypeADC (GPIO_Porte _BASE、GPIO_PIN_3);//设置通道1的 GPIO_E3
    ADCSequenceConfigure (ADC0_BASE、3、ADC_TRIGGER_TIMER、0);//序列发生器0
    ADCSequenceStepConfigure (ADC0_BASE、3、0、ADC_CTL_CH0 | ADC_CTL_IE | ADC_CTL_END);
    
    //TimerConfigure (TIMER0_BASE、TIMER_CFG_PERIODICRACASE);
    
    TimerLoadSet (TIMER0_BASE、TIMER_A、SysCtlClockGet ()/80);//80MHz
    TimerConfigure (TIMER0_BASE、TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PERIODICASE);
    TimerEnable (TIMER0_BASE、TIMER_A);
    TimerControlTrigger (TIMER0_BASE、TIMER_A、TRUE);
    
    ADCSequenceEnable (ADC0_BASE、3);
    ADCIntEnable (ADC0_BASE、3);
    
    
    //启用 ADC
    
    //uint32_t ADCCurrentIndex;
    
    
    while (1)
    {
    
    如果(c==1)
    {
    aquireON();//填充2048个 aquire 数组{Data0[]}
    if (i>2047)
    {
    C=2;
    I=0;
    
    }
    
    }
    
    
    } 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我是否可以建议先将所有内容减慢10倍、然后将其加速到您的工作速度?

    在下一次触发之前、全速模式下您只有80个时钟用于转换、读取和处理数据。 这时间不长。

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

    同意-当然、这种缓慢和简化清楚地说明了(始终)宝贵的"亲吻"。

    复杂的情况----由这种"过于乐观的启动条件"引起----最总是拖延,沮丧----常常失败!

    循序渐进的方法是经过深思熟虑和管理(受监测)的方法、长期以来一直被证明是最有效的!   (是否注意到亲吻?)

    我还建议生成一个"线性斜坡"、而不是正弦波、这使每个读数"更具可预测性"。   (简化错误检测!)

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

    您好、Rohan、我从未使用过 TM4C123、但我已经用 TM4C129进行了一段时间的模拟采集、我认为这与之非常相似。

    对于我来说、使用 TM4C UCS 实现1 MSPS 速率或2 MSPS 的唯一方法是避免使用 CPU 或处理器转换、我建议您使用 DMA 并使用计时器控制采样率。 这里有一些链接、第一个链接是我的 e2e 帖子、我遇到了与您类似的问题、最后您将找到代码的.c 文件(注意启动文件)、 但请记住、这是使用 TM4C129、可能必须考虑 TM4C123的一些注意事项。 在第二个链接中、您将找到使用具有 DMA 但不具有计时器控制功能的 TM4C123的音频源定位方案、我希望这对您有所帮助。

     

    https://e2e.ti.com/support/microcontrollers/tiva_arm/f/908/t/550008

    e2e.ti.com/.../550008

    https://www.hackster.io/graham_chow/acoustic-localization-c7c8ab

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

    您好!

     - 感谢您提供的信息。 我已经减少了这个数字、以检查我可以达到的最大速率。

      -是的、我正在尝试实施"亲吻"策略。

     -第一个链接不起作用、很抱歉我不理解 UDMA 的概念(我将在将来探讨这个主题)、尽管我现在想坚持计时器触发。

    void Timer0IntHandler (void)
    {
    uint32_t 值;
    
    //i++;
    TimerEnable (TIMER0_BASE、TIMER_A);
    ADCIntClear (ADC0_BASE、3);
    ADCIntEnable (ADC0_BASE、3);
    
    //ADCIntClear (ADC0_BASE、3);
    while (!ADCIntStatus (ADC0_BASE、3、0));
    
    ADCSequenceDataGet (ADC0_BASE、3、&value);
    ADCIntDisable (ADC0_BASE、3);
    
    if (i<2048)
    {
    Data0[i++]=值;
    
    }
    TimerIntClear (TIMER0_BASE、TIMER_TINA_TIMEOUT);
    
    } 
    void main(){
    
    SysCtlClockSet (SYSCTL_SYSDIV_5 | SYSCTL_USE_PLL | SYSCTL_16MHz | SYSCTL_OSC_MAIN);//时钟设置为40MHz
    //SysCtlClockSet (SYSCTL_OSC_MAIN);
    
    
    //初始化 ADC
    SysCtlPeripheralEnable (SYSCTL_Periph_GPIOE);// ADC 输入引脚
    SysCtlPeripheralEnable (SYSCTL_Periph_ADC0);//ADC 外设
    SysCtlPeripheralEnable (SYSCTL_Periph_TIMER0);//Timer0外设
    
    //TimerConfigure (TIMER0_BASE、TIMER_CFG_PERIODICRACASE);
    
    TimerConfigure (TIMER0_BASE、TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PERIODICASE);
    TimerLoadSet (TIMER0_BASE、TIMER_A、100000);//100KHz
    TimerEnable (TIMER0_BASE、TIMER_A);
    TimerControlTrigger (TIMER0_BASE、TIMER_A、TRUE);
    
    用于 ADC 通道的//引脚
    GPIOPinTypeADC (GPIO_Porte _BASE、GPIO_PIN_3);//设置通道1的 GPIO_E3
    ADCSequenceConfigure (ADC0_BASE、3、ADC_TRIGGER_TIMER、0);//序列发生器0
    ADCSequenceStepConfigure (ADC0_BASE、3、0、ADC_CTL_CH0 | ADC_CTL_IE | ADC_CTL_END);
    ADCSequenceEnable (ADC0_BASE、3);
    
    
    ADCIntEnable (ADC0_BASE、3);
    
    for (;;);
    
    } 

    上面给出的函数是主函数和 Timer0 ISR。 但我无法使用它触发 ADC。

    据我所知、应该有一个 ISR、它会执行不必要的操作(将 ADC 值放入数组中)。 每次触发计时器中断时(Hence I 写入 Timer0ISRHandler)、该 ISR 都应运行。

    对于之前帖子中的代码片段、未实现此操作(因为例程是在 while (1)... 环路)、因此我怀疑这是一种错误的方法。

    我不确定在哪里定义 ISRoutine、因此当 Timer0中断无限空闲循环以获取 ADC 结果时、应执行此定义的 ISR 并返回空闲循环。

    请给出建议

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Rohan 链接已更新、对于您的计时器问题、您应该检查您的中断服务例程是否已在项目的 startup_ccs 文件上声明。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 USER="Rohan Chwhan">据我了解、应该有一个 ISR 来执行不必要的操作(将 ADC 值放入数组中)。 [/报价]

    是的

    [引用 USER="Rohan Chahwan"]每次触发计时器中断时,该 ISR 都应运行[/引用]

    不是真的。 当 A/D 中断被触发时、它应该运行。 这将是计时器中断后的一段时间。 实际上、您可能不需要计时器中断。

    Robert

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

    您好 、您能给我指链接还是推荐您的建议吗?
    [引述]
    实际上、您可能不需要计时器中断。

    [/报价]

    我会提供很多帮助:)

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

    同意-除了海报所要求的事实、"定时器触发 ADC 操作"。

    您认为(可能的)"周期定时器-减去其 ISR "足以证明"触发 ADC"处于"选择的海报、定期间隔"的状态吗?

    也许"问题"在于、" ADC 的定时器触发器?"    "定时器触发器"是否确实会产生"定时器中断"、如果是、是否必须将其清除?   (因此、"定时器触发器"会进一步发生...)

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

    [引用 USER="CB1_MOBILE]同意-除了海报所要求的"定时器触发的 ADC 操作"之外。

    您认为(可能的)"周期定时器-减去其 ISR "-足以证明"触发 ADC"在"选择海报、定期间隔"下是足够的吗?"[/quot]

    是的、定时器直接触发 A/D 转换。 我将以这种方式使用它。

    [引用 USER="CB1_MOBILE]也许"问题"在于、" ADC 的计时器触发?"    "定时器触发器"是否确实会产生"定时器中断"、如果是、是否必须将其清除? [/报价]

    我不知道它会触发中断。 它当然不需要清除。 如果将计时器设置为周期计时器、则只会在每个周期触发 A/D 序列。

    Robert

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

    [引用用户="Rohan Chahwan"] Hey 能否给我指链接或您建议的资源?

    仅提供处理器手册和 TIVAWare 用户指南。 可能有一个 TIVAWare 示例、但我不知道有。

    Robert

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    感谢 Robert -"海报的阅读和对这两个要点的考虑"可能会对这里的"两个"有所帮助...
    这种"细节级别"证明了采用不同供应商 ARM MCU 的人员的弱点、其中"外设差异"可能"让人厌恶"。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    大家好、

    对这种迟交的答复表示歉意。 由于个人原因、我不在身边。

    我非常高兴地告诉大家,现在在你的帮助下,问题得到解决。 我再次经历了整个问题、并发现 关于未 在 startup_ccs 文件中声明的 ISR 例程的帖子。

    事实上,"不是"。

    主代码大致相同。

    我删除了 Timer0中断处理程序以及"许多海报都建议"。


    我能够使用我可以达到最大~700KHz 的定时器频率触发 ADC (我使用 GPIO 引脚检查该频率->使其高低与 ADC ISR 的入口和出口相关)

    感谢大家的帮助。

    此致、

    罗汉

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

    [引用 user="Rohan Chahwan"]我要附上我存储 ADC 输出的数据数组图形的屏幕截图。

    虽然您的"ADC Trigger"演示非常有用-但它与您的"Graphic Screenshot"(图形屏幕截图) 2017年10月11日提供的(必需)详细信息完全不匹配。

    存在一些重要问题-单靠"ADC 触发器"不可能解决这些问题...    您今天的帖子是否"避开"任何"图形屏幕截图?"   (如过去提供的-"非常好"地说明了您问题的关键方面。)

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

    高 CB1_MOBILE (1830783)

    "我的错误"-我没有上传结果的屏幕截图

    下面是分别针对50kHz 和25KHz 正弦波的 ADC 输出、这些输出用于700KHz 采样频率

    此致、

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    谢谢你们(非常)做得很好-一定会受到很多人的赞赏!

    700KHz 是否是您可以(合理)实现的最快采样率? (结果与您之前的 CAP 相比有了显著改善!)

    我们可以询问您的"图形演示"来源吗? 是 CCS 的一部分还是"外部图形程序"(即 Excel)、如果是"外部"、您通过什么方式将捕获的 ADC 数据引入到图形程序中?

    再次-赞扬您的坚持-并且、"只是为您的改进结果而努力!" (非常满意...)
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢您的感谢 CB1_MOBILE (1830783)

    [引述]
    700KHz 是否是您可以(合理)实现的最快采样率? (结果与您之前的 CAP 相比有了很大改善!

    [/报价]

    是的、在今天的帖子中上传的图像(DSO 上显示的是方波)是我获得的最大采样率、这是通过以下代码段实现的。

    //配置 TIMER0
    TimerConfigure (TIMER0_BASE、TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PERIODICASE);
    TimerLoadSet (TIMER0_BASE、TIMER_A、0x1);//使用0x1计数器进行最快触发
    TimerControlTrigger (TIMER0_BASE、TIMER_A、TRUE); 

    我将输出保存在数组中、并使用 MATLAB 进行进一步改进、如整理或重叠。 (所有上传的图像都是如此、直至现在)

    我使用内部编译 CCS 一次性图形在运行时查看输出、但使用 MATLAB 进行演示。

    此致、

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    非常好——今天有“弃船”的“快船”——和这位记者——感谢你们的努力,感谢你们的努力。

    此外-您提供的计时器代码和 MATLAB & CCS 的"一次性图形"亮点很可能会鼓励(其他)重复您的应用-并且可能会(可能)产生"微调和/或改进"。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Rohan、大家好、我很高兴能够解决这个问题。现在、我建议您尝试 DMA、如果您要使用 UCS 处理器忙于其他工作、那么这将非常有用。

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

    [引用用户="Josue Pareja"]

    现在、我建议您尝试 DMA、如果您要使用 UCS 处理器忙于其他工作、您会发现它非常有用。

    [/报价]
    当然 ,在项目完成后,我一定会研究“所有不同的方式”以获得乐趣:)
    再次感谢您的努力。 谢谢