打印
[牛人杂谈]

CLK_SetCoreClock函数的妙用

[复制链接]
85|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
yiyigirl2014|  楼主 | 2025-1-8 13:48 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
ETC, ck, core, se, tc
我们先看这个M058S的库函数
/**
  * [url=home.php?mod=space&uid=247401]@brief[/url]      Set HCLK frequency
  * @param[in]  u32Hclk is HCLK frequency
  * [url=home.php?mod=space&uid=266161]@return[/url]     HCLK frequency
  * [url=home.php?mod=space&uid=1543424]@Details[/url]    This function set HCLK frequency. The frequency unit is Hz. The range of u32Hclk is 25 MHz ~ 50 MHz.
  *             The register write-protection function should be disabled before using this function.
  */
uint32_t CLK_SetCoreClock(uint32_t u32Hclk)
{
    uint32_t u32HIRCSTB;

    /* Read HIRC clock source stable flag */
    u32HIRCSTB = CLK->CLKSTATUS & CLK_CLKSTATUS_OSC22M_STB_Msk;

    /* The range of u32Hclk is 25 MHz ~ 50 MHz */
    if(u32Hclk > FREQ_50MHZ)
        u32Hclk = FREQ_50MHZ;
    else if(u32Hclk < FREQ_25MHZ)
        u32Hclk = FREQ_25MHZ;

    /* Switch HCLK clock source to HIRC clock for safe */
    CLK->PWRCON |= CLK_PWRCON_OSC22M_EN_Msk;
    CLK_WaitClockReady(CLK_CLKSTATUS_OSC22M_STB_Msk);
    CLK->CLKSEL0 |= CLK_CLKSEL0_HCLK_S_HIRC;
    CLK->CLKDIV &= (~CLK_CLKDIV_HCLK_N_Msk);

    /* Configure PLL setting if HXT clock is stable */
    if(CLK->CLKSTATUS & CLK_CLKSTATUS_XTL12M_STB_Msk)
        u32Hclk = CLK_EnablePLL(CLK_PLLCON_PLL_SRC_HXT, u32Hclk);

    /* Configure PLL setting if HXT clock is not stable */
    else
    {
        u32Hclk = CLK_EnablePLL(CLK_PLLCON_PLL_SRC_HIRC, u32Hclk);

        /* Read HIRC clock source stable flag */
        u32HIRCSTB = CLK->CLKSTATUS & CLK_CLKSTATUS_OSC22M_STB_Msk;
    }

    /* Select HCLK clock source to PLL */
    CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_PLL, CLK_CLKDIV_HCLK(1));

    /* Disable HIRC if HIRC is disabled before setting core clock */
    if(u32HIRCSTB == 0)
        CLK->PWRCON &= ~CLK_PWRCON_OSC22M_EN_Msk;

    return u32Hclk;
}
函数内先判断参数在什么区间内,并将传递进来的HCLK时钟参数控制在合适的范围
介于25M到50MHz之间。
先设置时钟源为内部RC时钟源,并设置为HCLK时钟。
接下来判断 是否启用了外部时钟,如果启用了,作为PLL的时钟源,并使能PLL
如果没启用外部的时钟源,就将内部RC作为PLL时钟源,使能PLL
最后将PLL作为HCLK时钟源
所以该函数的最终目的都是将PLL作为HCLK时钟源。

使用特权

评论回复
沙发
yiyigirl2014|  楼主 | 2025-1-8 13:55 | 只看该作者
所以对HCLK时钟源要求不高可以直接使用 这一个函数就搞定

#include <stdio.h>
#include "M058S.h"

#define PLLCON_SETTING  CLK_PLLCON_50MHz_HXT
#define PLL_CLOCK       50000000

void SYS_Init(void)
{

    /*---------------------------------------------------------------------------------------------------------*/
    /* Init System Clock                                                                                       */
    /*---------------------------------------------------------------------------------------------------------*/
        CLK_SetCoreClock(FREQ_50MHZ);
        CLK_EnableModuleClock(UART0_MODULE);
        CLK_SetModuleClock(UART0_MODULE,CLK_CLKSEL1_UART_S_PLL,CLK_CLKDIV_UART(1));

    /*---------------------------------------------------------------------------------------------------------*/
    /* Init I/O Multi-function                                                                                 */
    /*---------------------------------------------------------------------------------------------------------*/

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

}

void UART0_Init()
{
    /*---------------------------------------------------------------------------------------------------------*/
    /* Init UART                                                                                               */
    /*---------------------------------------------------------------------------------------------------------*/
    /* Reset UART0 */
    SYS->IPRSTC2 |=  SYS_IPRSTC2_UART0_RST_Msk;
    SYS->IPRSTC2 &= ~SYS_IPRSTC2_UART0_RST_Msk;

    /* Configure UART0 and set UART0 Baudrate */
    UART0->BAUD = UART_BAUD_MODE2 | UART_BAUD_MODE2_DIVIDER(__HXT, 115200);
    UART0->LCR = UART_WORD_LEN_8 | UART_PARITY_NONE | UART_STOP_BIT_1;
}

/*---------------------------------------------------------------------------------------------------------*/
/*  Main Function                                                                                          */
/*---------------------------------------------------------------------------------------------------------*/
int32_t main(void)
{
   
    /* 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("\n\nCPU [url=home.php?mod=space&uid=72445]@[/url] %dHz\n", SystemCoreClock);

    /*
        This sample code will blinking LED on NuTiny EVB board of M058SSAN.
        The I/O for LED is P2.3 or P3.6
    */

    printf("+---------------------------------------+\n");
    printf("|    NuTiny EVB LED Sample Code         |\n");
    printf("+---------------------------------------+\n");
   
    /* Init P3.6 to be output mode */

                GPIO_SetMode(P3,BIT6,GPIO_PMD_OUTPUT);
   
    while(1)
    {      
        /* Toggle P3.6 */
        P36 ^= 1;
        /* Delay 200ms */
        CLK_SysTickDelay(200000);
    }   
}


使用特权

评论回复
板凳
yiyigirl2014|  楼主 | 2025-1-8 13:59 | 只看该作者
大家觉得我这个帖子艺术含量有多高?
我看很多人没用过这个函数,我也没用过,仔细研究发现,真是个一劳永逸的函数。

使用特权

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

本版积分规则

218

主题

3566

帖子

10

粉丝