Chinaunix首页 | 论坛 | 博客
  • 博客访问: 19568
  • 博文数量: 5
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 55
  • 用 户 组: 普通用户
  • 注册时间: 2016-08-30 21:50
个人简介

让技术进行到底

文章分类
文章存档

2016年(5)

我的朋友

分类: 嵌入式

2016-09-18 23:00:17

    STM32的SYSCLK(系统时钟)可由三种不同的时钟源来驱动,分别是HSI振荡器时钟、HSE振荡器时钟、PLL时钟。这些设备还拥有2种二级时钟源:

    1、低速内部RC(LSI RC)振荡器,频率在30~60KHZ之间变化,为了方便计算我们一般估算为40KHZ,它主要为独立看门狗提供时钟源,或通过相关寄存器配置驱动RTC(RTCCLK),用于从停机/待机模式下自动唤醒系统。

    2、使用32.768KHZ的低速外部晶体时钟来驱动RTC(RTCCLK)。 

    为减小功耗,STM32的任一时钟源都可以独立地开启或关闭。

注意:1、当HSI(高速内部时钟)作为PLL时钟输入时,SYSCLK得到的最大频率为36MHZ(有些写的是64MHZ)。SDIO接口的时钟频率固定为HCLK/2。

  2、AHB、高速APB(APB2)域的最大频率是72MHZ; 低速APB(APB1)域的最大频率是36MHZ,所以在配置由APB1提供时钟的外设时要特别留意。

  3、RCC通过AHB时钟(HCLK)8分频后作为Cortex系统定时器(SYSTick)的外部 时钟,当然SYSTICK的时钟也可通过相关寄存器来获得。

  4、ADC时钟由高速APB2时钟经2、4、6、8分频后获得。

    定时器在STM32中起着举足轻重的地位,学不好定时器就相当于没有学过STM32单片机。所以定时器的频率设置就显得尤为重要,其频率分频由硬件按以下2种情况自动设置:

1、如果相应的APB预分频系数是1,定时器的时钟频率与所在APB总线频率一致。

2、否则,定时器的时钟频率被设为与其相连的APB总线频率的2倍。



例:若AHB的时钟为72MHZ,因为APB1的时钟最大只能为36MHZ,所以APB1的预分频值不能为1,假设为2,则APB1=36MHZ时钟,则定时器2~7的时钟就为72MHZ。
以上介绍时钟主要来自系统时钟SYSCLK,其它请参考STM32官方参考手册。

高速外部时钟(HSE)

时钟来源:HSE外部时钟:它由 外部提供时钟(50%占空比的方波、正弦波、三角波)连接到输入端,同时要保证OSC_OUT端口悬空,输入最高频率50MHZ。

HSE外部晶体/陶瓷谐振器:3~25MHZ外部振荡器为系统提供精确的主时钟,在电路设计时为了减少时钟输出的失真和缩短启动稳定时间,晶振和负载电容必须尽可能的靠近振荡器引脚,连接线路时不要打过孔,最好进行包地处理。负载电容值必须根据所选的振荡器来调整。

晶振的负载电容=[(c1*c2)/(c1+c2)]+(4~6)pf的杂散电容;c1,c2为旁路电容。


                                                                                               
高速内部时钟(HSI)

        HSI时钟信号由内部8MHZ的RC震荡器产生,可直接作为系统时钟或2分频后作为PLL输入。在外部无时钟或HSE失效时,HSI时钟会作为备用时钟源自动切换,但时钟精度稍差。


低速外部时钟(LSE)

        由一个外部的32.768khz低速晶体或陶瓷谐振器提供,主要为实时时钟或其他定时器功能提供一个低功耗且精确的时钟源。


低速内部时钟(LSI)

        它可以在停机和待机模式下保持运行,为独立看门狗和自动唤醒单元提供时钟,时钟频率在(30KHZ和60KHZ之间)。


时钟初始化过程:

1、设置时钟配置为初始值

2、开启外部时钟,等待外部时钟配置是否成功;

成功:设置PLL输入时钟

失败:开启内部时钟

3、配置AHB、APB2、APB1、HCLK、PCLK2、PCLK1等

4、使能PLL时钟,如果PLL作为了SYSCLK,它将不能被失能

5、等待PLL时钟是否就绪。

6、将PLL作为系统时钟,等待就绪。

7、开启外设时钟

8、设置优先级分组

这里采用V3.5库函数版本,MDK4.7;STM32F103ZET6


点击(此处)折叠或打开

  1. s32 STM32_CLOCK_Init(void)
  2. {
  3.     u32 Err=STM_ERR;

  4.     ErrorStatus HSEStartUpStatus;
  5.     u32 i=0;
  6.     /* Deinitialize the RCC registers */
  7.     RCC_DeInit();
  8.     //打开外部时钟,失败则选内部时钟
  9.     /* Enable the HSE */
  10.     RCC_HSEConfig(RCC_HSE_ON);
  11.     /* Wait till HSE is ready and if Time out is reached exit */
  12.     HSEStartUpStatus = RCC_WaitForHSEStartUp();
  13.     if(HSEStartUpStatus == SUCCESS)
  14.     {
  15.         //PLLCLK=16MHZ*2=32MHZ
  16.         RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_2);
  17.         Err=STM_TRUE;
  18.     }
  19.     else
  20.     {
  21.         /* Enable Internal High Speed oscillator */
  22.         RCC_HSICmd(ENABLE);    
  23.         //PLLCLK=8MHZ/2*8=32MHZ
  24.         RCC_PLLConfig(RCC_PLLSource_HSE_Div2, RCC_PLLMul_8);
  25.         Err=0x60000001;    
  26.     }
  27.     /* Configure HCLK such as HCLK = SYSCLK */
  28.     RCC_HCLKConfig(RCC_SYSCLK_Div1);//AHB==系统时钟
  29.     /* Configure PCLK2 such as PCLK2 = HCLK */
  30.     RCC_PCLK2Config(RCC_HCLK_Div1);//APB2==HCLK
  31.     /* Configure PCLK1 such as PCLK1 = HCLK/2 */
  32.     RCC_PCLK1Config(RCC_HCLK_Div2);//APB1==HCLK/2

  33.     /* Configure the Latency cycle: Set 2 Latency cycles */
  34.     FLASH_SetLatency(FLASH_Latency_2);//存储器取值延时2个周期
  35.     /* Enable The Prefetch Buffer */
  36.     FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

  37.     /* Enable the PLL */
  38.     RCC_PLLCmd(ENABLE);
  39.     while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET)
  40.     {
  41.         i++;
  42.         if(0xffff<=i)
  43.         {
  44.             Err=0x60000002;
  45.             break;
  46.         }
  47.     }
  48.     /* Select the PLL as system clock source */
  49.     RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
  50.     i=0;
  51.     while(RCC_GetSYSCLKSource()!=0x08)
  52.     {
  53.         i++;
  54.         if(0xffff<=i)
  55.         {
  56.             Err=0x60000003;
  57.             break;
  58.         }
  59.     }
  60.     RCC_APB1PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
  61.     /* Configure the Priority Grouping with 1 bit */
  62.     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
  63.     return Err;
  64. }

在库函数V3.5以后,在不配置系统时钟的情况下,默认为72MHZ。从startup_stm32f10x_hd.s中可以看出:

点击(此处)折叠或打开

  1. ; Reset handler
  2. Reset_Handler PROC
  3.                 EXPORT Reset_Handler [WEAK]
  4.                 IMPORT __main
  5.                 IMPORT SystemInit
  6.                 LDR R0, =SystemInit
  7.                 BLX R0
  8.                 LDR R0, =__main
  9.                 BX R0
  10.                 ENDP

在复位产生之后,系统首先运行SystemInit(),然后在执行main函数。而在system_stm32f10x.c中默认外部时钟为8M,设置为72MHZ,但在实际中如果我们使用大于8MHZ的外部时钟时,系统时钟依旧为72MHZ。如果想


点击(此处)折叠或打开

  1. #if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
  2. /* #define SYSCLK_FREQ_HSE HSE_VALUE */
  3.  #define SYSCLK_FREQ_24MHz 24000000
  4. #else
  5. /* #define SYSCLK_FREQ_HSE HSE_VALUE */
  6. /* #define SYSCLK_FREQ_24MHz 24000000 */
  7. /* #define SYSCLK_FREQ_36MHz 36000000 */
  8. /* #define SYSCLK_FREQ_48MHz 48000000 */
  9. /* #define SYSCLK_FREQ_56MHz 56000000 */
  10. #define SYSCLK_FREQ_72MHz 72000000
  11. #endif















阅读(1814) | 评论(0) | 转发(0) |
0

上一篇:没有了

下一篇:STM32最小系统设计

给主人留下些什么吧!~~