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.

[参考译文] TM4C1294NCPDT:输入边沿计时模式不能按预期工作

Guru**** 2394305 points
Other Parts Discussed in Thread: EV2500, EK-TM4C1294XL

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/978451/tm4c1294ncpdt-input-edge-time-mode-does-not-work-as-expected

器件型号:TM4C1294NCPDT
Thread 中讨论的其他器件:EK-TM4C1294XL

您好、专家先生

   我将通用定时器1配置为在输入边沿计时模式下工作、以捕获分配给引脚 PD2的 T1CPP0上的上升沿、但当低电平脉冲应用于 PD2引脚时、不会触发相关中断。

   下面是 Timer1初始化和 GPIO 引脚 PD2配置的代码。

   …
   #define AFSEL_T1CCP0   4.
   #define PMC2_T1CCP0    0x30
   #define DEN_T1CCP0     4.
   #define ODR_T1CCP0     4.

   …

  //初始化 Timer1_A 以输入边沿计时模式
   HWREG (GPIO_PORTD_BASE + GPIO_AFSEL)|= AFSEL_T1CCP0;
   HWREG (GPIO_PORTD_BASE + GPIO_O_PCTL)|= PMC2_T1CCP0;       //将 PD0设置为 T0CCP0功能,使用 PWM 功能作为 DQ 输出
   HWREG (GPIO_PORTD_BASE + GPIO_DEN)|= DEN_T1CCP0;

   HWREG (SYSCTL_RCGCTIMER)|= SYSCTL_RCGCTIME_R1;

   HWREG (Timer1_base + TIMER_O_CTL)&=~TIMER_CTL_TAEN;
   HWREG (Timer1_base + TIMER_O_CFG)= TIMER_CFG_16_BIT;
   HWREG (Timer1_base + TIMER_O_TAMR)= TIMER_TAMR_TACMR | TIMER_TAMR_TAMR_CAP | TIMER_TAMR_TACDIR;    //计时器从0开始递增计数
   HWREG (Timer1_base + TIMER_O_CTL)|= TIMER_CTL_TAEVENT_Both;
   HWREG (Timer1_base + TIMER_O_TAPR)= 0xFF;
   HWREG (Timer1_base + TIMER_O_TAILR)= 0xFFFF;

   bBitPatternRecognized = false;
   ui32BitLength = 0;
   HWREG (Timer1_base + TIMER_O_IMR)= TIMER_IMR_CAEIM;
   TimerIntRegister (Timer1_base、timer_A、Timer1IntHandler);

   …

   在我设置 TAEN 位后、下拉 PD2上的电压、然后将 PD2上的电压释放为高电平。

   HWREG (Timer1_base + TIMER_O_CTL)|= TIMER_CTL_TAEN;    

   中断未按预期触发。 您能否帮助检查我是否错过了引脚配置?
   bBitPatternRecognized = false;
   ui32BitLength = 0;
   HWREG (Timer1_base + TIMER_O_IMR)= TIMER_IMR_CAEIM;
   TimerIntRegister (Timer1_base、timer_A、Timer1IntHandler);

EV2500_TM4C_003

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

    您好、Steve、

     您为什么不使用 TivaWare 开发您的软件? 编写 DRM (直接寄存器操作)样式很容易出错。  

     以下是您可以参考的一个示例。   如果您坚持使用 DRM、请查看每个函数的源代码并查看它们如何配置计时器。  

    //启用和配置 Timer0外设。
    SysCtlPeripheralEnable (SYSCTL_Periph_TIMER0);
    
    //初始化计时器 A 和 B,以便在边沿计时模式中向上计数
    TimerConfigure (TIMER0_BASE、(TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_CAP_TIME_UP | TIMER_CFG_B_CAP_TIME_UP));
    
    // Timer A 记录位置边沿时间,Timer b 记录 neg 边沿时间
    TimerControlEvent (TIMER0_BASE、TIMER_A、TIMER_EVENT_POS_EDGE);
    TimerControlEvent (TIMER0_BASE、TIMER_B、TIMER_EVENT_NEG_EDGE);
    
    //设置计时器计数到的值(0x9C3F = 39999)
    //CO2传感器输出1kHz PWM、因此 MCU 为40MHz 时、计时器应与 CO2输出保持同步
    TimerLoadSet (TIMER0_BASE、TIMER_Both、0x9C3F);
    
    //配置计时器读取的引脚(PD0)
    SysCtlPeripheralEnable (SYSCTL_Periph_GPIOD);
    GPIOPinConfigure (GPIO_PD0_T0CCP0);
    GPIOPinTypeTimer (GPIO_PORTD_base、GPIO_PIN_0);
    
    
    //注册一个中断函数,当计时器 b 遇到 neg 边缘事件时调用该函数
    内部寄存器(INT_TIMER0A、DUTY 周期);
    //确保清除中断
    TimerIntClear (TIMER0_BASE、TIMER_CAP_EVENT);
    //启用指示的定时器中断源。
    TimerIntEnable (TIMER0_BASE、TIMER_CAP_EVENT);
    //在中断控制器中启用指定的中断。
    IntEnable (INT_TIMER0A); 

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

    您好、Charles

       感谢您的回复、我使用 DRM 是因为它对我更有前景、而且、我还记得在中断处理程序中使用 TivaWare 函数会导致警告

       我会仔细阅读您的代码并检查代码中缺少的内容

    谢谢

    Steven

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

    您好、Charles

       我仍对您的参考代码有几个问题:

       1:在 TimerConfigure 函数中、我发现以下代码始终将 TnPWMIE 位的 TAMR 或 TBMR 位置位、因为目的是设置输入边沿计时模式、所以 TnMR 寄存器中的 TnPWMIE 位为什么要置位?

       if (new_timer_configuration)
       {
           HWREG (ui32Base + TIMER_O_TAMR)=((((ui32Config & 0x000f0000)>> 4)|
                                             (ui32Config & 0xff)|
                                             Timer_TAMR_TAPWMIE);
           HWREG (ui32Base + TIMER_O_TBMR)=((((ui32Config & 0x00f00000)>> 8)|
                                             ((ui32Config >> 8)& 0xff)|
                                             Timer_TBMR_TBPWMIE);
       }
       其他
       {
           HWREG (ui32Base + TIMER_O_TAMR)=((ui32Config & 0xff)|
                                             Timer_TAMR_TAPWMIE);
           HWREG (ui32Base + TIMER_O_TBMR)=((((ui32Config >> 8)& 0xff)|
                                             Timer_TBMR_TBPWMIE);
       }

       2:   在函数 GPIOPinTypeTimer()中,我找到以下代码:

       //
       //为标准推挽操作设置焊盘。
       //
       GPIOPadConfigSet (ui32Port、ui8引脚、GPIO_Strength _2mA、GPIO_PIN_TYPE_STD);

       这是否表示该引脚仅在配置为 TxCCPx 引脚时才能设置为标准推挽模式?

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

    您好、Charles

       我需要将 Timer1_A 配置为输入边沿时间模式并检测引脚 PD2上正边沿上的时间、使用您在上面提供的参考代码、我按照如下方式为 Timer1_A 编写代码、 但我仍然无法触发 Timer1_A 中断、请您进一步帮助检查以下代码是否有问题:

       SysCtlPeripheralEnable (SYSCTL_Periph_Timer1);
       TimerConfigure (Timer1_base、(TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_CAP_TIME_UP));
       TimerControlEvent (Timer1_base、timer_A、timer_event_POS_EDGE);

       SysCtlPeripheralEnable (SYSCTL_Periph_GPIOD);
       GPIOPinConfigure (GPIO_PD2_T1CCP0);
       GPIOPinTypeTimer (GPIO_PORTD_base、GPIO_PIN_2);

       //注册一个中断函数,当计时器 b 遇到 neg 边缘事件时调用该函数
       IntRegister (INT_TIMER1A、Timer1IntHandler);
       //确保清除中断
       TimerIntClear (Timer1_base、timer_CAP_event);
       //启用指示的定时器中断源。
       TimerIntEnable (Timer1_base、timer_CAP_event);
       //在中断控制器中启用指定的中断。
       IntEnable (INT_TIMER1A);

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

    您好 Steven、

     我没有看到您在处理器级别启用 NVIC 中断。 请调用 IntMasterEnable()来启用处理器中断。 请告诉我这是否能解决您的问题。  

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

    您好、Charles

       在 Timer1初始化完成后、我添加了 IntMasterEnable 函数、但仍无法触发中断。

       我还检查了 PRIMASK 寄存器中的 lsb、在调用 IntMasterEnable 函数之前和之后、该位始终清零、这表示在之前的代码中已启用 NVIC 中断。 是否有任何其他原因导致定时器中断触发失败

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

    您好、Steve、

     TivaWare 库中有一个边沿计时 CCS 工程示例。 您可以在 C:\ti\TivaWare_C_Series-2.2.0.295\examples\boards\ek-tm4c1294xl\timer_edge_capture 中找到示例。 请按原样尝试此示例、看看是否可以使其正常工作。 工作后、您可以修改 Timer1。 我认为您缺少的是以下两行。 无论如何、请先尝试该示例、看看您是否可以使其正常工作。  

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

    您好、Charles

       感谢您对此案例的支持、现已确定此问题的原因!