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.

[参考译文] TM4C129CNCZAD:使用 TI-RTOS 时发生 T0CCP0中断

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1299613/tm4c129cnczad-t0ccp0-interrupt-while-using-ti-rtos

器件型号:TM4C129CNCZAD
Thread 中讨论的其他器件:SYSBIOS

我正在尝试使用捕获控制引脚来测量输入引脚的 PWM。 我仔细阅读、发现使用2个引脚最简单、但遗憾的是、我当前的应用中只有1个引脚。 我将使用 T0CCP0来使用计时器0A 中断。 代码如下所示:

用于创建 HWI 并切换内部时钟以使用 timer3的 application.cfg 设置

var Clock = xdc.useModule('ti.sysbios.knl.Clock');
Clock.timerId = 3; /* use timer 3 */

var ti_sysbios_family_arm_m3_Hwi3Params = new ti_sysbios_family_arm_m3_Hwi.Params();
ti_sysbios_family_arm_m3_Hwi3Params.instance.name = "motorSpeedIntHandle";
Program.global.motorSpeedIntHandle = ti_sysbios_family_arm_m3_Hwi.create(19, "&MotorSpeedIntHandler", ti_sysbios_family_arm_m3_Hwi3Params);

PWM_Measure.cc

extern "C" void MotorSpeedIntHandler() {
  static uint32_t pwm_fall_edge = 0;
  static uint32_t pwm_rise_edge = 0;
  static uint32_t log_counter = 0;
  // Timer has timed out
  if (TimerIntStatus(TIMER0_BASE, TIMER_TIMA_TIMEOUT) == TIMER_TIMA_TIMEOUT) {
      // If we timed out throw away sample
      pwm_fall_edge = 0;
      pwm_rise_edge = 0;
      TimerIntClear(TIMER0_BASE,  TIMER_TIMA_TIMEOUT);
  }
  if (TimerIntStatus(TIMER0_BASE, TIMER_TIMA_TIMEOUT) == TIMER_CAPA_EVENT) {
      int32_t pin_value = GPIOPinRead(GPIO_PORTL_BASE, GPIO_PIN_4);
      if (pin_value == 0) {
        pwm_fall_edge = TimerValueGet(TIMER0_BASE, TIMER_A);
        int32_t pwm_on_time = pwm_rise_edge - pwm_fall_edge;
        motor_speed_measured_RPM = (pwm_on_time / MOTOR_PWM_FEEDBACK_SPEED_CONVERSION_INVERSE);
      } else {
        pwm_rise_edge = TimerValueGet(TIMER0_BASE, TIMER_A);
      }
      TimerIntClear(TIMER0_BASE, TIMER_CAPA_EVENT);
  }
}

void motorControlFeedbackInit() {
  // Signal is a 482Hz from 5% - 100% duty cycle
  SysCtlPeripheralDisable(SYSCTL_PERIPH_TIMER0);
  SysCtlPeripheralReset(SYSCTL_PERIPH_TIMER0);
  SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);

  // Initialize timer A and B to count up in edge time mode
  TimerConfigure(TIMER0_BASE, (TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_CAP_TIME | TIMER_CFG_A_ACT_NONE));
  // 120MHz / 4 = 30MHz
  TimerPrescaleSet(TIMER0_BASE, TIMER_A, 4);

  // Timer a records pos edge time and Timer b records neg edge time
  TimerControlEvent(TIMER0_BASE, TIMER_A, TIMER_EVENT_BOTH_EDGES);

  TimerLoadSet(TIMER0_BASE, TIMER_A, 0xFFFF);

  //Configure the pin that the timer reads from (PL4)
  GPIOPinConfigure(GPIO_PL4_T0CCP0);
  GPIOPinTypeTimer(GPIO_PORTL_BASE, GPIO_PIN_4);

  TimerIntRegister(TIMER0_BASE, TIMER_A, MotorSpeedIntHandler);

  // Enable the indicated timer interrupt source.
  TimerIntClear(TIMER0_BASE, (TIMER_CAPA_EVENT | TIMER_TIMA_TIMEOUT));
  TimerIntEnable(TIMER0_BASE, (TIMER_CAPA_EVENT | TIMER_TIMA_TIMEOUT));
  TimerEnable(TIMER0_BASE, TIMER_A);
}

我遇到的问题是、正如您在 init 函数中看到的那样、我需要手动注册一个中断 、因为在我注册这个中断(或取消注册任何已设置的中断)后、这个中断在.cfg 中都无法正常运行。 我怀疑这是因为 RTOS 使用 timer0、它在后台执行记录自身节拍中断的操作、不喜欢我尝试覆盖该中断的情况。 我是否在.cfg 中遗漏了某个内容?

谢谢!

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

    您好!

     有关详细信息、请参阅此帖子。 基本上,你永远不应该使用 TimerIntRegister 来注册你的 MotorSpeedIntHandler () ISR。 您需要使用 Hwi 来管理 ISR。  

    https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/849627/faq-can-i-update-the-vector-table-with-intregister-when-using-ti-rtos?tisearch=e2e-sitesearch&keymatch=ti-rtos%20vector%20table#

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

    https://e2e.ti.com/support/dlp-products-group/dlp/f/dlp-products-forum/921711/where-does-the-function-timerinthandler-get-assigned-to-be-the-callback-function-for-timer0

    如果不使用 IntRegister 函数、中断永远不会触发、如上面的线程所示、建议在使用 TI-RTOS 时使用该函数来注册新的中断。

    此外、当前的.cfg 文件中是否缺少一个需要注册中断的地方? 如果我没有该 TimerIntRegister ()调用,为什么它不会触发呢?

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

    看起来您提到的帖子不是基于 TI-RTOS 的设计、而是裸机设计。 在这种情况下、您可以使用  TimerIntRegister。 我提到的这篇文章包含了我们 TI-ROS 专家的详细解释、我也提到了 几篇 e2e 文章中的帖子 以及它们的问题已得到解决。   

    https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1211787/simplelink-msp432-sdk-ti-drivers-timer-in-capture-mode/4572062?tisearch=e2e-sitesearch&keymatch=intregister#4572062

    https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1274060/ek-tm4c123gxl-creating-output-section-vtable-without-a-sections/4827442?tisearch=e2e-sitesearch&keymatch=intregister#4827442

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

    好的、明白。 另一个原因。 中断为什么不会触发? 我已在随附的.cfg 文件中将其设置为一个 hwi。 我在工程中定义了其他有效的中断、但这一个似乎不触发。 您对原来的问题有任何意见吗?

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

    您好!

     我认为问题与中断编号有关。 可以尝试 timer0的矢量编号35吗?

    program.global.motorSpeedIntHandle = ti_sysbios_family_arm_m3_Hwi.create ( 19 、"&MotorSpeedIntHandler"、ti_sysBIOS_family_arm_m3_Hwi3Params);

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

    啊,我发誓我检查了两次,但那个桌子让我再次,因为它总是. 我将其更改为使用35、但现在我收到一个编译器错误、该错误表示我认为会发生什么情况。

    ti.sysbios.family.arm.lm4.Timer.Instance_State#1 : Timer interrupt 35 already in use!
    

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

    是的、回答正确。 Timer0由 TI-RTOS 用于 Tiva 器件。 请参阅 TI-RTOS 入门指南。  https://www.ti.com/lit/pdf/spruhu5。 您可以使用其他计时器实例吗?

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

    在我的.cfg 文件中、我尝试让 RTOS 使用 timer3、这不可能吗、或者我的操作是否错误?  e2e.ti.com/.../ti-rtos-and-timer0

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

    您好!

     我认为它应该起作用。 我只是在一个简单的 hello 程序上尝试、方法是将 timerID 更改为3作为内核的基本时钟。  请参阅下面以黄色突出显示的屏幕截图。 如右上角所示、Timer3在寄存器窗口中可见。 如果未使用 Timer3、则会显示错误:无法读取"消息。 我还使用 ROV 来确认 timer3被内核使用。  

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

    您是否尝试将中断绑定到 timer0? 我让该行将 RTOS 时钟模块更改为使用 timer3、但在使用该中断时仍无法编译。 我试图避免更改引脚、这样我就不必进行电路板旋转、但如果不可能、我理解。

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

    您好!

     我刚刚运行了一个简单的示例、使用 timer3进行内核节拍、timer0用于在 TM4C123 MCU 上生成周期性中断。 我将获得中止。 以下是我的代码。 我使用 TI-RTOS 计时器驱动程序而不是 TivaWare 本机 API 来创建中断。 运行代码时、我将在 Timer0初始化期间获得中止。 它将无法检查所选计时器是否为有效计时器。 我还修改了代码、以使用 Timer4生成中断、并保留 Timer3用于内核节拍。 在本例中、它将很好地工作。 我认为问题是、如果用于内核的实例之前的计时器实例索引(例如0、1或2)将导致中止。 它在第293行出现故障、因为 tempId 由于早期代码中的掩码而变为0xFFFF。 我想 TI-RTOS 没有考虑到 timer0可用于正常计时器使用。  

    //----------------------------------------
    // BIOS header files
    //----------------------------------------
    #include <xdc/std.h>  						//mandatory - have to include first, for BIOS types
    #include <ti/sysbios/BIOS.h> 				//mandatory - if you call APIs like BIOS_start()
    #include <xdc/runtime/Log.h>				//needed for any Log_info() call
    #include <xdc/cfg/global.h> 				//header file for statically defined objects/handles
    #include <xdc/runtime/System.h>
    #include <xdc/runtime/Error.h>
    #include <ti/sysbios/hal/Hwi.h>
    #include <ti/sysbios/hal/Timer.h>
    
    //------------------------------------------
    // TivaWare Header Files
    //------------------------------------------
    #include <stdint.h>
    #include <stdbool.h>
    
    #include "inc/hw_types.h"
    #include "inc/hw_memmap.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/gpio.h"
    #include "inc/hw_ints.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/timer.h"
    
    
    //----------------------------------------
    // Prototypes
    //----------------------------------------
    void hardware_init(void);
    void ledToggle(void);
    
    
    //---------------------------------------
    // Globals
    //---------------------------------------
    volatile int16_t i16ToggleCount = 0;
    
    
    //---------------------------------------------------------------------------
    // main()
    //---------------------------------------------------------------------------
    void main(void)
    {
    
        Timer_Params Timer0;
        Timer_Handle myTimer;
    
       hardware_init();							// init hardware via Xware
    
       Timer_Params_init(&Timer0);
       Timer0.arg=0;
       Timer0.period=100000;
       Timer0.periodType=Timer_PeriodType_MICROSECS;
       myTimer=Timer_create(0,(Timer_FuncPtr)ledToggle,&Timer0,NULL);
       Timer_start(myTimer);
    
       BIOS_start();
    
    }
    
    
    //---------------------------------------------------------------------------
    // hardware_init()
    //
    // inits GPIO pins for toggling the LED
    //---------------------------------------------------------------------------
    void hardware_init(void)
    {
    //	uint32_t ui32Period;
    
    	//Set CPU Clock to 40MHz. 400MHz PLL/2 = 200 DIV 5 = 40MHz
    	SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);
    
    	// ADD Tiva-C GPIO setup - enables port, sets pins 1-3 (RGB) pins for output
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    	GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3);
    
    	// Turn on the LED
    	GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 4);
    
    
    }
    
    
    //---------------------------------------------------------------------------
    // ledToggle()
    //
    // toggles LED on Tiva-C LaunchPad
    //---------------------------------------------------------------------------
    void ledToggle(void)
    {
        TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);			// must clear timer flag FROM timer
    
    	// LED values - 2=RED, 4=BLUE, 8=GREEN
    	if(GPIOPinRead(GPIO_PORTF_BASE, GPIO_PIN_2))
    	{
    		GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 0);
    	}
    	else
    	{
    		GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 4);
    	}
    
    	i16ToggleCount += 1;									// keep track of #toggles
    
    	Log_info1("LED TOGGLED [%u] TIMES",i16ToggleCount);		// send toggle count to UIA
    
    }

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

    好的、所以在使用 RTOS 时无法使用 timer0用于中断、感谢 Charles 的帮助!