[CW32L083系列]CW32L083评估板学习-3.了解系统时钟与延时函数的实现

3.1认识CW32L083的时钟源
CW32L083可选择5种时钟源,包括HSE、LSE、PLL、HSI、LSI
 


HSE是外部高速时钟,有两种工作模式
 


可以使用的晶振频率如下


评估板上焊接了一颗16MHz的晶振作为高速时钟源
LSE是外部低速时钟,与HSE类似也有两种工作模式


评估板上接的是32.768K的晶振作为低速时钟源
HSI是内部高速时钟,由内部RC振荡器产生并分频而来,不需要外部电路,比HSE时钟的成本低,启动速度快,HSIOSC时钟频率固定为48MHz,频率精度低于HSE时钟
LSI是内部低速时钟,由内部低速RC振荡器产生,默认频率为 32.8kHz,与HSI类似内部低速RC振荡器不需要外部电路,比LSE时钟的成本低,但精度低于LSE时钟
PLL可对输入时钟源进行倍频输出,通过PLL可以使用最高64MHz的时钟,可用的时钟源有


3.2使用不同的时钟源
在之前创建的工程中并没有特意的配置时钟,通过手册可以知道通电默认使用的HSI频率为8MHz
 


使用MCO_OUT(PA08)输出HCLK的512分频波形
 

复制

int32_t main(void)

{

    RCC_HCLKPRS_Config(RCC_HCLK_DIV1);

    RCC_PCLKPRS_Config(RCC_PCLK_DIV1);

    RCC_MCO_OUT(RCC_MCO_SRC_HCLK,RCC_MCO_DIV512);

    while(1)

    {

    }

}

查看输出的波形
 


15.625KHz x 512 = 8000KHz = 8MHz
接下来使用内部48MHz时钟不分频初始化,需要注意的是CW32的FLASH存储器支持最快24MHz的操作时钟,当系统时钟设置超过24MHz后要设置FLASH的等待周期,且此操作必须在时钟频率切换之前执行,这里输出时改用1024分频
 

复制

void RCC_HSI_init()

{

    //< 当使用的时钟源HCLK大于24M,小于等于48MHz:设置FLASH 读等待周期为2 cycle >

    __RCC_FLASH_CLK_ENABLE();

    FLASH_SetLatency(FLASH_Latency_2);

    /* HSI使能 */

    RCC_HSI_Enable(RCC_HSIOSC_DIV1); //1分频要在设置之前设置FLASH读等待周期

    RCC_SystemCoreClockUpdate(48000000);

}

int32_t main(void)

{

        RCC_HSI_init();

    RCC_HCLKPRS_Config(RCC_HCLK_DIV1);

    RCC_PCLKPRS_Config(RCC_PCLK_DIV1);

    RCC_MCO_OUT(RCC_MCO_SRC_HCLK,RCC_MCO_DIV1024);

    while(1)

    {

    }

}

输出波形
 


45.455KHz x 1024 = 46545.92KHz = 46.5MHz
再来用外部16MHz晶振来初始化
 

复制

void RCC_HSE_16M_init()

{

    RCC_HSE_Enable( RCC_HSE_MODE_OSC, 16000000, RCC_HSE_DRIVER_NORMAL, RCC_HSE_FLT_CLOSE);

    RCC_SysClk_Switch( RCC_SYSCLKSRC_HSE );

    RCC_HSI_Disable();

    RCC_SystemCoreClockUpdate(16000000);

}

int32_t main(void)

{

        RCC_HSE_16M_init();

    RCC_HCLKPRS_Config(RCC_HCLK_DIV1);

    RCC_PCLKPRS_Config(RCC_PCLK_DIV1);

    RCC_MCO_OUT(RCC_MCO_SRC_HCLK,RCC_MCO_DIV1024);

    while(1)

    {

    }

}

输出波形
 


15.625KHz x 1024 = 16000KHz = 16MHz
接下来使用外部时钟PLL到64MHz
 

复制

void RCC_HSE_16M_PLL64M_init()

{

    //< 当使用的时钟源HCLK大于48M,小于等于72MHz:设置FLASH 读等待周期为3 cycle >

    __RCC_FLASH_CLK_ENABLE();

    FLASH_SetLatency(FLASH_Latency_3);

    RCC_HSE_Enable( RCC_HSE_MODE_OSC, 16000000, RCC_HSE_DRIVER_NORMAL, RCC_HSE_FLT_CLOSE);

    RCC_PLL_Enable(RCC_PLLSOURCE_HSEOSC,16000000,RCC_PLL_MUL_4);

    RCC_SysClk_Switch( RCC_SYSCLKSRC_PLL );

    RCC_HSI_Disable();

    RCC_SystemCoreClockUpdate(64000000);

}

int32_t main(void)

{

        RCC_HSE_16M_PLL64M_init();

    RCC_HCLKPRS_Config(RCC_HCLK_DIV1);

    RCC_PCLKPRS_Config(RCC_PCLK_DIV1);

    RCC_MCO_OUT(RCC_MCO_SRC_HCLK,RCC_MCO_DIV1024);

    while(1)

    {

    }

}

输出波形
 


62.5KHz x 1024 = 64000KHz = 64MHz
接下来用内部48MHz时钟6分频得到8MHz再倍频到64MHz
 

复制

void RCC_HSI_PLL64M_init()

{

    //< 当使用的时钟源HCLK大于48M,小于等于72MHz:设置FLASH 读等待周期为3 cycle >

    __RCC_FLASH_CLK_ENABLE();

    FLASH_SetLatency(FLASH_Latency_3);

    RCC_HSI_Enable(RCC_HSIOSC_DIV6);

    RCC_PLL_Enable(RCC_PLLSOURCE_HSI,8000000,RCC_PLL_MUL_8);

    RCC_SysClk_Switch( RCC_SYSCLKSRC_PLL );

    RCC_SystemCoreClockUpdate(64000000);

}

int32_t main(void)

{

        RCC_HSI_PLL64M_init();

    RCC_HCLKPRS_Config(RCC_HCLK_DIV1);

    RCC_PCLKPRS_Config(RCC_PCLK_DIV1);

    RCC_MCO_OUT(RCC_MCO_SRC_HCLK,RCC_MCO_DIV1024);

    while(1)

    {

    }

}

输出波形


62.5KHz x 1024 = 64000KHz = 64MHz
使用内部低速时钟LSI
 

复制

void RCC_LSI_init()

{

    RCC_LSI_Enable();

    RCC_SysClk_Switch(RCC_SYSCLKSRC_LSI);

    RCC_HSI_Disable();

    RCC_SystemCoreClockUpdate(32800);

}

int32_t main(void)

{

        RCC_LSI_init();

    RCC_HCLKPRS_Config(RCC_HCLK_DIV1);

    RCC_PCLKPRS_Config(RCC_PCLK_DIV1);

    RCC_MCO_OUT(RCC_MCO_SRC_HCLK,RCC_MCO_DIV1);

    while(1)

    {

    }

}

输出波形
 


使用外部低速晶振
 

复制

void RCC_LSE_init()

{

    RCC_LSE_Enable(RCC_LSE_MODE_OSC,RCC_LSE_AMP_LARGER,RCC_LSE_DRIVER_LARGER);

    RCC_SysClk_Switch(RCC_SYSCLKSRC_LSE);

    RCC_HSI_Disable();

    RCC_SystemCoreClockUpdate(32768);

}

int32_t main(void)

{

        RCC_LSE_init();

    RCC_HCLKPRS_Config(RCC_HCLK_DIV1);

    RCC_PCLKPRS_Config(RCC_PCLK_DIV1);

    RCC_MCO_OUT(RCC_MCO_SRC_HCLK,RCC_MCO_DIV1);

    while(1)

    {

    }

}

输出波形


3.3延时函数的实现
L083的system_cw32l083.c中有一个FirmwareDelay方法用于延时
 


但是这个并不好控制具体延时多长时间,利用SysTick可以做一个Arm内核的通用延时方法,SysTick定时器(又名系统滴答定时器)是存在于ARM Cotex-M系列内核中的定时器。具体实现方法
 

复制

extern uint32_t SystemCoreClock;

void yuyy_delay_us(uint16_t us)

{

    uint32_t temp;

    SysTick->CTRL = 0x0;               /*!< disable systick function */

    SysTick->LOAD = us * (SystemCoreClock/1000000);         /*!< time count for 1us with SYSCLK */

    SysTick->VAL  = 0x00;              /*!< clear counter */

    SysTick->CTRL = 0x5;               /*!< start discrease with Polling */

    do

    {

        temp = SysTick->CTRL;

    }

    while ((temp & 0x01) && !(temp & (1 << 16))); /*!< wait time count done */

    SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;    /*!< Close Counter */

    SysTick->VAL   = 0X00;

}



void yuyy_delay_ms(uint16_t ms)

{

    while(ms--)

        yuyy_delay_us(1000);

}

这个延时方法我已经在M0 M3 M4 M33的MCU上都使用过了,移植基本不用改动,只要注意修改时钟源后更新系统时钟就行了I
---------------------
作者:yuyy1989
链接:https://bbs.21ic.com/icview-3319334-1-1.html
来源:21ic.com
此文章已获得原创/原创奖标签,著作权归21ic所有,任何人未经允许禁止转载。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值