打印
[DemoCode下载]

Nano100的定时器写延时函数

[复制链接]
1488|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zhuomuniao110|  楼主 | 2017-5-4 17:42 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

/******************************************************************************
* [url=home.php?mod=space&uid=288409]@file[/url]     main.c
* [url=home.php?mod=space&uid=895143]@version[/url]  V1.00
* $Revision: 3 $
* $Date: 14/09/11 7:17p $
* [url=home.php?mod=space&uid=247401]@brief[/url]    Demonstrate the usage of TIMER_Delay() API to generate a 1 second delay
*
* @note
* Copyright (C) 2013 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include <stdio.h>
#include "Nano100Series.h"

void SYS_Init(void)
{
    /*---------------------------------------------------------------------------------------------------------*/
    /* Init System Clock                                                                                       */
    /*---------------------------------------------------------------------------------------------------------*/
    /* Unlock protected registers */
    SYS_UnlockReg();

    /* Enable External XTAL (4~24 MHz) */
    CLK_EnableXtalRC(CLK_PWRCTL_HXT_EN_Msk);

    /* Waiting for 12MHz clock ready */
    CLK_WaitClockReady( CLK_CLKSTATUS_HXT_STB_Msk);

    /* Switch HCLK clock source to HXT */
    CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_HXT,CLK_HCLK_CLK_DIVIDER(1));

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


    /* Select IP clock source */
    CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART_S_HXT, CLK_UART_CLK_DIVIDER(1));
    CLK_SetModuleClock(TMR0_MODULE, CLK_CLKSEL1_TMR0_S_HXT, 0);

    /* Update System Core Clock */
    /* User can use SystemCoreClockUpdate() to calculate SystemCoreClock. */
    SystemCoreClockUpdate();


    /*---------------------------------------------------------------------------------------------------------*/
    /* Init I/O Multi-function                                                                                 */
    /*---------------------------------------------------------------------------------------------------------*/
    /* Set GPB multi-function pins for UART0 RXD and TXD */
    SYS->PB_L_MFP &= ~(SYS_PB_L_MFP_PB0_MFP_Msk | SYS_PB_L_MFP_PB1_MFP_Msk);
    SYS->PB_L_MFP |= (SYS_PB_L_MFP_PB1_MFP_UART0_TX | SYS_PB_L_MFP_PB0_MFP_UART0_RX);


    /* Lock protected registers */
    SYS_LockReg();
}

int main(void)
{
    /* Init System, IP clock and multi-function I/O
       In the end of SYS_Init() will issue SYS_LockReg()
       to lock protected register. If user want to write
       protected register, please issue SYS_UnlockReg()
       to unlock protected register if necessary */
    SYS_Init();

    /* Init UART to 115200-8n1 for print message */
    UART_Open(UART0, 115200);

    printf("\nThis sample code use timer to create a small delay \n");
    while(1) {
        printf("Delay 1 second\n");
        TIMER_Delay(TIMER0, 1000000);
    }

}

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



沙发
zhuomuniao110|  楼主 | 2017-5-4 17:44 | 只看该作者
void TIMER_Delay(TIMER_T *timer, uint32_t u32Usec);
这个是定时器延时函数的原型

使用特权

评论回复
板凳
zhuomuniao110|  楼主 | 2017-5-4 17:45 | 只看该作者

/**
  * @brief This API is used to create a delay loop for u32usec micro seconds
  * @param[in] timer The base address of Timer module
  * @param[in] u32Usec Delay period in micro seconds with 10 usec every step. Valid values are between 10~1000000 (10 micro second ~ 1 second)
  * [url=home.php?mod=space&uid=266161]@return[/url] None
  * @note This API overwrites the register setting of the timer used to count the delay time.
  * @note This API use polling mode. So there is no need to enable interrupt for the timer module used to generate delay
  */
void TIMER_Delay(TIMER_T *timer, uint32_t u32Usec)
{
    uint32_t u32Clk = TIMER_GetModuleClock(timer);
    uint32_t u32Prescale = 0, delay = SystemCoreClock / u32Clk;
    long long u64Cmpr;

    // Clear current timer configuration
    timer->CTL = 0;

    if(u32Clk == 10000) {         // min delay is 100us if timer clock source is LIRC 10k
        u32Usec = ((u32Usec + 99) / 100) * 100;
    } else {    // 10 usec every step
        u32Usec = ((u32Usec + 9) / 10) * 10;
    }

    if(u32Clk >= 0x2000000) {
        u32Prescale = 3;    // real prescaler value is 4
        u32Clk >>= 2;
    } else if(u32Clk >= 0x1000000) {
        u32Prescale = 1;    // real prescaler value is 2
        u32Clk >>= 1;
    }

    // u32Usec * u32Clk might overflow if using uint32_t
    u64Cmpr = ((long long)u32Usec * (long long)u32Clk) / (long long)1000000;

    timer->CMPR = (uint32_t)u64Cmpr;
    timer->PRECNT = u32Prescale;
    timer->CTL = TIMER_CTL_TMR_EN_Msk; // one shot mode

    // When system clock is faster than timer clock, it is possible timer active bit cannot set in time while we check it.
    // And the while loop below return immediately, so put a tiny delay here allowing timer start counting and raise active flag.
    for(; delay > 0; delay--) {
        __NOP();
    }

    while(timer->CTL & TIMER_CTL_TMR_ACT_Msk);

}
这个是定时器延时函数的实现
实现的过程是复杂的,我们是不是该考虑这个实现过程消耗掉的时间呢?

使用特权

评论回复
地板
wahahaheihei| | 2017-5-4 23:14 | 只看该作者
通过查询定时器做到延时的效果

使用特权

评论回复
5
huangcunxiake| | 2017-5-5 14:40 | 只看该作者
关于那个实现过程,感觉好复杂,没看懂。

使用特权

评论回复
6
捉虫天师| | 2017-5-5 16:21 | 只看该作者
看了一下,基本上那个系统初始化代码都是可以拿来主义的。

使用特权

评论回复
7
yiyigirl2014| | 2017-5-6 20:52 | 只看该作者
如果跑系统,那么系统是如何管理这些中断和定时器的?

使用特权

评论回复
8
wahahaheihei| | 2017-5-7 16:17 | 只看该作者
u32Usec Delay period in micro seconds with 10 usec every step. Valid values are between 10~1000000 (10 micro second ~ 1 second)
这个是延时的范围,还是很大呢,那个最小的是10,可能就是考虑到了实现部分的其他代码。

使用特权

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

本版积分规则

204

主题

3334

帖子

10

粉丝