打印
[DemoCode下载]

利用定时器捕捉双边沿

[复制链接]
705|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
小明的同学|  楼主 | 2024-4-21 14:57 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
/**************************************************************************//**
* [url=home.php?mod=space&uid=288409]@file[/url]    main.c
* @brief
*          Demonstrate how to use the TIMER0 capture function to capture
*          both edge of external capture signal and calculate the time
*          of high level duration of capture signal.
* @note
* Copyright (C) 2013 Nuvoton Technology Corp. All rights reserved.
******************************************************************************/
#include <stdio.h>
#include "M0518.h"

/****************************************************************************/
/* Define                                                                   */
/****************************************************************************/

#define HCLK_CLOCK           50000000

/****************************************************************************/
/* Global variables                                                         */
/****************************************************************************/

volatile uint32_t g_au32TMRCapCountRise, g_au32TMRCapCountFall, g_u32TimerCapFlag;

/****************************************************************************/
/* Functions                                                                */
/****************************************************************************/

/*------------------------------*/
/* TIMER0 interrupt handler     */
/*------------------------------*/
void TMR0_IRQHandler(void)
{
    if (TIMER_GetCaptureIntFlag(TIMER0) == 1)
    {
        /* Clear TIMER0 capture interrupt flag */
        TIMER_ClearCaptureIntFlag(TIMER0);

        if (PB15)
        {
            /* Save the capture counter for PB15 rising edge */
            g_au32TMRCapCountRise = TIMER_GetCaptureData(TIMER0);
        }
        else
        {
            /* Save the capture counter for PB15 falling edge */
            g_au32TMRCapCountFall = TIMER_GetCaptureData(TIMER0);
            g_u32TimerCapFlag = 1;
        }
    }
}

void SYS_Init(void)
{
    /*------------------------------*/
    /* Init System Clock            */
    /*------------------------------*/

    /* Enable HIRC clock */
    CLK_EnableXtalRC(CLK_PWRCON_IRC22M_EN_Msk);

    /* Waiting for HIRC clock ready */
    CLK_WaitClockReady(CLK_CLKSTATUS_IRC22M_STB_Msk);

    /* Switch HCLK clock source to HIRC */
    CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_HIRC, CLK_CLKDIV_HCLK(1));

    /* Enable HXT */
    CLK_EnableXtalRC(CLK_PWRCON_XTL12M_EN_Msk);

    /* Waiting for clock ready */
    CLK_WaitClockReady(CLK_CLKSTATUS_XTL12M_STB_Msk);

    /* Set core clock as HCLK_CLOCK from PLL and SysTick source to HCLK/2*/
    CLK_SetCoreClock(HCLK_CLOCK);

    /* Enable peripheral clock */
    CLK_EnableModuleClock(UART0_MODULE);
    CLK_EnableModuleClock(TMR0_MODULE);

    /* Peripheral clock source */
    CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART_S_PLL, CLK_CLKDIV_UART(1));
    CLK_SetModuleClock(TMR0_MODULE, CLK_CLKSEL1_TMR0_S_HCLK, 0);

    /*------------------------------*/
    /* Init I/O Multi-function      */
    /*------------------------------*/
    /* Set PB multi-function pins for UART0 RXD, TXD */
    SYS->GPB_MFP = SYS_GPB_MFP_PB0_UART0_RXD | SYS_GPB_MFP_PB1_UART0_TXD;

    /* Set PB multi-function pins for TM0_EXT on PB.15 */
    SYS->GPB_MFP |= (SYS_GPB_MFP_PB15_TM0_EXT);
    SYS->ALT_MFP  = SYS_ALT_MFP_PB15_TM0_EXT;
}


void UART0_Init(void)
{
    /*------------------------------*/
    /* Init UART                    */
    /*------------------------------*/
    /* Reset UART IP */
    SYS_ResetModule(UART0_RST);

    /* Configure UART0 and set UART0 Baudrate */
    UART_Open(UART0, 115200);
}


/*------------------------------*/
/* Main Function                */
/*------------------------------*/
int main(void)
{
    uint32_t u32CAPValue = 0;
    uint32_t u32delayCounter;

    /* Unlock protected registers */
    SYS_UnlockReg();

    /* Init System, peripheral clock and multi-function I/O */
    SYS_Init();

    /* Lock protected registers */
    SYS_LockReg();

    /* Init UART0 for printf */
    UART0_Init();

    printf("CPU [url=home.php?mod=space&uid=72445]@[/url] %d Hz\n", SystemCoreClock);
    printf("+------------------------------------------+\n");
    printf("|    TIMER0 Capture Counter Sample Code    |\n");
    printf("+------------------------------------------+\n\n");
    printf(" * Please connect PB14 and PB15 by wire.\n");

    /* Config PB14 to GPIO output mode to generate a pulse as external capture signal */
    PB14 = 0;
    GPIO_SetMode(PB, BIT14, GPIO_PMD_OUTPUT);

    /*----- Initial TIMER0 -----*/

    SYS_ResetModule(TMR0_RST);
    TIMER_Open(TIMER0, TIMER_CONTINUOUS_MODE, 1);

    /* Configure TIMER0 setting for external counter input and capture function */
    /* Set TIMER0 clock to HCLK/(1+1) */
    TIMER_SET_PRESCALE_VALUE(TIMER0, 1);
    printf("TIMER0 clock @ %d Hz\n", SystemCoreClock / 2);
    /* Reset TIMER0 counter value */
    TIMER_SET_CMP_VALUE(TIMER0, 0xFFFFFF);
    /* Set TIMER0 to capture both edges */
    TIMER_EnableCapture(TIMER0, TIMER_CAPTURE_FREE_COUNTING_MODE, TIMER_CAPTURE_FALLING_AND_RISING_EDGE);
    /* Enable TIMER0 capture interrupt */
    TIMER_EnableCaptureInt(TIMER0);
    NVIC_EnableIRQ(TMR0_IRQn);

    /*---- Begin to test -----*/

    g_au32TMRCapCountRise = g_au32TMRCapCountFall = g_u32TimerCapFlag = 0;

    /* Start TIMER0 counting */
    TIMER_Start(TIMER0);

    /* Generate a pulse with both rising edge and falling edge to PB14 */
    PB14 = 1;   /* Rising edge */

    /* Delay to keep high level of pulse. */
    /* Change the delay counter will get different capture counter value */
    for (u32delayCounter = 0; u32delayCounter < 10000; u32delayCounter++);

    PB14 = 0;   /* Falling edge */

    /* Wait a rising edge and a falling edge from PB15 */
    /* TIMER0 interrupt handler will set g_u32TimerCapFlag to 1 when received */
    /*      external capture signal from PB15 */
    while (g_u32TimerCapFlag == 0);

    /* Got the counter value for external capture signal */
    if (g_au32TMRCapCountFall > g_au32TMRCapCountRise)
        u32CAPValue = g_au32TMRCapCountFall - g_au32TMRCapCountRise;
    else
        /* In the case that TIMER0 counter overflowed */
        u32CAPValue = 0xffffff - g_au32TMRCapCountRise + g_au32TMRCapCountFall;

    printf("Capture counter for rising edge: 0x%X (%d)\n", g_au32TMRCapCountRise, g_au32TMRCapCountRise);
    printf("Capture counter for falling edge: 0x%X (%d)\n", g_au32TMRCapCountFall, g_au32TMRCapCountFall);
    printf("\n");
    printf("Capture counter for high level duration: 0x%X (%d)\n", u32CAPValue, u32CAPValue);
    printf("The high level duration time should be about (TIMER0 clock) * %d\n", u32CAPValue);
    printf("                                             = %d us\n", u32CAPValue / (SystemCoreClock / 2 / 1000000));

    /* Stop TIMER0 counting */
    TIMER_Close(TIMER0);

    while (1);
}

/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/


使用特权

评论回复
沙发
21mengnan| | 2024-4-21 17:48 | 只看该作者
定时器功能比较强大,捕捉功能,可以高精度捕捉脉宽。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

139

主题

1486

帖子

2

粉丝