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.

[参考译文] EK-TM4C1294XL:EK-TM4C1294XL

Guru**** 2539340 points
Other Parts Discussed in Thread: EK-TM4C1294XL

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1048484/ek-tm4c1294xl-ek-tm4c1294xl

器件型号:EK-TM4C1294XL

尊敬的先生/女士:

我正在使用 EK-TM4C1294XL 电路板 、需要从其中一条 GPIO 线路生成5MHz 信号。  我正在使用 TIMERA、并且能够通过 GPIO 线路生成1.17Mhz 信号。  我的 TIMERA ISR 只有以下两行:

G_ui32Flags = 1 - g_ui32Flags;

GPIOPinWrite (GPIO_PORTL_base、GPIO_PIN_0、 g_ui32Flags);

是否有方法生成5MHz 信号?  我假设使用120MHz 的系统时钟时、我可以这样做、但我想知道即使我必须以其他方式这样做、这是否可能。

感谢你的帮助。

Jorge Gonzalez

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

    您好!

      为了增加频率,您需要直接写入 GPIO 数据寄存器,因为 GPIOPinWrite()函数在写入数据之前执行一些移位运算来计算地址。 您 的 g_ui32Flags = 1 - g_ui32Flags 也需要一些周期来完成。  查看反汇编窗口、您可以找到生成的汇编指令并推算所需的周期数。  如果您知道要写入的确切值和寄存器地址、则可以通过如下方式直接写入寄存器来降低延迟:

     HWREG (GPIOPx_ADDR、0x55);//示例写入值为0x55的任意地址 GPIOx_ADDR

    但是、您永远无法精确地确定您将获得的频率。 要获得一致的5MHz 频率、您应生成 PWM 信号。 定时器模块可被配置为 PWM。 您所需的只是设置周期和占空比、为您提供所需的5MHz 周期性信号。

    请参阅示例 C:\ti\TivaWare_C_Series-2.2.0.295\examples\peripheral\timer\PWM.c

    无效
    GPIOPinWrite (uint32_t ui32Port、uint8_t ui8引脚、uint8_t ui8Val)

    //
    //检查参数。
    //
    assert (_GPIOBaseValid (ui32Port));

    //
    //写入引脚。
    //
    HWREG (ui32Port +(GPIO_O_DATA +(ui8引脚<< 2)))= ui8Val;

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

    非常感谢 Charles。  我将尝试您的建议。

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

    查尔斯

    我找到 了 EK-TM4C1294XL 电路板的 PWM 示例、但我可以生成的最快周期是千赫兹范围。  我想使用120MHz 系统时钟时、我可以生成5MHz、但我开始认为我无法生成。  我是对的吗?

    感谢你的所有帮助。

    Jorge Gonzalez

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

    下面是一个5MHz PWM 示例。 PWM 周期为5MHz、占空比在25%和75%之间变化。  

     

    #include <stdbool.h>
    #include <stdint.h>
    #include "inc/hw_memmap.h"
    #include "driverlib/debug.h"
    #include "driverlib/gpio.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/pwm.h"
    #include "driverlib/rom.h"
    #include "driverlib/rom_map.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/uart.h"
    #include "utils/uartstdio.h"
    
    
    //*****************************************************************************
    //
    // The variable g_ui32SysClock contains the system clock frequency in Hz.
    //
    //*****************************************************************************
    uint32_t g_ui32SysClock;
    
    //*****************************************************************************
    //
    // The error routine that is called if the driver library encounters an error.
    //
    //*****************************************************************************
    #ifdef DEBUG
    void
    __error__(char *pcFilename, uint32_t ui32Line)
    {
    }
    #endif
    
    
    //*****************************************************************************
    //
    // Configure PWM for a 25% duty cycle signal running at 250Hz.
    //
    //*****************************************************************************
    int
    main(void)
    {
        uint32_t ui32PWMClockRate;
    
        //
        // Run from the PLL at 120 MHz.
        // Note: SYSCTL_CFG_VCO_240 is a new setting provided in TivaWare 2.2.x and
        // later to better reflect the actual VCO speed due to SYSCTL#22.
        //
        g_ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
                                                 SYSCTL_OSC_MAIN |
                                                 SYSCTL_USE_PLL |
                                                 SYSCTL_CFG_VCO_240), 120000000);
    
    
        //
        // The PWM peripheral must be enabled for use.
        //
        MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0);
    
        //
        // Enable the GPIO port that is used for the PWM output.
        //
        MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    
        //
        // Configure the PWM function for this pin.
        //
        MAP_GPIOPinConfigure(GPIO_PF2_M0PWM2);
        MAP_GPIOPinTypePWM(GPIO_PORTF_BASE, GPIO_PIN_2);
    
        //
        // Set the PWM clock to be SysClk / 8.
        //
        MAP_PWMClockSet(PWM0_BASE, PWM_SYSCLK_DIV_1);
        //
        // Use a local variable to store the PWM clock rate which will be
        // 120 MHz / 8 = 15 MHz. This variable will be used to set the
        // PWM generator period.
        //
        ui32PWMClockRate = g_ui32SysClock / 1;
    
        //
        // Configure PWM2 to count up/down without synchronization.
        //
        MAP_PWMGenConfigure(PWM0_BASE, PWM_GEN_1,
                            PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_NO_SYNC);
    
        //
        // Set the PWM period to 5Mhz.  To calculate the appropriate parameter
        // use the following equation: N = (1 / f) * PWMClk.  Where N is the
        // function parameter, f is the desired frequency, and PWMClk is the
        // PWM clock frequency based on the system clock.
        //
        MAP_PWMGenPeriodSet(PWM0_BASE, PWM_GEN_1, (ui32PWMClockRate / 5000000));
    
        //
        // Set PWM2 to a duty cycle of 25%.  You set the duty cycle as a function
        // of the period.  Since the period was set above, you can use the
        // PWMGenPeriodGet() function.  For this example the PWM will be high for
        // 25% of the time or (PWM Period / 4).
        //
        MAP_PWMPulseWidthSet(PWM0_BASE, PWM_OUT_2,
                             MAP_PWMGenPeriodGet(PWM0_BASE, PWM_GEN_1) / 4);
    
        //
        // Enable PWM Out Bit 2 (PF2) output signal.
        //
        MAP_PWMOutputState(PWM0_BASE, PWM_OUT_2_BIT, true);
    
        //
        // Enable the PWM generator block.
        //
        MAP_PWMGenEnable(PWM0_BASE, PWM_GEN_1);
    
        //
        // Loop forever while the PWM signals are generated.
        //
        while(1)
        {
            //
            // This function provides a means of generating a constant length
            // delay.  The function delay (in cycles) = 3 * parameter.  Delay
            // 2 seconds arbitrarily.
            //
            MAP_SysCtlDelay((g_ui32SysClock * 2) / 3);
    
            //
            // Invert PWM2 signal.
            //
            MAP_PWMOutputInvert(PWM0_BASE, PWM_OUT_2_BIT, true);
    
            //
            // This function provides a means of generating a constant length
            // delay.  The function delay (in cycles) = 3 * parameter.  Delay
            // 2 seconds arbitrarily.
            //
            MAP_SysCtlDelay((g_ui32SysClock * 2) / 3);
    
            //
            // Switch PWM2 signal back to regular operation.
            //
            MAP_PWMOutputInvert(PWM0_BASE, PWM_OUT_2_BIT, false);
        }
    }
    

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

    如果您希望使用计时器模块生成 PWM、下面是另一个生成5MHz PWM 的示例。  

    #include <stdbool.h>
    #include <stdint.h>
    #include "inc/hw_gpio.h"
    #include "inc/hw_ints.h"
    #include "inc/hw_memmap.h"
    #include "inc/hw_timer.h"
    #include "inc/hw_types.h"
    #include "driverlib/gpio.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/timer.h"
    #include "driverlib/uart.h"
    #include "utils/uartstdio.h"
    
    
    //*****************************************************************************
    //
    // The g_ui32SysClock contains the system clock frequency
    //
    //*****************************************************************************
    
    uint32_t g_ui32SysClock;
    
    
    //*****************************************************************************
    //
    // Configure Timer3A as a 16-bit PWM with a duty cycle of 66%.
    //
    //*****************************************************************************
    int
    main(void)
    {
        //
        // Set the clocking to run directly from the external crystal/oscillator.
        // TODO: The SYSCTL_XTAL_ value must be changed to match the value of the
        // crystal on your board.
        //
    
        g_ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
                                           SYSCTL_OSC_MAIN |
                                           SYSCTL_USE_PLL |
                                           SYSCTL_CFG_VCO_480), 120000000);
    
        //
        // The Timer1 peripheral must be enabled for use.
        //
        SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER3);
    
        //
        // For this example T3CCP0 is used with port B pin 2 or port M pin 2.
        // The actual port and pins used may be different on your part, consult
        // the data sheet for more information.
        // GPIO port B needs to be enabled so these pins can be used.
        // TODO: change this to whichever GPIO port you are using.
        //
    
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOM);
    
        //
        // Configure the GPIO pin muxing for the Timer/CCP function.
        // This is only necessary if your part supports GPIO pin function muxing.
        // Study the data sheet to see which functions are allocated per pin.
        // TODO: change this to select the port/pin you are using
        //
        GPIOPinConfigure(GPIO_PM2_T3CCP0);
    
        //
        // Configure the ccp settings for CCP pin.  This function also gives
        // control of these pins to the SSI hardware.  Consult the data sheet to
        // see which functions are allocated per pin.
        // TODO: change this to select the port/pin you are using.
        //
        GPIOPinTypeTimer(GPIO_PORTM_BASE, GPIO_PIN_2);
    
        //
        // Configure Timer3A as a 16-bit periodic timer.
        //
        TimerConfigure(TIMER3_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PWM);
    
        //
        // Set the Timer3A load value to (120000000/5000000=24) - 1
        //
        TimerLoadSet(TIMER3_BASE, TIMER_A, g_ui32SysClock / 5000000 - 1);
    
        //
        // Set the Timer3A match value to load value / 2.
        //
        TimerMatchSet(TIMER3_BASE, TIMER_A,
                      TimerLoadGet(TIMER3_BASE, TIMER_A) / 2);
    
        //
        // Enable Timer3A.
        //
        TimerEnable(TIMER3_BASE, TIMER_A);
    
        //
        // Loop forever while the Timer3A PWM runs.
        //
        while(1)
        {
    
        }
    }