0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

关于内外时钟切换及时钟超频测试

硬件攻城狮 来源:21ic 作者:21ic 2022-12-07 14:11 次阅读
前言

近日,有群友困于STM32时钟系统。这里就详细介绍一下关于内外时钟切换及时钟超频测试,希望对大家能有所帮助。

46be059a-75f1-11ed-8abf-dac502259ad0.png

诚然,当使用固件库时,把外部晶振摘掉,系统确实会自动切换到内部时钟,但是只会以8M的默认值运行,显然这是十分不可行的,8M的速度直接让我们的STM32病入膏肓,今天的任务就是让STM32失去外挂(晶振)时,依旧可以激情澎湃。

时钟详解这里不过多介绍,自己也没有别人介绍的好,本文旨在解决现实问题。

此处插播广告:群友问过这种问题,外部接8M晶振和16M晶振有啥区别?

以我微薄的经验来看,这两个在用的时候差别不大,如果使用ST的固件库(以STM32F103为例),使用8M的晶振会更方便,不用改任何代码,时钟就是72M的全速运行状态。如果用16M晶振,则需要修改代码:

在stm32f10x.h中修改宏定义HSE_VALUE ((uint32_t)8000000)为HSE_VALUE ((uint32_t)16000000)。

46e8dcb6-75f1-11ed-8abf-dac502259ad0.png

之后进入system_stm32f10x.c,将RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);改为RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSI_Div2| RCC_CFGR_PLLMULL9);此处是将输入时钟二分频为8M,再进行9倍频到72M,和使用了8M没区别。

如果不进行该二分频操作,时钟还是有的,但是会以16M为基准进行9倍频到144M,此时单片机以超频模式运行,也是可以运行的。但是,时钟的精准性不能得到保证。

470d387c-75f1-11ed-8abf-dac502259ad0.png

系统的时钟可以通过添加代码在debug模式下显示:

RCC_ClocksTypeDef ClockInfo;
RCC_GetClocksFreq(&ClockInfo);

4733359a-75f1-11ed-8abf-dac502259ad0.png

通过debug模式下观察ClockInfo的值,便可知道此时系统时钟速度:

4766a934-75f1-11ed-8abf-dac502259ad0.png

4766a934-75f1-11ed-8abf-dac502259ad0.png

这里提一下,在使用外部晶振的情况下,ST即使是超频,依旧发挥稳定,不得不夸一下ST的质量。

此时我将我的开发板以8M的基准倍频16倍,得到128M的主频,使用定时器定时10us,示波器测试无误差。串口通信无误。

47d370dc-75f1-11ed-8abf-dac502259ad0.png

48011564-75f1-11ed-8abf-dac502259ad0.png

48323c2a-75f1-11ed-8abf-dac502259ad0.png

48c47860-75f1-11ed-8abf-dac502259ad0.png

以72M的主频跑128依旧稳定,赞一个,因为我的外部晶振只有8M最大只能倍频到128,如果使用外部16M,不知继续倍频可以到多少。不过性能还是很好的。

预留测试GD32的效果:

写本文时,将GD的GD32E230翻出来进行了同样的测试,因为GD的倍频器倍数较高,我已经倍频到144M(标准72M),测试定时器依旧稳定。

48e53c1c-75f1-11ed-8abf-dac502259ad0.png

广告很长,请忍一下:

上半场结束,下半场继续:

此处歪解一下时钟的问题,之前有群友很疑惑单片机的低功耗和时钟的关系,疑惑高速的时钟会不会增加MCU的功耗,为啥低功耗要降低时钟速度。这里讲解一下:

可以用用单位时间内执行的指令来看,高速时钟在单位时间内使系统跑了更多的指令,而低速时钟单位时间内跑的少,而单片机是直线结构,内核是不会休息的,功耗就看执行的指令多少。而单片机的低功耗就是降低时钟,让单片机跑慢点。就像人一样,低功耗相当于你不跑了,原地休息,但是你的心跳不会停止,你还是得消耗能量,即使再少还得消耗。

就像人一样,时钟就相当于心跳,只要还活着就得消耗能量,你要想跑得快,心脏就得跳得快,跳得越快能量消耗越高,即使你去睡觉,心跳只要不停止,你还得消耗能量,如果心跳没了,整个人就没了,MCU也就宕机了。所以,在处理低功耗时最先解决的就是时钟频率,只有降低了时钟的频率,才能真正降低功耗。关于单片机进入低功耗和唤醒,以及降低整体运行功耗我看能不能在下文讲解,近期刚好做了一个低功耗的项目,这里留悬念吧。

广告结束,正文开始,不好意思,有点喧宾夺主了哈!

回到主题,为了解决时钟切换的问题,才有了这个帖子,上文全属歪楼,为最近开发时的经验总结。

我们在使用STM32103的固件库时,时钟配置在system_stm32f10x.c中,但是只是对外部晶振做了初始化,而对于内部时钟并没有添加代码,如果你的MCU没有外部晶振,当系统运行时是先启动内部时钟,然后会检测外部晶振,如果没有检测到晶振,系统便以内部的8M继续运行,这是不合理的。

4907446a-75f1-11ed-8abf-dac502259ad0.png

这里可以看到,如果外部启动失败,会进入这个else,但是这个else中并未添加任何代码,所以只会用8M的内钟执行,我们要做的就是在else中添加外部启动失败的代码:

  /* 开启HSI 即内部晶振时钟 */
  RCC->CR |= (uint32_t)0x00000001; 
  /*选择HSI为PLL的时钟源HSI必须2分频给PLL*/
  RCC->CFGR |= (uint32_t)RCC_CFGR_PLLSRC_HSI_Div2; 
         
  /*PLLCLK=8/2*13=52MHz 设置倍频得到时钟源PLL的频率*/
  RCC->CFGR |= (uint32_t)RCC_CFGR_PLLMULL12;
  /* PLL不分频输出*/
  RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
   
  /* 使能 PLL时钟 */
  RCC->CR |= RCC_CR_PLLON;
  /* 等待PLL时钟就绪*/
  while((RCC->CR & RCC_CR_PLLRDY) == 0)
  {
  }
  /* 选择PLL为系统时钟的时钟源 */
  RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
  RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;  
  /* 等到PLL成为系统时钟的时钟源*/
  while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)
  {
}

该代码填充后如果检测到有外部时钟,便以外部时钟为基准进行时钟的倍频处理,达到用户想要的时钟频率,如果你的MCU没有外部时钟,则会执行else内部的代码,将时钟源切换到内部时钟并进行倍频,如此便达到了自动检测时钟的目的。

问题:这是我根据STM32F031的时钟切换代码演变来的,但是这个只能用于主频小于或等于48M时使用,如果倍频因子超过12,也就是主频超过48M是,就会出现硬件错误,直接卡死。当需要更高的主频时就需要如下配置。

在else里面最开头添加:

  /* Enable Prefetch Buffer */
  FLASH->ACR |= FLASH_ACR_PRFTBE;
  /* Flash 2 wait state */
  FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
FLASH->ACR|=(uint32_t)FLASH_ACR_LATENCY_2;

492c0bec-75f1-11ed-8abf-dac502259ad0.png

问:如果我的MCU有晶振,但是我不想用外部,就想用内部,如何处理呢?

答:打一顿就好了,有外部不用干啥用内部呢?

上述纯属恶搞自己,被坑过……

因为内部时钟不准!!!测试内部时钟在使用定时器时会有偏差,本人在此吃过亏。此问题在STM32F031和GD32E230中均有体现。但是USART和SPI通信是正常的,即使我用的2.5M波特率的USART和8M的SPI。

解决办法,上述代码不用动,添加如下代码。

4980dbcc-75f1-11ed-8abf-dac502259ad0.png

通过注释原文RCC->CR |= ((uint32_t)RCC_CR_HSEON);并添加RCC->CR &= ~((uint32_t)RCC_CR_HSEON);可默认之以内部时钟方式启动。 注意:在主函数加上SystemInit();函数哦!!! 最终代码如下:

static void SetSysClockTo72(void)
{


__IO uint32_t StartUpCounter = 0, HSEStatus = 0;





/* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/  


/* Enable HSE */  


//RCC->CR |= ((uint32_t)RCC_CR_HSEON);


  /*取消改行注释并注释上文,可默认启动内部时钟*/


  RCC->CR &= ~((uint32_t)RCC_CR_HSEON);


/* Wait till HSE is ready and if Time out is reached exit */


do


{


  HSEStatus = RCC->CR & RCC_CR_HSERDY;


  StartUpCounter++;


} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));






if ((RCC->CR & RCC_CR_HSERDY) != RESET)


{


  HSEStatus = (uint32_t)0x01;


}


else


{


  HSEStatus = (uint32_t)0x00;


}






if (HSEStatus == (uint32_t)0x01)


{


  /* Enable Prefetch Buffer */


  FLASH->ACR |= FLASH_ACR_PRFTBE;






  /* Flash 2 wait state */


  FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);


  FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;  










  /* HCLK = SYSCLK */


  RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;


  


  /* PCLK2 = HCLK */


  RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;


  


  /* PCLK1 = HCLK */


  RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;






#ifdef STM32F10X_CL


  /* Configure PLLs ------------------------------------------------------*/


  /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */


  /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */


  


  RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL |


          RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);


  RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 |


         RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5);





  /* Enable PLL2 */


  RCC->CR |= RCC_CR_PLL2ON;


  /* Wait till PLL2 is ready */


  while((RCC->CR & RCC_CR_PLL2RDY) == 0)


  {


  }


  


 


  /* PLL configuration: PLLCLK = PREDIV1 * 9 = 72 MHz */ 


  RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL);


  RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | 


          RCC_CFGR_PLLMULL9); 


#else  


  /*PLL configuration: PLLCLK = HSE * 9 = 72 MHz */


  RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE |


              RCC_CFGR_PLLMULL));


  RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL16);


#endif /* STM32F10X_CL */






  /* Enable PLL */


  RCC->CR |= RCC_CR_PLLON;






  /* Wait till PLL is ready */


  while((RCC->CR & RCC_CR_PLLRDY) == 0)


  {


  }


  


  /* Select PLL as system clock source */


  RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));


  RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;  






  /* Wait till PLL is used as system clock source */


  while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)


  {


  }


}


else


{ 


  /* Enable Prefetch Buffer */


  FLASH->ACR |= FLASH_ACR_PRFTBE;


  /* Flash 2 wait state */


  FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);


  FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;    


   /* 开启HSI 即内部晶振时钟 */


  RCC->CR |= (uint32_t)0x00000001; 






  /*选择HSI为PLL的时钟源HSI必须2分频给PLL*/


  RCC->CFGR |= (uint32_t)RCC_CFGR_PLLSRC_HSI_Div2; 






         


  /*PLLCLK=8/2*13=52MHz 设置倍频得到时钟源PLL的频率*/


  RCC->CFGR |= (uint32_t)RCC_CFGR_PLLMULL16;






  /* PLL不分频输出*/


  RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;


   


  /* 使能 PLL时钟 */


  RCC->CR |= RCC_CR_PLLON;






  /* 等待PLL时钟就绪*/


  while((RCC->CR & RCC_CR_PLLRDY) == 0)


  {


  }










  /* 选择PLL为系统时钟的时钟源 */


  RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));


  RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;  






  /* 等到PLL成为系统时钟的时钟源*/


  while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)


  {






  }


}


}

在STM32F030或者STM32F031中,同样可以做类似操作:

static void SetSysClock(void)
{


__IO uint32_t StartUpCounter = 0, HSEStatus = 0;





/* SYSCLK, HCLK, PCLK configuration ----------------------------------------*/


/* Enable HSE */ 






RCC->CR |= ((uint32_t)RCC_CR_HSEON);


  //修改为内部晶振  


//  RCC->CR &= ~((uint32_t)RCC_CR_HSEON);


 


/* Wait till HSE is ready and if Time out is reached exit */


do


{


  HSEStatus = RCC->CR & RCC_CR_HSERDY;


  StartUpCounter++;


} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));






if ((RCC->CR & RCC_CR_HSERDY) != RESET)


{


  HSEStatus = (uint32_t)0x01;


}


else


{


  HSEStatus = (uint32_t)0x00;


}






if (HSEStatus == (uint32_t)0x01)


{


  /* Enable Prefetch Buffer and set Flash Latency */


  FLASH->ACR = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY;


 


  /* HCLK = SYSCLK */


  RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;


  


  /* PCLK = HCLK */


  RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE_DIV1;






  /* PLL configuration = HSE * 6 = 48 MHz */


  RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));


  RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLMULL7);


    


  /* Enable PLL */


  RCC->CR |= RCC_CR_PLLON;






  /* Wait till PLL is ready */


  while((RCC->CR & RCC_CR_PLLRDY) == 0)


  {


  }






  /* Select PLL as system clock source */


  RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));


  RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;  






  /* Wait till PLL is used as system clock source */


  while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)RCC_CFGR_SWS_PLL)


  {


  }


}


else


{ /* If HSE fails to start-up, the application will have wrong clock 


   configuration. User can add here some code to deal with this error */


       // HSI 内部时钟做为PLL时钟源并配置PLL 56M做为系统时钟


  /* Enable Prefetch Buffer and set Flash Latency */


  FLASH->ACR = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY;






  /* HCLK = SYSCLK */


  RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;






  /* PCLK = HCLK */


  RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE_DIV1;






  // PLL configuration = (HSI/2) * 12 = 48 MHz


  RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_14); // 8M/2 * 14 = 56M






  /* Enable PLL */


  RCC->CR |= RCC_CR_PLLON;






  /* Wait till PLL is ready */


  while ((RCC->CR & RCC_CR_PLLRDY) == 0)


  {


  }






  /* Select PLL as system clock source */


  RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); // PLL 做系统时钟






  /* Wait till PLL is used as system clock source */


  while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)RCC_CFGR_SWS_PLL)


  {


  }


}


}

在STM32F103中,使用内部晶振,最大时钟频率也只能到64M,受倍频因子的影响嘛,最大只能倍频16倍。但在STM32F031中,标准使用内部时钟主频只有48M,但是我们仍然可以继续倍频,用内部时钟进行超频达到64M。在我们的产品中就用过内部超频到56M,USART和SPI长时间无问题。

而GD32E230因为其高达32的倍频因子,内部时钟可以倍频到128M。

49aaa9ca-75f1-11ed-8abf-dac502259ad0.png

但是,这种几分钟内没有明显发热现象,不敢做长时间测试,现在MCU有点小贵。干费一个就心疼。

总之,无论ST还是国产,其主频更适合在规定的范围内运行,但是跑极限在短时间内也没有很大的问题。这些数据仅供参考。

至此单片机时钟讲解就结束了,没有多少理论性的东西,主要是解决一些时钟使用时的问题,自己也总是忘,留帖一篇作为自省。

本文中所有代码都经过本人测试,运行无任何问题,但是对于问题的阐述或者一些见解可能有错误,欢迎大佬们批评指正,一定接受各种批评,努力完善!

审核编辑 :李倩


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 晶振
    +关注

    关注

    33

    文章

    2793

    浏览量

    67808
  • STM32
    +关注

    关注

    2264

    文章

    10852

    浏览量

    354184
  • 时钟
    +关注

    关注

    10

    文章

    1712

    浏览量

    131260

原文标题:工程师歪解单片机的时钟系统,有点意思~

文章出处:【微信号:mcu168,微信公众号:硬件攻城狮】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    京准时钟科普:关于北斗卫星同步时钟的那些事?

    京准时钟科普:关于北斗卫星同步时钟的那些事?
    的头像 发表于 10-29 09:28 143次阅读
    京准<b class='flag-5'>时钟</b>科普:<b class='flag-5'>关于</b>北斗卫星同步<b class='flag-5'>时钟</b>的那些事?

    视频时钟合成芯片怎么用

    ,以确保视频信号的同步和稳定。以下是关于视频时钟合成芯片的使用指南: 1. 视频时钟合成芯片的基本概念 视频时钟合成芯片是一种数字电路,它通过相位锁定环(Phase-Locked Lo
    的头像 发表于 10-10 11:17 167次阅读

    时钟抖动和时钟偏移的区别

    时钟抖动(Jitter)和时钟偏移(Skew)是数字电路设计中两个重要的概念,它们对电路的时序性能和稳定性有着显著的影响。下面将从定义、原因、影响以及应对策略等方面详细阐述时钟抖动和时钟
    的头像 发表于 08-19 18:11 689次阅读

    请问cyt4bb7的锁相环如何配置到cpu时钟,以达到超频的目的?

    请问cyt4bb7的锁相环如何配置到cpu时钟,以达到超频的目的?
    发表于 05-23 08:25

    请问STM32可以超频吗?

    在配置STM32的时钟的时候,像F103是72M,F429是180M,F4大部分是168M,改变时钟的配置让他超频行不行呢?是不是会不可靠?有没有人试过啊? 等考完试了,好好地实验一下。看看F429能超到多少 。。。
    发表于 05-08 07:14

    关于STM32F103内外时钟切换问题求解

    产品设计方案:在HSE故障时切换至HSI,2分频后给PLL再16倍频(手册说可以到64M),在LSE故障时优先切换至HSE时钟,HSE故障时切换至LSI,暂时只考虑故障后复位重启,未修
    发表于 04-10 08:03

    PTP时钟源设备全攻略:从普通时钟到透明时钟的进阶之路

    在现代通信技术中,精确时间同步对于保障网络性能至关重要。PTP(PrecisionTimeProtocol)时钟源设备作为实现高精度时间同步的关键组件,其配置和选择对于网络架构师和工程师来说至关重要
    的头像 发表于 02-22 08:04 1319次阅读
    PTP<b class='flag-5'>时钟</b>源设备全攻略:从普通<b class='flag-5'>时钟</b>到透明<b class='flag-5'>时钟</b>的进阶之路

    数字电路之时钟切换电路解析

    以上是一个比较经典的时钟切换电路。 根据实际使用场景的不同,时钟切换有很多不同的实现方法,都可以做得非常经典。 时钟,复位,是数字设计里最最
    的头像 发表于 02-18 18:22 2991次阅读
    数字电路之<b class='flag-5'>时钟</b><b class='flag-5'>切换</b>电路解析

    什么是时钟信号?数字电路的时钟信号是怎么产生呢?

    什么是时钟信号?数字电路的时钟信号是怎么产生呢? 时钟信号,也称为时钟脉冲,是用于同步数字电路中所有操作的基本信号。它提供了一个参考频率,使得所有电路元件都能按照同样的节奏进行工作。
    的头像 发表于 01-25 15:40 9007次阅读

    网络时钟同步有哪些要求?如何在5G网络中测试时间与时钟同步?

    网络时钟同步有哪些要求?要注意哪些问题?如何在5G网络中测试时间与时钟同步? 网络时钟同步是指在计算机网络中,各个时钟节点之间通过协议和算法
    的头像 发表于 01-16 16:03 1182次阅读

    如何生成关于时钟同步功能的DTC?

    如何生成关于时钟同步功能的DTC? 时钟同步功能是指在一个系统内的多个时钟源进行同步,确保它们的时间保持一致。这在许多实时系统中都非常重要,特别是在需要多个设备或组件协同工作的场景中。
    的头像 发表于 01-16 15:10 545次阅读

    FPGA中时钟的用法

    生成时钟包括自动生成时钟(又称为自动衍生时钟)和用户生成时钟。自动生成时钟通常由PLL或MMCM生成,也可以由具有分频功能的
    的头像 发表于 01-11 09:50 1585次阅读
    FPGA中<b class='flag-5'>时钟</b>的用法

    差分探头对时钟测试的影响

    差分探头对时钟测试的影响  差分探头是一种用于测量电路中电压或电流变化的设备。在时钟测试中,差分探头被用来测量时钟信号的频率、占空比、上升时
    的头像 发表于 01-08 15:36 471次阅读

    如何实现分频时钟切换

    其实这个分频时钟切换很简单,根本不需要额外的切换电路。一个共用的计数器,加一点控制逻辑,就可以了,而且可以实现2到16任意整数分频率之间的无缝切换
    的头像 发表于 12-14 15:28 719次阅读
    如何实现分频<b class='flag-5'>时钟</b>的<b class='flag-5'>切换</b>

    时钟树是什么?介绍两种时钟树结构

    今天来聊一聊时钟树。首先我先讲一下我所理解的时钟树是什么,然后介绍两种时钟树结构。
    的头像 发表于 12-06 15:23 1537次阅读