[DemoCode下载] 频率修改与时钟输出的方法

[复制链接]
957|3
 楼主| xixi2017 发表于 2024-2-25 19:14 | 显示全部楼层 |阅读模式
  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: 5 $
  5. * $Date: 15/02/06 10:22a $
  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 "M058S.h"

  15. #define PLL_CLOCK       50000000

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

  18. extern char GetChar(void);

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

  26.     printf("Brown Out is Detected\n");
  27. }

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

  55. int32_t piResult[19];

  56. int32_t pi(void)
  57. {
  58.     int32_t i, i32Err;
  59.     int32_t a = 10000, b = 0, c = PI_NUM, d = 0, e = 0, g = 0;

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

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

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

  75.     return i32Err;
  76. }

  77. void Delay(uint32_t x)
  78. {
  79.     int32_t i;

  80.     for(i = 0; i < x; i++)
  81.     {
  82.         __NOP();
  83.         __NOP();
  84.     }
  85. }

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

  96. void SYS_PLL_Test(void)
  97. {
  98.     int32_t  i;

  99.     /*---------------------------------------------------------------------------------------------------------*/
  100.     /* PLL clock configuration test                                                                             */
  101.     /*---------------------------------------------------------------------------------------------------------*/

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

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

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

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

  111.         /* Waiting for PLL clock ready */
  112.         CLK_WaitClockReady(CLK_CLKSTATUS_PLL_STB_Msk);

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

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

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

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

  120.         if(pi())
  121.         {
  122.             printf("[FAIL]\n");
  123.         }
  124.         else
  125.         {
  126.             printf("[OK]\n");
  127.         }

  128.         /* Disable CKO clock */
  129.         CLK_DisableCKO();
  130.     }
  131. }

  132. void SYS_Init(void)
  133. {

  134.     /*---------------------------------------------------------------------------------------------------------*/
  135.     /* Init System Clock                                                                                       */
  136.     /*---------------------------------------------------------------------------------------------------------*/

  137.     /* Enable Internal RC 22.1184MHz clock */
  138.     CLK_EnableXtalRC(CLK_PWRCON_OSC22M_EN_Msk);

  139.     /* Waiting for Internal RC clock ready */
  140.     CLK_WaitClockReady(CLK_CLKSTATUS_OSC22M_STB_Msk);

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

  143.     /* Enable external XTAL 12MHz clock */
  144.     CLK_EnableXtalRC(CLK_PWRCON_XTL12M_EN_Msk);

  145.     /* Waiting for external XTAL clock ready */
  146.     CLK_WaitClockReady(CLK_CLKSTATUS_XTL12M_STB_Msk);

  147.     /* Set core clock as PLL_CLOCK from PLL */
  148.     CLK_SetCoreClock(PLL_CLOCK);

  149.     /* Enable UART module clock */
  150.     CLK_EnableModuleClock(UART0_MODULE);

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

  153.     /*---------------------------------------------------------------------------------------------------------*/
  154.     /* Init I/O Multi-function                                                                                 */
  155.     /*---------------------------------------------------------------------------------------------------------*/

  156.     /* Set P3 multi-function pins for UART0 RXD , TXD and CKO */
  157.     SYS->P3_MFP &= ~(SYS_MFP_P30_Msk | SYS_MFP_P31_Msk  | SYS_MFP_P36_Msk);
  158.     SYS->P3_MFP |= (SYS_MFP_P30_RXD | SYS_MFP_P31_TXD | SYS_MFP_P36_CKO);

  159. }

  160. void UART0_Init(void)
  161. {
  162.     /*---------------------------------------------------------------------------------------------------------*/
  163.     /* Init UART                                                                                               */
  164.     /*---------------------------------------------------------------------------------------------------------*/
  165.     /* Reset UART0 */
  166.     SYS_ResetModule(UART0_RST);

  167.     /* Configure UART0 and set UART0 Baudrate */
  168.     UART_Open(UART0, 115200);
  169. }

  170. /*---------------------------------------------------------------------------------------------------------*/
  171. /*  Main Function                                                                                          */
  172. /*---------------------------------------------------------------------------------------------------------*/
  173. int32_t main(void)
  174. {
  175.     uint32_t u32data;

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

  179.     /* Unlock protected registers */
  180.     SYS_UnlockReg();

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

  183.     /* Lock protected registers */
  184.     SYS_LockReg();

  185.     /* Init UART0 for printf */
  186.     UART0_Init();

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

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

  196.     printf("+---------------------------------------+\n");
  197.     printf("|    M05xx System Driver Sample Code    |\n");
  198.     printf("+---------------------------------------+\n");

  199.     if(M32(FLAG_ADDR) == SIGNATURE)
  200.     {
  201.         printf("  CPU Reset success!\n");
  202.         M32(FLAG_ADDR) = 0;
  203.         printf("  Press any key to continue ...\n");
  204.         GetChar();
  205.     }

  206.     /*---------------------------------------------------------------------------------------------------------*/
  207.     /* Misc system function test                                                                               */
  208.     /*---------------------------------------------------------------------------------------------------------*/

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

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

  214.     /* Clear reset source */
  215.     SYS_ClearResetSrc(u32data);

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

  218.     /* Check if the write-protected registers are unlocked before BOD setting and CPU Reset */
  219.     if(SYS_IsRegLocked() == 0)
  220.     {
  221.         printf("Protected Address is Unlocked\n");
  222.     }

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

  225.     /* Enable BOD IRQ */
  226.     NVIC_EnableIRQ(BOD_IRQn);

  227.     /* Enable Low Voltage Reset function */
  228.     SYS_ENABLE_LVR();

  229.     /* Run PLL Test */
  230.     SYS_PLL_Test();

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

  234.     /* Waiting for message send out */
  235.     UART_WAIT_TX_EMPTY(UART0);

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

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

  240.     /* Reset CPU */
  241.     SYS_ResetCPU();
  242. }


 楼主| xixi2017 发表于 2024-2-25 19:15 | 显示全部楼层
这段单片机程序是针对M058S型号的芯片编写的,主要功能是改变系统时钟到不同的PLL频率,并且从CLKO引脚输出系统时钟。

以下是程序的主要功能和流程:

引入头文件,并定义了一些常量和变量,包括PLL_CLOCK(PLL的目标频率)、SIGNATURE(用于标识复位状态的签名值)、FLAG_ADDR(标志位的地址)、PI_NUM等。

定义了BOD_IRQHandler函数(用于处理Brown Out检测中断)和Delay函数(用于延时)。

定义了pi函数,用于进行简单的计算测试。这个函数的主要目的是通过一系列计算来估算圆周率π的值,并与预先计算好的π值进行比较,以验证计算的准确性。

定义了g_au32PllSetting数组,存储了一系列不同的PLL设置。

定义了SYS_PLL_Test函数,用于测试不同的PLL设置,并输出系统时钟频率到CLKO引脚。

定义了SYS_Init函数,用于初始化系统时钟和外设时钟。

定义了UART0_Init函数,用于初始化UART0模块。

主函数main中进行了如下操作:

解锁保护寄存器。
初始化系统。
锁定保护寄存器。
初始化UART0,并打印系统时钟频率。
执行一系列的系统功能测试,包括读取设备ID、获取和清除复位源、设置BOD、运行PLL测试等。
最后,将一个签名写入SRAM,然后重置CPU。
整个程序的主要功能是测试不同的PLL设置,并输出系统时钟频率到CLKO引脚,同时进行一些系统功能测试。
 楼主| xixi2017 发表于 2024-2-25 19:15 | 显示全部楼层
你用过这个功能吗?
wanduzi 发表于 2024-2-28 18:45 | 显示全部楼层
制作一个频率参数表,调用修改。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

145

主题

2034

帖子

2

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