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/TM4C1294NCPDT:ADC 定时器触发器配置

Guru**** 2482225 points


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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/718813/ccs-tm4c1294ncpdt-adc-timmer-trigger-configuration

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

工具/软件:Code Composer Studio

您好! 我很新使用这个平台、我在使用时间较长触发的 ADC 转换时遇到问题。 有人能帮我找出代码中的错误吗?

// Inclusão ó n de Arquivos/Bibliotecas
#include 
#include 
#include 
#include 
#include "inc/hw_types.h"
#include "inc/hw_memmap.h"
#include "inc/hw_ints.h"
#include "driverlib/adc.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.iptexample.h"


















;"driveriptex_intradt1 intrust_ipt1 (intrust_ipt1)#def_ipt1 (intrintrust_ipt1)#def_ipt1 (intrintrust_ipt1)#def_ipt1 (intrust_ipt1)#def_ipt1 (intrust_ipt1 intrust_ipt1 (intrust_ipt_ipt_ipt1)#include "intrintrust_ipt1 (intrust_ipt_ipt_ipt_ipt1)#def_ipt1 (intrust_ipt1 (intrintrintrust_ipt_ipt_ipt_ipt.ipt1);

UART_CLOCK_PIOSC);

GPIOPinTypeUART (GPIO_Porta_base、GPIO_PIN_0 | GPIO_PIN_1);

UARTStdioConfig (0、115200、 16000000);
}

void InitADC (void)
{
SysCtlPeripheralEnable (SYSCTL_Periph_ADC0);

SysCtlPeripheralEnable (SYSCTL_Periph_GPIOE);
while (!SysCtlPeripheralReady (SYSCTL_Periph_GPIOE))
;{

SysCtlPinTypeADC (SYSCTL_ADC_CL_CLUST_CLOCK_CLK)



;GP0_CL_CL_CLUS_ADCK_CL_CK_CL_CLOCK (SYSD_CL_CL_CL_CL_CL_CL_CL_CL_CL_CLUS_CLK); 5);
SysCtlDelay (10U);

IntDisable (INT_ADC0SS0);
ADCIntDisable (ADC0_BASE、3);
ADCSequenceDisable (ADC0_BASE、3);

ADCSequenceConfigure (ADC0_BASE、3、ADC_TRIGGER_TIMER、 0);

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

ADCIntClear (ADC0_BASE、3);
IntEnable (INT_ADC0SS3);
ADCIntEnable (ADC0_BASE、 3);
ADCSequenceEnable (ADC0_BASE、3);

}

void InitGPIO (void)
{
SysCtlPeripheralEnable (SYSCTL_Periph_GPION);
while (!SysCtlPeripheralReady (SYSCTL_Periph_GPION))
}{


GPIOTypeGPIOOutput (GPIO_PORTn_BASE);0x03_GPIO_PIN_0
;GPIO_PIN_0;GPIO_PIN_0_PIN_1;GPIO_PIN_0



空 InitTimer0 (空)
{
SysCtlPeripheralEnable (SYSCTL_Periph_TIMER0);

TimerConfigure (TIMER0_BASE、TIMER_CFG_SPLIT_PAIR | TIMER_CFG_B_PERIODICRAY);

TimerLoadSet (TIMER0_BASE、TIMER_B、 SysCtlClockGet ()/ 1000);

TimerControlTrigger (TIMER0_BASE、TIMER_B、TRUE);

TimerIntEnable (TIMER0_BASE、 Timer_TIMB_TIMEOUT);

IntMasterEnable ();

TimerEnable (TIMER0_BASE、TIMER_B);
}

void ADC0SS3IntHandler (void)
{

CONT+2;
ADCIntClear (ADC0_BASE、3);

ADCSequenceDataGet (ADC0_BASE、3、 ADC0Value);
}


int main (void)
{

SysCtlClockFreqSet (SYSCTL_XTAL_25MHz | SYSCTL_OSC_main | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480、120000000);


InitGPIO ();
InitConsole ();
InitADC ();
InitTimer0 ();

while (1)

{

UARTprintf ("AIN0 =%d\t"、ADC0Value[0]);
GPIOPinWrite (GPIO_PORTN_BASE、GPIO_PIN_0 | GPIO_PIN_1、var);

UARTprintf ("var =%d\n"var);

SysCtlDelay (10000000);

if (var = 4)
var = 1;
否则
var*=2;
}


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

    您的 ADC 时钟配置看起来处于关闭状态。 对于 TM4C129x 器件、分频后 ADC 的时钟频率必须介于16MHz 和32MHz 之间。 因此、如果您使用的是 API 指示的来自 PLL 的 VCO、则应使用15至30之间的器件值、以便在 VCO 以480MHz 运行时进入该范围。

    您可以在 DriverLib 用户指南中阅读有关如何使用 ADCClockConfigSet 的更多详细信息。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 Ralph、

    我按照您的建议进行了此更改、但我的 ADC 测量结果仍然错误。

    现在、我将使用此配置:

    //ADCClockConfigSet (ADC0_BASE、ADC_CClock_SRC_PIOSC | ADC_CClock_RATE_FULL、1);
    ADCClockConfigSet (ADC0_BASE、ADC_CLOCK_SRC_PLL | ADC_CLOCK_RATE_FULL、24);

    并且已经尝试过上面的那个。

    它似乎不稳定、即使存在固定输入、转换后的值也会发生很大变化。 您能帮我解决这个问题吗?

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

    啊、您现在会得到错误的测量结果吗? 我以为这不是工作时间。 这种情况与此相当不同。

    您能否解释一下您正在测量的内容以及会影响 ADC 引脚输入阻抗的任何阻抗源?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用用户="Tiago Texeira "]它(海报的 ADC 值)似乎不稳定,即使有固定的输入-转换后的值也有很大变化。

    什么是"批次?"   对于任何此类"复用信号器件"、3 lsb 可能会受到抖动的影响。   (您的描述必须准确。)

    到了夏天、我公司的实习生在"你的帮助"上遇到了一些问题。   他们发现

    • IntDisable (INT_ADC0SS0);  然后(稍后)执行以下操作:

    • IntEnable (INT_ADC0SS3);  (它们注意到(一些)一致性会很有用)

    • 您已经选择了 ADC 序列#3 -它只执行(仅)一次转换。   在这个早期阶段-它是否不会证明(更多)有用-对于您来说、您可以选择序列#0 -这将启用"8 "背靠背"转换?   事实证明、这些(附加) 7个转换结果(全部在同一个通道上)肯定会提供进一步的见解、对于此类 ADC 故障排除非常有帮助。  (即"更多"数据-最常-比"更少"数据更重要!)
    • 和往常一样-正如供应商的 Ralph 所说-没有关于您的描述、"模拟输入信号"详细信息"就到了。   为了获得最佳性能-模拟信号的"输出特性"-必须与 MCU ADC 的"输入特性"匹配(尽可能接近)。   (MCU 手册中提供了此类详细信息- ADC 部分和后续部分-以及"电气规格"中提供的详细信息。)
    • 您已经选择了 ADC 以1毫秒(MS)间隔运行的计时器触发器。   然而、您已经使用 UART 来显示信号结果、并且(通常)" UART 数据速率的缓慢"将介入1ms、定时器触发间隔!   那么呢?   这是否会影响您的测量?   测试时-"kiss"指示您"数据速率"(以及 ADC 转换速率)、以便您"为器件提供最大的成功机会!"    建议您增加 ADC 转换之间的时间!  (但这又是另一个问题、(可能)一 个"疯狂"的小问题!)
    • 您已经选择了一个半定时器(16位)和一个120MHz 系统时钟-并且需要一个1ms (重复)定时器触发器。   然而、在120MHz 系统时钟和16个定时器位的条件下、您的定时器(最多)可以容纳~546µS μ s 以上的间隔时间(不大于 μ s)!    因此、计时器(可能)以不同的速率"触发"、这超出了您的预期!   (这证明了超大的定时器装载值"溢出"定时器的16位容量-产生65K 的"值减法"。    这似乎是您的"代码问题!"的"最严重"
    • 与"邀请计时器触发器的复杂情况-(旧待机) "ADC 处理器触发器"相比、调用 的频率可能要低得多(即更安全的速率-当与"移至序列0"耦合时 (实现8次转换-同一通道(背靠背等)) -这应该为您的 ADC 成功提供"最有可能"(并简化)的"途径!"   (礼貌-一如既往、"亲吻!")

    为了"最佳匹配"您的信号-符合 ADC 的要求-一般而言:

    • 尽量缩短"引线"的长度(如果采用这些引线)以提供模拟信号。   (如果需要分离-考虑使用屏蔽电缆-电缆屏蔽层的一侧接地)
    • 确保'GND'为公共(即 MCU GND 和模拟信号的 GND 均已牢固连接!)   (经常会错过!)
    • 向 ADC 引入最稳定和最纯净的直流电平。   (不太可能因"敲击" MCU 的 VDD 而导致!)
    • 如果您的 MCU 提供"模拟 VDD 和模拟 GND"-正确利用这些(信号稳定)电源输入。   向模拟 VDD 施加最高质量的基准电压!
    • 最常-阻抗匹配通过配置为"电压跟随器"的运算放大器来缓冲您的模拟信号、从而获得"辅助"。
    • 0.01µF 在尽可能靠近 MCU 的 ADC 引脚的位置安装一个低值陶瓷电容器(μ F)、通常也会改善结果
    • 尽可能使模拟信号远离明显的"噪声源、高电流和快速开关信号"-每种信号都可能会增加(不需要)抖动 (再次-"短"屏蔽电缆辅助)
    • 当然-确保您的模拟信号始终保持在 ADC 的输入信号规格中。

    [编辑/更新] 信贷供应商的 Charles、因为他的敏锐观察:  

    海报使用这个函数'TimerLoadSet (TIMER0_BASE、TIMER_B、SysCtlClockGet ()/ 1000);' 、其中包含一个参数(我的员工认为这个参数太大-不能容纳在16位寄存器中-还会受到(另一个)和(可能)更明显的弱点!   尽管许多代码示例显示了'SysCtlClockGET()(或 SET)'-它的使用仅保留给 TM4C123器件!   这是一个"不幸的现实"- TM4C129系列的到来带来了这个事实!   当部署"129时、必须使用完全不同的函数-以及那些过去的标签(已放弃)!

    年轻的员工——如此周到和细致——会这么多…… 喜欢看到他们的"贡献喜欢"、出于(原因不明)原因、这种情况被拒绝了...   (太棒了,“激活杀戮”…… 太美了!)

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

    感谢您提到 SysCtlClockGet ()、我也错过了它。 另一位同事也告诉我。

    Tiago、请移除 SysCtlClockGet ()调用并根据 SysCtlClockFreqSet 的输出输入时钟频率(许多用户将其存储为一个变量以方便参考)。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Ralph、

    谢谢-应该(再次)注意海报的"初步"选择"1ms"- ADC 的"已确定的转换调用"速率证明:

    • 当由一个120MHz 源计时时、不可能在分离定时器的16位寄存器容量内实现
    • 对于海报的初始"测试/验证"、所有概率都是"太快"。   "kiss"指示最慢、可轻松实现的速率-这"大大增加了海报成功的可能性!"
    • 使用计时器作为 ADC 触发器会增加(另一个)风险元素、因此违反了"kiss"。   相反-应该采用旧的待机模式、'ADC processor trigger'- 至少在 ADC 成功结果之前。

    即将离职(实习生)的员工(下周开始上学)为技术项目提供了"丰富的指南"、值得海报上的时间和考虑。   (即使是(其他人)来到这里-也应受益于这一专门小组的关注和努力...)

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

    您好! 非常感谢大家花时间和精力帮助我!

    这一切都是关于时钟配置的,为了正确设置它,我做了一些修改,包括删除 SysCtlClockGet()。

    以下是修改后的代码:


    Inclusão ó n de Arquivos/ Bibliotecas
    #include
    #include
    #include
    #include
    #include "inc/hw_types.h"
    #include "inc/hw_memmap.h"
    #include "inc/hw_ints.h"
    #include "driverlib/adc.h"
    #include "driverlib/gpio.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/uart.h"
    #include "utils/uartstdio.h"
    #include "driverlib/timer.h"

    // Definição de variáveis
    #define NUMBER_ON_INTS 32000


    int cont=0;
    int i = 0;
    int ADC_FREQKHZ = 30;
    uint32_t SysClock = 0;
    uint32_t ADC0Value[2];
    uint32_t DATA_ADC0[number_for_ints];
    uint32_t DATA_ADC1[number_for_ints];

    空 InitConsole (空)

    SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA);  

    GPIOPinConfigure (GPIO_PA0_U0RX);  
    GPIOPinConfigure (GPIO_PA1_U0TX);  

    SysCtlPeripheralEnable (SYSCTL_Periph_UART0);  

    UARTClockSourceSet (UART0_BASE、UART_CLOCK_PIOSC);  

    GPIOPinTypeUART (GPIO_Porta_base、GPIO_PIN_0 | GPIO_PIN_1);

    UARTStdioConfig (0、115200、16000000);  

    空 InitADC (空)

    SysCtlPeripheralEnable (SYSCTL_Periph_ADC0);//Habilita o cCanal ADC0

    SysCtlPeripheralEnable (SYSCTL_Periph_GPIOE);//Habilit性 A 端口 E

    GPIOPinTypeADC (GPIO_Porte _BASE、GPIO_PIN_3 | GPIO_PIN_2);  
    //GPIOPinTypeADC (GPIO_Porte _BASE、GPIO_PIN_3);
    SysCtlDelay (80u);


    //ADCClockConfigSet (ADC0_BASE、ADC_CLOCK SRC_PLL | ADC_CLOCK RATE_FULL、10);
    //ADCClockConfigSet (ADC0_BASE、ADC_CClock_SRC_PIOSC | ADC_CClock_RATE_FULL、1);
    ADCClockConfigSet (ADC0_BASE、ADC_CLOCK_SRC_PLL | ADC_CLOCK_RATE_FULL、24);
    SysCtlDelay (10U);

    IntDisable (INT_ADC0SS0);
    ADCIntDisable (ADC0_BASE、0);
    ADCSequenceDisable (ADC0_BASE、0);

    ADCSequenceConfigure (ADC0_BASE、0、ADC_TRIGGER_TIMER、0);  

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

    ADCHardwareOversampleConfigure (ADC0_BASE、8);

    ADCIntClear (ADC0_BASE、0);//将标志参数定义为 conversões
    IntEnable (INT_ADC0SS0);
    ADCIntEnable (ADC0_BASE、0);
    ADCSequenceEnable (ADC0_BASE、0);//Habilitico cCanal 0

    空 InitGPIO (空)

    SysCtlPeripheralEnable (SYSCTL_Periph_GPION);//Habitit性 o GPION
    GPIOPinTypeGPIOOutput (GPIO_PORTN_BASE、GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2);  
    GPIOPinWrite (GPIO_PORTN_BASE、GPIO_PIN_0 | GPIO_PIN_1、0x02);  


    空 InitTimer0 (空)

    SysCtlPeripheralEnable (SYSCTL_Periph_TIMER0);

    TimerConfigure (TIMER0_BASE、TIMER_CFG_SPLIT_PAIR | TIMER_CFG_B_PERIODICASE);

    TimerLoadSet (TIMER0_BASE、TIMER_B、SysClock/(1000*ADC_FREQKHZ));

    TimerControlTrigger (TIMER0_BASE、TIMER_B、TRUE);

    TimerIntEnable (TIMER0_BASE、TIMER_TIMB_TIMEOUT);

    IntMasterEnable();

    TimerEnable (TIMER0_BASE、TIMER_B);

    空 ADC0SS0IntHandler (空)

    CONT+=1;
    ADCIntClear (ADC0_BASE、0);
    ADCSequenceDataGet (ADC0_BASE、0、ADC0Value);
    //UARTprintf ("AIN0 =%d\n"、ADC0Value[0]);
    DATA_ADC0[CONT]= ADC0Value[0];//PE3
    DATA_ADC1[CONT]= ADC0Value[1];//PE2

    if (续>= number_for_ints)

    IntDisable (INT_ADC0SS0);
    ADCIntDisable (ADC0_BASE、0);
    ADCSequenceDisable (ADC0_BASE、0);
    ADCIntClear (ADC0_BASE、0);


    int main (空)

    SysClock = SysCtlClockFreqSet (SYSCTL_XTAL_25MHz | SYSCTL_OSC_main | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480、40000000);  
    InitGPIO();

    InitConsole();
    InitADC();
    InitTimer0();


    CONT = 0;

    while (1)

    if (续>= number_for_ints)

    CONT = 0;
    for (i=0;i<=number_of_ints;i++)

    UARTprintf ("示例%d:%d\t%d\n"、i、DATA_ADC0[i]、DATA_ADC1[i]);
    SysCtlDelay (10000);




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

    感谢您-我的团队(当然也是这个供应商)很高兴您坚持下去-并且成功了!

    然而、我们是否可以询问-"预期 定时器触发、ADC 速率"是通过以下方式实现的:

    "TimerLoadSet (TIMER0_BASE、TIMER_B、SysClock/(1000*ADC_FREQKHZ));"

    您可能已经注意到、当  由120MHz 时钟源驱动时、员工(之前)将"~564µS "标识为最大值-与定时器的16位寄存器中的值不可控制!    您是否确定您的"新实施"确实适合于这16个定时器位?

    我们刚刚注意到-远远低于您的代码列表-您(似乎)将系统时钟降低至40MHz。   这应将您的16位计时器寄存器扩展到1.5mS (最大值)容量。   (假设"所有其他内容"-保持恒定。)   但事实并非如此!  (我们稍后才发现!)

    相反-您将'ADC_FREQKHZ'定义为30'-因此我们相信您在 TimerLoadSet()中的最终(第三个)参数(现在) 30、000。   (哪个 btw -与65K 定时器寄存器中的哪个 btw 完美匹配-这个(30k)是正确的?)

    和-请描述 ADC 测量的差异-在向 ADC 馈送"固定输入信号电平"时。   (两个通道(现在)正在转换...)   预计 ADC 转换值的3lsb 将揭示"抖动"-(任何) MCU 的 ADC...的特征

    最后-您尚未采纳员工(之前的帖子)的建议采用"ADC Sequence 0!"中的"全部八个步骤"    不会有8个(背靠背) ADC 测量(同一 ADC 通道)-证明(甚至)更大的值?    (此类"快速转换"中的变化可能(可能)表明您的模拟信号输出与 ADC 输入之间存在"不正确匹配"。   这证明了其价值... 不是吗?