rcc.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /* 包含头文件-----------------------------------------------------------------*/
  2. #include "rcc.h"
  3. /* 私有宏定义-----------------------------------------------------------------*/
  4. #define RCC_CLOCK_SOURCE (0u) /* 0:内部时钟HSI 1:外部时钟HSE */
  5. #define RCC_SYSTICK_EN (1u) /* 0:不开启 1:开启 */
  6. #define RCC_ADC_CLOCK_EN (0u) /* 0:不开启 1:开启 */
  7. /* 私有类型定义---------------------------------------------------------------*/
  8. /* 私有变量-------------------------------------------------------------------*/
  9. static uint16_t delayMsCnt, delayUsCnt;
  10. /* 全局变量-------------------------------------------------------------------*/
  11. /* 私有函数原型---------------------------------------------------------------*/
  12. /* 注释掉位于stm32f10x_it.c文件中的SysTick_Handler函数
  13. 在别的地方复现此函数 滴答定时器中断函数
  14. void SysTick_Handler(void)
  15. {
  16. // user handle write here
  17. }
  18. */
  19. /**
  20. * @brief 系统时钟初始化
  21. * @note 外部晶振8MHz
  22. * @param sysclk : 时钟频率MHz(4的倍数)(HSI 8~64)(HSE 8~64和72)
  23. * @retval 0:时钟初始化成功 1:非法参数
  24. */
  25. uint8_t rcc_system_clock_config(uint8_t sysclk)
  26. {
  27. #if (RCC_CLOCK_SOURCE)
  28. if(64 < sysclk && 72 != sysclk) { return 1; }
  29. if(0 != (sysclk % 4) || 8 > sysclk || 72 < sysclk) { return 1; }
  30. #else
  31. if(0 != (sysclk % 4) || 8 > sysclk || 64 < sysclk) { return 1; }
  32. #endif
  33. RCC_DeInit();
  34. #if (RCC_CLOCK_SOURCE)
  35. RCC_HSEConfig(RCC_HSE_ON); /* 打开外部高速时钟HSE */
  36. while(RESET == RCC_GetFlagStatus(RCC_FLAG_HSERDY)); /* 等待时钟稳定 */
  37. #else
  38. RCC_HSICmd(ENABLE); /* 打开内部高速时钟HSI */
  39. while(RESET == RCC_GetFlagStatus(RCC_FLAG_HSIRDY)); /* 等待时钟稳定 */
  40. #endif
  41. RCC_HCLKConfig(RCC_SYSCLK_Div1); /* AHB clock(HCLK) = SYSCLK/1 (max:72MHz) */
  42. RCC_PCLK1Config(RCC_HCLK_Div2); /* APB1 clock(PCLK1) = HCLK/2 (max:36MHz) */
  43. RCC_PCLK2Config(RCC_HCLK_Div1); /* APB2 clock(PCLK2) = HCLK/1 (max:72MHz) */
  44. /* SYSCLK <= 24MHz 0等待周期 */
  45. if(24 >= sysclk)
  46. {
  47. FLASH_SetLatency(FLASH_Latency_0);
  48. } /* 24MHz < SYSCLK <= 48MHz 1等待周期 */
  49. else if(48 >= sysclk)
  50. {
  51. FLASH_SetLatency(FLASH_Latency_1);
  52. } /* 48MHz < SYSCLK <= 72MHz 2等待周期 */
  53. else
  54. {
  55. FLASH_SetLatency(FLASH_Latency_2);
  56. }
  57. FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); /* 使能FLASH预取缓冲区 */
  58. #if (RCC_CLOCK_SOURCE)
  59. /* SYSCLK <= 64MHz PLLCLK = (8MHz/2)*(SYSCLK/4) */
  60. if(64 >= sysclk)
  61. {
  62. RCC_PLLConfig(RCC_PLLSource_HSE_Div2, (sysclk / 4 - 2) * RCC_PLLMul_3);
  63. } /* SYSCLK == 72MHz PLLCLK = 8MHz*9 */
  64. else
  65. {
  66. RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
  67. }
  68. #else
  69. RCC_PLLConfig(RCC_PLLSource_HSI_Div2, (sysclk / 4 - 2) * RCC_PLLMul_3); /* PLLCLK = (8MHz/2)*(SYSCLK/4) */
  70. #endif
  71. RCC_PLLCmd(ENABLE); /* 使能PLL */
  72. while(RESET == RCC_GetFlagStatus(RCC_FLAG_PLLRDY)); /* 等待PLL稳定 */
  73. RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); /* 选择PLLCLK作为SYSCLK时钟源 */
  74. while(0x08 != RCC_GetSYSCLKSource()); /* 等待SYSCLK时钟源切换完成 */
  75. #if (RCC_SYSTICK_EN)
  76. SysTick_Config(sysclk * 1000); /* systick初始化周期1ms */
  77. #endif
  78. #if (RCC_ADC_CLOCK_EN)
  79. /* 设置ADC时钟分频系数 */
  80. if(28 >= sysclk)
  81. {
  82. RCC_ADCCLKConfig(RCC_PCLK2_Div2);
  83. }
  84. else if(56 >= sysclk)
  85. {
  86. RCC_ADCCLKConfig(RCC_PCLK2_Div4);
  87. }
  88. else
  89. {
  90. RCC_ADCCLKConfig(RCC_PCLK2_Div6);
  91. }
  92. #endif
  93. /* 根据主频计算延时因子 */
  94. if(24 >= sysclk)
  95. {
  96. delayMsCnt = sysclk * 123;
  97. delayUsCnt = sysclk / 8;
  98. if(!delayUsCnt) { delayUsCnt = 1; }
  99. }
  100. else if(48 >= sysclk)
  101. {
  102. delayMsCnt = sysclk * 111;
  103. delayUsCnt = sysclk / 9;
  104. }
  105. else
  106. {
  107. delayMsCnt = sysclk * 100;
  108. delayUsCnt = sysclk / 10;
  109. }
  110. return 0;
  111. }
  112. /**
  113. * @brief 输出各时钟频率信息
  114. * @param None
  115. * @retval None
  116. */
  117. void rcc_system_clock_debug(void)
  118. {
  119. RCC_ClocksTypeDef clock;
  120. RCC_GetClocksFreq(&clock);
  121. /*
  122. printf("SYSCLK:%dHz, HCLK:%dHz, PCLK1:%dHz, PCLK2:%dHz\r\n", clock.SYSCLK_Frequency, clock.HCLK_Frequency, clock.PCLK1_Frequency, clock.PCLK2_Frequency);
  123. */
  124. }
  125. /**
  126. * @brief ms延时(粗略)
  127. * @param ms : 延时时间ms
  128. * @retval None
  129. */
  130. void rcc_delay_ms(uint32_t ms)
  131. {
  132. volatile uint32_t cnt = 0;
  133. volatile uint32_t msCnt = ms;
  134. while(msCnt--)
  135. {
  136. cnt = delayMsCnt;
  137. while(cnt--);
  138. }
  139. }
  140. /**
  141. * @brief us延时(粗略)
  142. * @param us : 延时时间us
  143. * @retval None
  144. */
  145. void rcc_delay_us(uint32_t us)
  146. {
  147. volatile uint32_t usCnt = us * delayUsCnt;
  148. while(usCnt--);
  149. }