[DemoCode下载] Nano100的定时器写延时函数

[复制链接]
1615|7
 楼主| zhuomuniao110 发表于 2017-5-4 17:42 | 显示全部楼层 |阅读模式

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

  13. void SYS_Init(void)
  14. {
  15.     /*---------------------------------------------------------------------------------------------------------*/
  16.     /* Init System Clock                                                                                       */
  17.     /*---------------------------------------------------------------------------------------------------------*/
  18.     /* Unlock protected registers */
  19.     SYS_UnlockReg();

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

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

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

  26.     /* Enable IP clock */
  27.     CLK_EnableModuleClock(UART0_MODULE);
  28.     CLK_EnableModuleClock(TMR0_MODULE);


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

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


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


  41.     /* Lock protected registers */
  42.     SYS_LockReg();
  43. }

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

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

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

  59. }

  60. /*** (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 | 显示全部楼层

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

  14.     // Clear current timer configuration
  15.     timer->CTL = 0;

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

  21.     if(u32Clk >= 0x2000000) {
  22.         u32Prescale = 3;    // real prescaler value is 4
  23.         u32Clk >>= 2;
  24.     } else if(u32Clk >= 0x1000000) {
  25.         u32Prescale = 1;    // real prescaler value is 2
  26.         u32Clk >>= 1;
  27.     }

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

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

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

  38.     while(timer->CTL & TIMER_CTL_TMR_ACT_Msk);

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

wahahaheihei 发表于 2017-5-4 23:14 | 显示全部楼层
通过查询定时器做到延时的效果
huangcunxiake 发表于 2017-5-5 14:40 | 显示全部楼层
关于那个实现过程,感觉好复杂,没看懂。
捉虫天师 发表于 2017-5-5 16:21 | 显示全部楼层
看了一下,基本上那个系统初始化代码都是可以拿来主义的。
yiyigirl2014 发表于 2017-5-6 20:52 | 显示全部楼层
如果跑系统,那么系统是如何管理这些中断和定时器的?
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,可能就是考虑到了实现部分的其他代码。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

233

主题

3529

帖子

11

粉丝
快速回复 在线客服 返回列表 返回顶部