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.

如何使用CC2640的硬件定时器进行捕获

Other Parts Discussed in Thread: CC2640R2F

项目中有一个环节是捕获电机返回的FG脉冲信号,现在我想要获取该脉冲信号的宽度计算出电机转速,我该如何配置定时器?

  • 你可以参考C:\ti\tirtos_cc13xx_cc26xx_2_21_01_08\products\cc26xxware_2_24_03_17272\driverlib目录
    下的timer.c和timer.h文件将timerA或timerB设置成capture模式
  • 有在线文档吗?我一时找不到这个路径
  • 标题写错了,用的CC2640R2F
  • 关于定时器请看文档13节:

    代码部分还得看tirtos_cc13xx_cc26xx_2_21_01_08\products\cc26xxware_2_24_03_17272\driverlib

    下的timer文件,请在附件中查看timer.h

    /******************************************************************************
    *  Filename:       timer.c
    *  Revised:        2016-06-30 09:21:03 +0200 (Thu, 30 Jun 2016)
    *  Revision:       46799
    *
    *  Description:    Driver for the General Purpose Timer
    *
    *  Copyright (c) 2015 - 2016, Texas Instruments Incorporated
    *  All rights reserved.
    *
    *  Redistribution and use in source and binary forms, with or without
    *  modification, are permitted provided that the following conditions are met:
    *
    *  1) Redistributions of source code must retain the above copyright notice,
    *     this list of conditions and the following disclaimer.
    *
    *  2) Redistributions in binary form must reproduce the above copyright notice,
    *     this list of conditions and the following disclaimer in the documentation
    *     and/or other materials provided with the distribution.
    *
    *  3) Neither the name of the ORGANIZATION nor the names of its contributors may
    *     be used to endorse or promote products derived from this software without
    *     specific prior written permission.
    *
    *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
    *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    *  POSSIBILITY OF SUCH DAMAGE.
    *
    ******************************************************************************/
    
    #include <driverlib/timer.h>
    
    //*****************************************************************************
    //
    // Handle support for DriverLib in ROM:
    // This section will undo prototype renaming made in the header file
    //
    //*****************************************************************************
    #if !defined(DOXYGEN)
        #undef  TimerConfigure
        #define TimerConfigure                  NOROM_TimerConfigure
        #undef  TimerLevelControl
        #define TimerLevelControl               NOROM_TimerLevelControl
        #undef  TimerStallControl
        #define TimerStallControl               NOROM_TimerStallControl
        #undef  TimerWaitOnTriggerControl
        #define TimerWaitOnTriggerControl       NOROM_TimerWaitOnTriggerControl
        #undef  TimerIntRegister
        #define TimerIntRegister                NOROM_TimerIntRegister
        #undef  TimerIntUnregister
        #define TimerIntUnregister              NOROM_TimerIntUnregister
        #undef  TimerMatchUpdateMode
        #define TimerMatchUpdateMode            NOROM_TimerMatchUpdateMode
        #undef  TimerIntervalLoadMode
        #define TimerIntervalLoadMode           NOROM_TimerIntervalLoadMode
    #endif
    
    //*****************************************************************************
    //
    //! \brief Gets the timer interrupt number.
    //!
    //! Given a timer base address, this function returns the corresponding
    //! interrupt number.
    //!
    //! \param ui32Base is the base address of the timer module.
    //!
    //! \return Returns a timer interrupt number, or -1 if \c ui32Base is invalid.
    //
    //*****************************************************************************
    static uint32_t
    TimerIntNumberGet(uint32_t ui32Base)
    {
        uint32_t ui32Int;
    
        //
        // Loop through the table that maps timer base addresses to interrupt
        // numbers.
        //
        switch(ui32Base)
        {
        case GPT0_BASE :
            ui32Int = INT_GPT0A;
            break;
        case GPT1_BASE :
            ui32Int = INT_GPT1A;
            break;
        case GPT2_BASE :
            ui32Int = INT_GPT2A;
            break;
        case GPT3_BASE :
            ui32Int = INT_GPT3A;
            break;
        default :
            ui32Int = 0x0;
        }
    
        //
        // Return the interrupt number or (-1) if not base address is not matched.
        //
        return (ui32Int);
    }
    
    //*****************************************************************************
    //
    //! Configures the timer(s)
    //
    //*****************************************************************************
    void
    TimerConfigure(uint32_t ui32Base, uint32_t ui32Config)
    {
        //
        // Check the arguments.
        //
        ASSERT(TimerBaseValid(ui32Base));
        ASSERT((ui32Config == TIMER_CFG_ONE_SHOT) ||
               (ui32Config == TIMER_CFG_ONE_SHOT_UP) ||
               (ui32Config == TIMER_CFG_PERIODIC) ||
               (ui32Config == TIMER_CFG_PERIODIC_UP) ||
               ((ui32Config & 0xFF000000) == TIMER_CFG_SPLIT_PAIR));
        ASSERT(((ui32Config & 0xFF000000) != TIMER_CFG_SPLIT_PAIR) ||
               ((((ui32Config & 0x000000FF) == TIMER_CFG_A_ONE_SHOT) ||
                 ((ui32Config & 0x000000FF) == TIMER_CFG_A_ONE_SHOT_UP) ||
                 ((ui32Config & 0x000000FF) == TIMER_CFG_A_PERIODIC) ||
                 ((ui32Config & 0x000000FF) == TIMER_CFG_A_PERIODIC_UP) ||
                 ((ui32Config & 0x000000FF) == TIMER_CFG_A_CAP_COUNT) ||
                 ((ui32Config & 0x000000FF) == TIMER_CFG_A_CAP_COUNT_UP) ||
                 ((ui32Config & 0x000000FF) == TIMER_CFG_A_CAP_TIME) ||
                 ((ui32Config & 0x000000FF) == TIMER_CFG_A_CAP_TIME_UP) ||
                 ((ui32Config & 0x000000FF) == TIMER_CFG_A_PWM)) &&
                (((ui32Config & 0x0000FF00) == TIMER_CFG_B_ONE_SHOT) ||
                 ((ui32Config & 0x0000FF00) == TIMER_CFG_B_ONE_SHOT_UP) ||
                 ((ui32Config & 0x0000FF00) == TIMER_CFG_B_PERIODIC) ||
                 ((ui32Config & 0x0000FF00) == TIMER_CFG_B_PERIODIC_UP) ||
                 ((ui32Config & 0x0000FF00) == TIMER_CFG_B_CAP_COUNT) ||
                 ((ui32Config & 0x0000FF00) == TIMER_CFG_B_CAP_COUNT_UP) ||
                 ((ui32Config & 0x0000FF00) == TIMER_CFG_B_CAP_TIME) ||
                 ((ui32Config & 0x0000FF00) == TIMER_CFG_B_CAP_TIME_UP) ||
                 ((ui32Config & 0x0000FF00) == TIMER_CFG_B_PWM))));
    
        //
        // Disable the timers.
        //
        HWREG(ui32Base + GPT_O_CTL) &= ~(GPT_CTL_TAEN | GPT_CTL_TBEN);
    
        //
        // Set the global timer configuration.
        //
        HWREG(ui32Base + GPT_O_CFG) = ui32Config >> 24;
    
        //
        // Set the configuration of the A and B timers. Note that the B timer
        // configuration is ignored by the hardware in 32-bit modes.
        //
        HWREG(ui32Base + GPT_O_TAMR) = (ui32Config & 0xFF) | GPT_TAMR_TAPWMIE;
        HWREG(ui32Base + GPT_O_TBMR) =
            ((ui32Config >> 8) & 0xFF) | GPT_TBMR_TBPWMIE;
    }
    
    //*****************************************************************************
    //
    //! Controls the output level
    //
    //*****************************************************************************
    void
    TimerLevelControl(uint32_t ui32Base, uint32_t ui32Timer, bool bInvert)
    {
        //
        // Check the arguments.
        //
        ASSERT(TimerBaseValid(ui32Base));
        ASSERT((ui32Timer == TIMER_A) || (ui32Timer == TIMER_B) ||
               (ui32Timer == TIMER_BOTH));
    
        //
        // Set the output levels as requested.
        //
        ui32Timer &= GPT_CTL_TAPWML | GPT_CTL_TBPWML;
        HWREG(ui32Base + GPT_O_CTL) = (bInvert ?
                                       (HWREG(ui32Base + GPT_O_CTL) | ui32Timer) :
                                       (HWREG(ui32Base + GPT_O_CTL) &
                                       ~(ui32Timer)));
    }
    
    //*****************************************************************************
    //
    //! Controls the stall handling
    //
    //*****************************************************************************
    void
    TimerStallControl(uint32_t ui32Base, uint32_t ui32Timer, bool bStall)
    {
        //
        // Check the arguments.
        //
        ASSERT(TimerBaseValid(ui32Base));
        ASSERT((ui32Timer == TIMER_A) || (ui32Timer == TIMER_B) ||
               (ui32Timer == TIMER_BOTH));
    
        //
        // Set the stall mode.
        //
        ui32Timer &= GPT_CTL_TASTALL | GPT_CTL_TBSTALL;
        HWREG(ui32Base + GPT_O_CTL) = (bStall ?
                                       (HWREG(ui32Base + GPT_O_CTL) | ui32Timer) :
                                       (HWREG(ui32Base + GPT_O_CTL) & ~(ui32Timer)));
    }
    
    //*****************************************************************************
    //
    //! Controls the wait on trigger handling
    //
    //*****************************************************************************
    void
    TimerWaitOnTriggerControl(uint32_t ui32Base, uint32_t ui32Timer, bool bWait)
    {
        //
        // Check the arguments.
        //
        ASSERT(TimerBaseValid(ui32Base));
        ASSERT((ui32Timer == TIMER_A) || (ui32Timer == TIMER_B) ||
               (ui32Timer == TIMER_BOTH));
    
        //
        // Set the wait on trigger mode for timer A.
        //
        if(ui32Timer & TIMER_A)
        {
            if(bWait)
            {
                HWREG(ui32Base + GPT_O_TAMR) |= GPT_TAMR_TAWOT;
            }
            else
            {
                HWREG(ui32Base + GPT_O_TAMR) &= ~(GPT_TAMR_TAWOT);
            }
        }
    
        //
        // Set the wait on trigger mode for timer B.
        //
        if(ui32Timer & TIMER_B)
        {
            if(bWait)
            {
                HWREG(ui32Base + GPT_O_TBMR) |= GPT_TBMR_TBWOT;
            }
            else
            {
                HWREG(ui32Base + GPT_O_TBMR) &= ~(GPT_TBMR_TBWOT);
            }
        }
    }
    
    //*****************************************************************************
    //
    //! Registers an interrupt handler for the timer interrupt
    //
    //*****************************************************************************
    void
    TimerIntRegister(uint32_t ui32Base, uint32_t ui32Timer, void (*pfnHandler)(void))
    {
        uint32_t ui32Int;
    
        //
        // Check the arguments.
        //
        ASSERT(TimerBaseValid(ui32Base));
        ASSERT((ui32Timer == TIMER_A) || (ui32Timer == TIMER_B) ||
               (ui32Timer == TIMER_BOTH));
    
        //
        // Get the interrupt number for this timer module.
        //
        ui32Int = TimerIntNumberGet(ui32Base);
    
        //
        // Register an interrupt handler for timer A if requested.
        //
        if(ui32Timer & TIMER_A)
        {
            //
            // Register the interrupt handler.
            //
            IntRegister(ui32Int, pfnHandler);
    
            //
            // Enable the interrupt.
            //
            IntEnable(ui32Int);
        }
    
        //
        // Register an interrupt handler for timer B if requested.
        //
        if(ui32Timer & TIMER_B)
        {
            //
            // Register the interrupt handler.
            //
            IntRegister(ui32Int + 1, pfnHandler);
    
            //
            // Enable the interrupt.
            //
            IntEnable(ui32Int + 1);
        }
    }
    
    //*****************************************************************************
    //
    //! Unregisters an interrupt handler for the timer interrupt
    //
    //*****************************************************************************
    void
    TimerIntUnregister(uint32_t ui32Base, uint32_t ui32Timer)
    {
        uint32_t ui32Int;
    
        //
        // Check the arguments.
        //
        ASSERT(TimerBaseValid(ui32Base));
        ASSERT((ui32Timer == TIMER_A) || (ui32Timer == TIMER_B) ||
               (ui32Timer == TIMER_BOTH));
    
        //
        // Get the interrupt number for this timer module.
        //
        ui32Int = TimerIntNumberGet(ui32Base);
    
        //
        // Unregister the interrupt handler for timer A if requested.
        //
        if(ui32Timer & TIMER_A)
        {
            //
            // Disable the interrupt.
            //
            IntDisable(ui32Int);
    
            //
            // Unregister the interrupt handler.
            //
            IntUnregister(ui32Int);
        }
    
        //
        // Unregister the interrupt handler for timer B if requested.
        //
        if(ui32Timer & TIMER_B)
        {
            //
            // Disable the interrupt.
            //
            IntDisable(ui32Int + 1);
    
            //
            // Unregister the interrupt handler.
            //
            IntUnregister(ui32Int + 1);
        }
    }
    
    //*****************************************************************************
    //
    // Sets the Match Register Update mode
    //
    //*****************************************************************************
    void
    TimerMatchUpdateMode(uint32_t ui32Base, uint32_t ui32Timer, uint32_t ui32Mode)
    {
        // Check the arguments
        ASSERT(TimerBaseValid(ui32Base));
        ASSERT((ui32Timer == TIMER_A) || (ui32Timer == TIMER_B) || (ui32Timer == TIMER_BOTH));
        ASSERT((ui32Mode == TIMER_MATCHUPDATE_NEXTCYCLE) || (ui32Mode == TIMER_MATCHUPDATE_TIMEOUT));
    
        // Set mode for timer A
        if(ui32Timer & TIMER_A)
        {
            if(ui32Mode == TIMER_MATCHUPDATE_NEXTCYCLE)
            {
                HWREG(ui32Base + GPT_O_TAMR) &= ~(GPT_TAMR_TAMRSU);
            }
            else
            {
                HWREG(ui32Base + GPT_O_TAMR) |= GPT_TAMR_TAMRSU;
            }
        }
    
        // Set mode for timer B
        if(ui32Timer & TIMER_B)
        {
            if(ui32Mode == TIMER_MATCHUPDATE_NEXTCYCLE)
            {
                HWREG(ui32Base + GPT_O_TBMR) &= ~(GPT_TBMR_TBMRSU);
            }
            else
            {
                HWREG(ui32Base + GPT_O_TBMR) |= GPT_TBMR_TBMRSU;
            }
        }
    }
    
    //*****************************************************************************
    //
    // Sets the Interval Load mode
    //
    //*****************************************************************************
    void
    TimerIntervalLoadMode(uint32_t ui32Base, uint32_t ui32Timer, uint32_t ui32Mode)
    {
        // Check the arguments
        ASSERT(TimerBaseValid(ui32Base));
        ASSERT((ui32Timer == TIMER_A) || (ui32Timer == TIMER_B) || (ui32Timer == TIMER_BOTH));
        ASSERT((ui32Mode == TIMER_INTERVALLOAD_NEXTCYCLE) || (ui32Mode == TIMER_INTERVALLOAD_TIMEOUT));
    
        // Set mode for timer A
        if(ui32Timer & TIMER_A)
        {
            if(ui32Mode == TIMER_INTERVALLOAD_NEXTCYCLE)
            {
                HWREG(ui32Base + GPT_O_TAMR) &= ~(GPT_TAMR_TAILD);
            }
            else
            {
                HWREG(ui32Base + GPT_O_TAMR) |= GPT_TAMR_TAILD;
            }
        }
    
        // Set mode for timer B
        if(ui32Timer & TIMER_B)
        {
            if(ui32Mode == TIMER_INTERVALLOAD_NEXTCYCLE)
            {
                HWREG(ui32Base + GPT_O_TBMR) &= ~(GPT_TBMR_TBILD);
            }
            else
            {
                HWREG(ui32Base + GPT_O_TBMR) |= GPT_TBMR_TBILD;
            }
        }
    }