首先看一下 STM8S103K3 的时钟结构图,可以帮助你很好的理解。
这里有几个时钟,就是图中标识的时钟,需要弄清楚一下:fHSE: 外部高速晶振时钟,它是由外部晶振产生,大小由外部晶振大小决定,STM8S的外部晶振范围:1-24M,看图中的”HSE OSC 1-24M“。
fHSI:内部RC高速时钟,它是由内部的RC震荡电路产生的,其值16M。但是可以经过后面的分频器分频,四个分频系数可供选择(1,2,4,8)。注:精准度比外部晶振的要稍差一些。
fMASTER:主时钟,它是由HSE 或者 HSI提供时钟,主要功能给外围设备(peripherals,如I2C,SPI,ADC等)提供时钟,还有给CPU提供时钟源。
fCPU:cpu时钟,它是由fMASTER经过分频得到,其作用就是给CPU提供时钟,一个机械周期就是一个fCPU的时钟周期。
下面是时钟的源码部分,可供大家参考。
这里写了四段程序,分别是:使用高速内部时钟(寄存器版)
使用高速内部时钟(库函数版)
使用外部时钟(寄存器版)
使用外部时钟(库函数版)
源码如下,看注释应该就可以了。
/*******************************************************************************
* Function Name : InitCpuClock.
* Description : Initial CPU clock, .
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
static void InitCpuClock(void)
{
#if 1
// 寄存器版本 - 使用高速内部时钟
//Use HSI @8MHZ, div = 2; 8=16/2
CLK->ECKR &= ~CLK_ECKR_HSEEN; // 失能外时钟
CLK->CKDIVR &= (uint8_t)(~CLK_CKDIVR_HSIDIV); // 清零内部时钟预分频
CLK->CKDIVR |= CLK_PRESCALER_HSIDIV2; // 设置内部时钟预分频 2; 具体可以参考数据手册 (reference manual)
CLK->ICKR |= CLK_ICKR_HSIEN; // 使能内部高速时钟
while(!(CLK->ICKR&CLK_ICKR_HSIRDY)); // 等待内部高速时钟稳定, 稳定后则内部时钟已经开跑了。 时钟 = 16/2 M
#endif
#if 0
// 库函数版本 - 使用内部高速时钟
//Use HSI @8MHZ, div = 2; 8=16/2
CLK_HSECmd(DISABLE); // 失能外时钟
CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV2); // 设置内部时钟预分频 2; 具体可以参考数据手册 (reference manual)
CLK_HSICmd(ENABLE); // 使能内部高速时钟
while(!(CLK->ICKR&CLK_ICKR_HSIRDY)); // 等待内部高速时钟稳定, 稳定后则内部时钟已经开跑了。 时钟 = 16/2 M
#endif
#if 0
// 寄存器版本 - 使用外部时钟
CLK->CKDIVR |= CLK_PRESCALER_CPUDIV1; // CPU 时钟分频 1,CPU时钟 = 外部时钟(即是外部晶振频率)
CLK->ECKR |= CLK_ECKR_HSEEN; // 允许外部高速振荡器工作
while(!(CLK->ECKR & CLK_ECKR_HSERDY)); // 等待外部高速振荡器准备好
CLK->SWCR |= CLK_SWCR_SWEN; // 使能切换
CLK->SWR = CLK_SOURCE_HSE; // 选择芯片外部的高速振荡器为主时钟
while(!(CLK->SWCR&CLK_SWCR_SWIF)); // 等待切换成功
CLK->SWCR &= ~(CLK_SWCR_SWEN|CLK_SWCR_SWIF); // 清除切换标志
#endif
#if 0
// 库函数版本 - 使用外部时钟
CLK->CKDIVR |= CLK_PRESCALER_CPUDIV1; // CPU 时钟分频 1,CPU时钟 = 外部时钟(即是外部晶振频率)
CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, // 时钟自动切换模式,注: 参数是自动切换,不然只使用这一个函数是不能切换成功的
CLK_SOURCE_HSE, // 要切换的时钟(这里是外部时钟)
DISABLE, // 是否使能切换完成中断(这里失能)
CLK_CURRENTCLOCKSTATE_ENABLE);// 是否还使能当前时钟(这里选择 关掉当前时钟HSI)
CLK->SWCR &= ~(CLK_SWCR_SWEN|CLK_SWCR_SWIF); // 清除切换标志
#endif
}
上一篇:STM8 嵌入式特性编程之构建你的系统时间
下一篇:单片机ISP、IAP、ICP烧写方式的概念与区别
推荐阅读最新更新时间:2024-03-16 16:11
设计资源 培训 开发板 精华推荐
- “玄铁杯”第三届RISC-V应用创新大赛—国产高性能RISC-V Linux开发板LicheePi 4A报名专场,万元奖金,邀您奔赴开源设计盛宴
- 我给Xilinx资源中心做贡献
- 剁手不如玩板,这个双11免费好板等你来玩!
- 物联网、汽车、AI全覆盖——世平集团恩智浦解决方案大秀场
- ADI & 世健 新基建系列第三期——5G 仪器仪表和测试 答题赢好礼!
- “玄铁杯”第三届RISC-V应用创新大赛—国产高性能RISC-V Linux开发板LicheePi 4A报名专场,万元奖金,邀您奔赴开源设计盛宴
- 只为关心你——Maxim 智能可穿戴 IC 解决方案 白皮书免费下载
- 有奖直播:市场环境不确定,为物联网设备保驾护航英飞凌很确定