打印
[DemoCode下载]

定时器补获测脉宽

[复制链接]
544|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wanduzi|  楼主 | 2020-3-29 12:30 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
EC_M0518_TIMER_Capture_Both_Edge_V1.00.zip (1.62 MB)
捕获上升沿和下降沿,就可以计算出高电平持续时间。。

使用特权

评论回复
沙发
wanduzi|  楼主 | 2020-3-29 12:31 | 只看该作者
/**************************************************************************//**
* [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. ***/

使用特权

评论回复
板凳
heisexingqisi| | 2020-3-29 13:21 | 只看该作者
非常棒的操作。

使用特权

评论回复
地板
huangcunxiake| | 2020-3-29 15:29 | 只看该作者
非常棒的例子。

使用特权

评论回复
5
fcccc| | 2020-4-5 19:29 | 只看该作者
如果占空比=0或=1将会发生什么如果=0.9999呢?

使用特权

评论回复
6
磨砂| | 2020-4-6 15:48 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
7
晓伍| | 2020-4-6 15:48 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
8
八层楼| | 2020-4-6 15:48 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
9
haunghua| | 2020-4-10 21:54 | 只看该作者
这个读取到的计数值,跟电平的时间是和定时器的计数频率有关系吧,比如高低电平是100us,捕获到的计数值不可能是100吧,应该有个关系式的吧

使用特权

评论回复
10
heisexingqisi| | 2020-4-12 12:56 | 只看该作者
可以试试看。

使用特权

评论回复
11
wanduzi|  楼主 | 2020-4-14 23:42 | 只看该作者
跟PWM捕获区别是啥

使用特权

评论回复
12
wanduzi|  楼主 | 2020-4-14 23:43 | 只看该作者
这个比PWM好理解。

使用特权

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

本版积分规则

144

主题

1732

帖子

3

粉丝