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**** 2391225 points
Other Parts Discussed in Thread: ENERGIA, EK-TM4C1294XL

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1423591/tm4c1294ncpdt-timer-interrupt-question

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

工具与软件:

我已上传下面的代码。 我使用的是 Code Composer Studio v11.2。

PF_0的输出切换18次、当中断发生时、它保持在高电平状态。 我认为我无法使用 ROM_TimerIntClear (TIMER0_BASE、TIMER_TIMA_TIMEOUT)清除中断标志;

您能评论以下代码吗?

#include <stdint.h>
#include <stdbool.h>
#include "inc/tm4c1294ncpdt.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "driverlib/timer.h"
#include "driverlib/interrupt.h"
#include "driverlib/pin_map.h"

#define SYSTEM_CLOCK 120000000
void Timer0IntHandler(void)
{
    ROM_TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
    digitalWrite(PF_0, 0);
              delay(500);
              digitalWrite(PF_0, 1);
                        delay(500);
}

void ConfigureTimer(void)
{
    SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
    TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC);
    uint32_t timerLoad=399500000;
    TimerLoadSet(TIMER0_BASE,TIMER_A, timerLoad - 1);
    IntEnable(INT_TIMER0A);
    TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
    TimerEnable(TIMER0_BASE, TIMER_A);
}

void setup(void)
{
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    pinMode(PF_0, OUTPUT);
    SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), SYSTEM_CLOCK);
    ConfigureTimer();
    IntMasterEnable();
    while (1)
    {
        digitalWrite(PF_0, 0);
          delay(100);
          digitalWrite(PF_0, 1);
                    delay(100);
    }
}

void loop() {}

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [quote userid="626477" url="~/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1423591/tm4c1294ncpdt-timer-interrupt-question pf_0的输出切换18次、当发生中断时、它保持在高电平状态

    是从示波器还是从 LED 看到它保持在高电平?

    如果在 ISR 中放置一个断点、处理器是否在每次计时器超时时时时时暂停?

    该标志在 ISR 中被清除、但您需要再次将 PF0引脚设置为高电平。 如果您尝试在 LED 中查看 PF0、即使您尝试在很短的时间内重复清除和设置引脚、它通常仍会保持盖子。 就您的眼睛而言、它变得太快、您无法看到它变低了。  

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

    使用120MHz 时钟时、400M 时钟大约为3.5秒、这大约是通过(200ms)主循环的18次。 这表明第一个 ISR 调用失败了。

    如何实现 delay()? 我已经看到使用 SysTick 和中断计数完成了这一操作、这会在从 ISR 调用时使其失败(从不返回)。

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

    感谢您的回答。 我将使用示波器来检查引脚的状态。 我相信它不会进入 ISR。 因为 PF0波形中的脉冲宽度和周期相同。 在 Timer0IntHandler 中、我使用不同的脉冲宽度。

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

    Bruce、您好!

    感谢您的回答。 我想它并不像您所说的那样进入 ISR。 总方波持续时间为3.36秒、并不会在 ISR 中生成较长的脉冲。

    我已经更新到 SysCtlDelay。 同样、总方波持续时间为3.36秒、然后它变为高电平。 我正在使用示波器进行检查。  我可以使用什么来代替 Delay 或 SysCtlDelay? 我已从 Energia sketch 中导入此函数。

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

    您好!

    我已经将以下代码段插入到配置计时器块中。

    TimerIntRegister (TIMER0_BASE、TIMER_A、Timer0IntHandler);并且它在中断中断错误时不会残桩。 感谢您的帮助

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    TimerIntRegister (TIMER0_BASE、TIMER_A、Timer0IntHandler);并且它在中断处理时不会存根。 感谢您的帮助

    您说的是在最初发布的代码中、您从来没有在矢量表中以静态或动态方式指定中断矢量?

    通常情况下、您需要将向量添加到 startup_ccs.c 文件中的向量表中。 请参阅以下示例。 使用  TimerIntRegister (TIMER0_BASE、TIMER_A、Timer0IntHandler)是将矢量插入表的动态方法。  

    为什么不尝试 C:\ti\TivaWare_C_Series-2.2.0.295\examples\boards\ek-tm4c1294xl\timers 中的示例、并与您的代码进行比较。

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

    尊敬的 Charles Tsai:

    感谢您的帮助。  我的问题得到了解决。 我正在检查 TivaWare 中的示例文件夹、我还有另一个相关问题。 为了生成周期为20ms 的200ns 脉冲、我将使用 TimerConfigure (TIMER0_BASE、TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PWM);
    脉冲周期不能增加超过 546usec(120000000*65536)它不能产生更长的脉冲周期。 你能建议任何其他的选择吗?

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

    您好!

     有关详细信息、请参阅数据表。 该示例演示的是仅使用16位的分离式计时器。 在分页计时器模式下、您可以添加一个额外的8位预分频器来形成一个24位计数器、从而延长您的周期。 当然、您也可以将两个16位计数器串联在一起以创建一个32位计数器。  

    13.3功能说明
    每个 GPTM 模块的主要元件是两个自由运行的递增/递减计数器(称为
    Timer A 和 Timer B)、两个预分频器寄存器、两个匹配寄存器、两个预分频器匹配寄存器、
    两个影子寄存器、两个加载/初始化寄存器及其相关的控制功能。
    GPTM 的准确功能可由软件来控制、并通过寄存器进行配置
    缩写。 Timer A 和 Timer B 可以单独使用、在这种情况下、它们有一个16位的计数
    16/32位 GPTM 模块的内部范围。 此外、可以将 Timer A 和 Timer B 连接到
    为16/32位 GPTM 模块提供32位的计数范围。 请注意、预分频器只能是
    当单独使用定时器时使用。

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

    查尔斯·蔡先生:
    此代码生成390ns 脉冲宽度和8ms PRI 持续时间。 不过、计时过程可能不会产生所需的脉冲宽度、而是会产生较短的脉冲。 能否指出我的错误?

    #define SYSTEM_CLOCK 120000000  
    
    void ConfigurePWM(void) {
        SysCtlPWMClockSet(SYSCTL_PWMDIV_1);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); 
        GPIOPinTypePWM(GPIO_PORTF_BASE, GPIO_PIN_1);
        GPIOPinConfigure(GPIO_PF1_M0PWM1);
        PWMGenConfigure(PWM0_BASE, PWM_GEN_0, PWM_GEN_MODE_DOWN | PWM_GEN_MODE_NO_SYNC);
        PWMGenPeriodSet(PWM0_BASE, PWM_GEN_0, 1200);  // Configure period for PWM
        PWMPulseWidthSet(PWM0_BASE, PWM_OUT_1, 47);
        PWMOutputState(PWM0_BASE, PWM_OUT_1_BIT, false);
    }
    
    void Timer0IntHandler_short(void) {
        TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
        PWMGenEnable(PWM0_BASE, PWM_GEN_0);
        PWMOutputState(PWM0_BASE, PWM_OUT_1_BIT, true);
        SysCtlDelay(320);  // corresponds to 8usec of delay
        PWMOutputState(PWM0_BASE, PWM_OUT_1_BIT, false);
    }
    void ConfigureTimer(void) {
        SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
        TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC);
        TimerLoadSet(TIMER0_BASE, TIMER_A, 960000-1);//Multiple of 1200
        IntEnable(INT_TIMER0A);
        TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
        TimerIntRegister(TIMER0_BASE, TIMER_A, Timer0IntHandler_short);
        TimerEnable(TIMER0_BASE, TIMER_A);
    }
    // Main function to start short pulse generation
    void SinglePulse_Short(void) {
        ConfigurePWM();
        ConfigureTimer();
    }
    
    

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

    您好!

     为什么要将 SysCtlDelay (320)添加到 ISR 中? 此延迟等于8.3 * 320 * 3 = 7960ns。 这比脉冲宽度长得多。  SysCtlDelay (1)等于3个 CPU 周期。  

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

    PWMPulseWidthSet (PWM0_BASE、PWM_OUT_1、47);该部分生成390ns 脉冲宽度、

    PWMGenPeriodSet (PWM0_BASE、PWM_GEN_01200);然后在1200处完成 PWM 周期前、使用 SysCtlDelay (320)和 PWMOutputState (PWM0_BASE、PWM_OUT_1_BIT、FALSE);PWM 被禁用。
     8毫秒后、PWMGenEnable (PWM0_BASE、PWM_GEN_0);在 Timer0IntHandler_short 中再次启用 PWM。