[DemoCode下载] 系统时钟配置输出的方法

[复制链接]
1731|12
 楼主| gejigeji521 发表于 2017-1-11 22:29 | 显示全部楼层 |阅读模式
  1. /****************************************************************************
  2. * [url=home.php?mod=space&uid=288409]@file[/url]     main.c
  3. * [url=home.php?mod=space&uid=895143]@version[/url]  V2.00
  4. * $Revision: 2 $
  5. * $Date: 14/12/15 4:01p $
  6. * @brief
  7. *           Change system clock to different PLL frequency and output system clock from CLKO pin..
  8. *
  9. * @note
  10. * Copyright (C) 2011 Nuvoton Technology Corp. All rights reserved.
  11. *
  12. ******************************************************************************/
  13. #include <stdio.h>
  14. #include "NUC100Series.h"


  15. #define PLL_CLOCK       50000000

  16. #define SIGNATURE       0x125ab234
  17. #define FLAG_ADDR       0x20003FFC


  18. /*---------------------------------------------------------------------------------------------------------*/
  19. /* Define functions prototype                                                                              */
  20. /*---------------------------------------------------------------------------------------------------------*/
  21. int32_t main(void);


  22. /*---------------------------------------------------------------------------------------------------------*/
  23. /*  Brown Out Detector IRQ Handler                                                                         */
  24. /*---------------------------------------------------------------------------------------------------------*/
  25. void BOD_IRQHandler(void)
  26. {
  27.     /* Clear BOD Interrupt Flag */
  28.     SYS_CLEAR_BOD_INT_FLAG();

  29.     printf("Brown Out is Detected\n");
  30. }

  31. /*---------------------------------------------------------------------------------------------------------*/
  32. /*  Simple calculation test function                                                                       */
  33. /*---------------------------------------------------------------------------------------------------------*/
  34. #define PI_NUM  256
  35. int32_t f[PI_NUM + 1];
  36. uint32_t piTbl[19] =
  37. {
  38.     3141,
  39.     5926,
  40.     5358,
  41.     9793,
  42.     2384,
  43.     6264,
  44.     3383,
  45.     2795,
  46.     288,
  47.     4197,
  48.     1693,
  49.     9937,
  50.     5105,
  51.     8209,
  52.     7494,
  53.     4592,
  54.     3078,
  55.     1640,
  56.     6284
  57. };

  58. int32_t piResult[19];

  59. int32_t pi(void)
  60. {
  61.     int32_t i, i32Err;
  62.     int32_t a = 10000, b = 0, c = PI_NUM, d = 0, e = 0, g = 0;

  63.     for(; b - c;)
  64.         f[b++] = a / 5;

  65.     i = 0;
  66.     for(; d = 0, g = c * 2; c -= 14,/*printf("%.4d\n",e+d/a),*/ piResult[i++] = e + d / a, e = d % a)
  67.     {
  68.         if(i == 19)
  69.             break;

  70.         for(b = c; d += f[b] * a, f[b] = d % --g, d /= g--, --b; d *= b);
  71.     }
  72.     i32Err = 0;
  73.     for(i = 0; i < 19; i++)
  74.     {
  75.         if(piTbl[i] != piResult[i])
  76.             i32Err = -1;
  77.     }

  78.     return i32Err;
  79. }

  80. void Delay(uint32_t x)
  81. {
  82.     int32_t i;

  83.     for(i = 0; i < x; i++)
  84.     {
  85.         __NOP();
  86.         __NOP();
  87.     }
  88. }

  89. uint32_t g_au32PllSetting[] =
  90. {
  91.     CLK_PLLCON_PLL_SRC_HXT | CLK_PLLCON_NR(3) | CLK_PLLCON_NF(25) | CLK_PLLCON_NO_4,  /* PLL = 25MHz */
  92.     CLK_PLLCON_PLL_SRC_HXT | CLK_PLLCON_NR(3) | CLK_PLLCON_NF(29) | CLK_PLLCON_NO_4,  /* PLL = 29MHz */
  93.     CLK_PLLCON_PLL_SRC_HXT | CLK_PLLCON_NR(3) | CLK_PLLCON_NF(33) | CLK_PLLCON_NO_4,  /* PLL = 33MHz */
  94.     CLK_PLLCON_PLL_SRC_HXT | CLK_PLLCON_NR(3) | CLK_PLLCON_NF(37) | CLK_PLLCON_NO_4,  /* PLL = 37MHz */
  95.     CLK_PLLCON_PLL_SRC_HXT | CLK_PLLCON_NR(3) | CLK_PLLCON_NF(41) | CLK_PLLCON_NO_4,  /* PLL = 41MHz */
  96.     CLK_PLLCON_PLL_SRC_HXT | CLK_PLLCON_NR(3) | CLK_PLLCON_NF(45) | CLK_PLLCON_NO_4,  /* PLL = 45MHz */
  97.     CLK_PLLCON_PLL_SRC_HXT | CLK_PLLCON_NR(3) | CLK_PLLCON_NF(49) | CLK_PLLCON_NO_4   /* PLL = 49MHz */
  98. };

  99. void SYS_PLL_Test(void)
  100. {
  101.     int32_t  i;

  102.     /*---------------------------------------------------------------------------------------------------------*/
  103.     /* PLL clock configuration test                                                                             */
  104.     /*---------------------------------------------------------------------------------------------------------*/

  105.     printf("\n-------------------------[ Test PLL ]-----------------------------\n");

  106.     for(i = 0; i < sizeof(g_au32PllSetting) / sizeof(g_au32PllSetting[0]) ; i++)
  107.     {
  108.         /* Switch HCLK clock source to HXT and HCLK source divide 1 */
  109.         CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_HXT, CLK_CLKDIV_HCLK(1));

  110.         /* Set PLL to power down mode and PLL_STB bit in CLKSTATUS register will be cleared by hardware. */
  111.         CLK_DisablePLL();

  112.         /* Set PLL frequency */
  113.         CLK->PLLCON = g_au32PllSetting[i];

  114.         /* Waiting for PLL clock ready */
  115.         CLK_WaitClockReady(CLK_CLKSTATUS_PLL_STB_Msk);

  116.         /* Switch HCLK clock source to PLL */
  117.         CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_PLL, CLK_CLKDIV_HCLK(1));

  118.         printf("  Change system clock to %d Hz ...................... ", SystemCoreClock);

  119.         /* Output selected clock to CKO, CKO Clock = HCLK / 2^(1 + 1) */
  120.         CLK_EnableCKO(CLK_CLKSEL2_FRQDIV_S_HCLK, 1, 0);

  121.         /* The delay loop is used to check if the CPU speed is increasing */
  122.         Delay(0x400000);

  123.         if(pi())
  124.         {
  125.             printf("[FAIL]\n");
  126.         }
  127.         else
  128.         {
  129.             printf("[OK]\n");
  130.         }

  131.         /* Disable CKO clock */
  132.         CLK_DisableCKO();
  133.     }
  134. }

  135. void SYS_Init(void)
  136. {
  137.     /*---------------------------------------------------------------------------------------------------------*/
  138.     /* Init System Clock                                                                                       */
  139.     /*---------------------------------------------------------------------------------------------------------*/

  140.     /* Enable Internal RC 22.1184MHz clock */
  141.     CLK_EnableXtalRC(CLK_PWRCON_OSC22M_EN_Msk);

  142.     /* Waiting for Internal RC clock ready */
  143.     CLK_WaitClockReady(CLK_CLKSTATUS_OSC22M_STB_Msk);

  144.     /* Switch HCLK clock source to Internal RC and HCLK source divide 1 */
  145.     CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_HIRC, CLK_CLKDIV_HCLK(1));

  146.     /* Enable external XTAL 12MHz clock */
  147.     CLK_EnableXtalRC(CLK_PWRCON_XTL12M_EN_Msk);

  148.     /* Waiting for external XTAL clock ready */
  149.     CLK_WaitClockReady(CLK_CLKSTATUS_XTL12M_STB_Msk);

  150.     /* Set core clock as PLL_CLOCK from PLL */
  151.     CLK_SetCoreClock(PLL_CLOCK);

  152.     /* Enable UART module clock */
  153.     CLK_EnableModuleClock(UART0_MODULE);

  154.     /* Select UART module clock source */
  155.     CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART_S_HXT, CLK_CLKDIV_UART(1));


  156.     /*---------------------------------------------------------------------------------------------------------*/
  157.     /* Init I/O Multi-function                                                                                 */
  158.     /*---------------------------------------------------------------------------------------------------------*/

  159.     /* Set GPB multi-function pins for UART0 RXD and TXD, and Clock Output */
  160.     SYS->GPB_MFP &= ~(SYS_GPB_MFP_PB0_Msk | SYS_GPB_MFP_PB1_Msk | SYS_GPB_MFP_PB12_Msk);
  161.     SYS->ALT_MFP &= ~SYS_ALT_MFP_PB12_Msk;
  162.     SYS->GPB_MFP |= (SYS_GPB_MFP_PB0_UART0_RXD | SYS_GPB_MFP_PB1_UART0_TXD | SYS_GPB_MFP_PB12_CLKO);
  163.     SYS->ALT_MFP |=  SYS_ALT_MFP_PB12_CLKO;

  164. }

  165. void UART0_Init()
  166. {
  167.     /*---------------------------------------------------------------------------------------------------------*/
  168.     /* Init UART                                                                                               */
  169.     /*---------------------------------------------------------------------------------------------------------*/
  170.     /* Reset UART0 peripheral */
  171.     SYS_ResetModule(UART0_RST);

  172.     /* Configure UART0 and set UART0 Baudrate */
  173.     UART_Open(UART0, 115200);
  174. }

  175. /*---------------------------------------------------------------------------------------------------------*/
  176. /* MAIN function                                                                                           */
  177. /*---------------------------------------------------------------------------------------------------------*/
  178. int32_t main(void)
  179. {
  180.     uint32_t u32data;

  181.     /* In end of main function, program issued CPU reset and write-protection will be disabled. */
  182.     if(SYS_IsRegLocked() == 0)
  183.         SYS_LockReg();

  184.     /* Unlock protected registers */
  185.     SYS_UnlockReg();

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

  188.     /* Lock protected registers */
  189.     SYS_LockReg();

  190.     /* Init UART0 for printf */
  191.     UART0_Init();

  192.     printf("\n\nCPU [url=home.php?mod=space&uid=72445]@[/url] %dHz\n", SystemCoreClock);

  193.     /*
  194.         This sample code will show some function about system manager controller and clock controller:
  195.         1. Read PDID
  196.         2. Get and clear reset source
  197.         3. Setting about BOD
  198.         4. Change system clock depended on different PLL settings
  199.         5. Output system clock from CKO pin, and the output frequency = system clock / 4
  200.     */

  201.     printf("+----------------------------------------+\n");
  202.     printf("|    NUC100 System Driver Sample Code    |\n");
  203.     printf("+----------------------------------------+\n");

  204.     if(M32(FLAG_ADDR) == SIGNATURE)
  205.     {
  206.         printf("  CPU Reset success!\n");
  207.         M32(FLAG_ADDR) = 0;
  208.         printf("  Press any key to continue ...\n");
  209.         getchar();
  210.     }

  211.     /*---------------------------------------------------------------------------------------------------------*/
  212.     /* Misc system function test                                                                               */
  213.     /*---------------------------------------------------------------------------------------------------------*/

  214.     /* Read Part Device ID */
  215.     printf("Product ID 0x%x\n", SYS_ReadPDID());

  216.     /* Get reset source from last operation */
  217.     u32data = SYS_GetResetSrc();
  218.     printf("Reset Source 0x%x\n", u32data);

  219.     /* Clear reset source */
  220.     SYS_ClearResetSrc(u32data);

  221.     /* Unlock protected registers for Brown-Out Detector settings */
  222.     SYS_UnlockReg();

  223.     /* Check if the write-protected registers are unlocked before BOD setting and CPU Reset */
  224.     if(SYS_IsRegLocked() == 0)
  225.     {
  226.         printf("Protected Address is Unlocked\n");
  227.     }

  228.     /* Enable Brown-Out Detector, and set Brown-Out Detector voltage 2.7V */
  229.     SYS_EnableBOD(SYS_BODCR_BOD_INTERRUPT_EN, SYS_BODCR_BOD_VL_2_7V);

  230.     /* Enable BOD IRQ */
  231.     NVIC_EnableIRQ(BOD_IRQn);

  232.     /* Enable Low Voltage Reset function */
  233.     SYS_ENABLE_LVR();

  234.     /* Run PLL Test */
  235.     SYS_PLL_Test();

  236.     /* Write a signature work to SRAM to check if it is reset by software */
  237.     M32(FLAG_ADDR) = SIGNATURE;
  238.     printf("\n\n  >>> Reset CPU <<<\n");

  239.     /* Waiting for message send out */
  240.     UART_WAIT_TX_EMPTY(UART0);

  241.     /* Switch HCLK clock source to Internal RC 22.1184MHz clock and HCLK source divide 1 */
  242.     CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_HIRC, CLK_CLKDIV_HCLK(1));

  243.     /* Set PLL to Power down mode and HW will also clear PLL_STB bit in CLKSTATUS register */
  244.     CLK_DisablePLL();

  245.     /* Reset CPU */
  246.     SYS_ResetCPU();
  247. }

643757107 发表于 2017-1-11 23:53 | 显示全部楼层
SYS->ALT_MFP |=  SYS_ALT_MFP_PB12_CLKO;
天灵灵地灵灵 发表于 2017-1-14 19:22 | 显示全部楼层
想学好这些,还是要做好笔记。
捉虫天师 发表于 2017-1-16 16:14 | 显示全部楼层
应该这个封装成一个函数,然后通过条件编译来实现切换和设定。
玛尼玛尼哄 发表于 2017-1-16 22:02 | 显示全部楼层
还好这个冷僻的应用官方都给了例程了。
mintspring 发表于 2017-1-17 09:07 | 显示全部楼层
重启CPU。。
yiyigirl2014 发表于 2017-1-17 21:30 | 显示全部楼层
这个知识点要认真看相关的技术手册。
huangcunxiake 发表于 2017-1-17 22:34 | 显示全部楼层
M32(FLAG_ADDR) = 0;
这个恢复0的方法好,直接通过地址操作。
zhuotuzi 发表于 2017-1-19 11:10 | 显示全部楼层
    /* Clear reset source */
    SYS_ClearResetSrc(u32data);
这个是?
 楼主| gejigeji521 发表于 2017-1-26 20:11 | 显示全部楼层
想看明白要对照技术手册看。
wahahaheihei 发表于 2017-1-27 13:48 | 显示全部楼层
通过宏来定义全局的晶振时钟,那么在定时器函数里可以判断到这个变化吗
wahahaheihei 发表于 2017-1-27 14:10 | 显示全部楼层
   if(M32(FLAG_ADDR) == SIGNATURE)
    {
        printf("  CPU Reset success!\n");
        M32(FLAG_ADDR) = 0;
        printf("  Press any key to continue ...\n");
        getchar();
    }
这个估计就是半主机的概念吧。
yiyigirl2014 发表于 2017-1-27 14:49 | 显示全部楼层
玩PLL是不是就是超频啊。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

196

主题

2465

帖子

8

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