SN_RCC.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. #include "SN_RCC.h"
  2. /*
  3. 文件名:SN_RCC.c/.h
  4. 作者: SN_FAE_黄泽洪
  5. 免责声明:无版权,可随意传播和篡改,该代码仅供开发参考,如需使用请自行验证
  6. 本人不担负商业使用上带来的风险。
  7. */
  8. /*
  9. SN_RCC模块使用方法:
  10. int main(){
  11. //配置系统时钟
  12. SN_SYSCLK_set(SYSCLK_16MHZ);
  13. //通过PB1输出系统时钟信号
  14. SN_CLK_MOC( MOC_PB1_OUT,RCC_MCO_SRC_SYSCLK, RCC_MCO_DIV1);
  15. while(1);
  16. }
  17. */
  18. /*
  19. 函数名称 void SN_SYSCLK_set(uint8_t SYSCLK_from)
  20. 功能:设置系统时钟频率 (未调用该函数时,MCU上电默认时8M)
  21. 参数: 系统时钟频率 SYSCLK_from
  22. @SYSCLK_8MHZ 功耗RUN 0.9ma 所有外设时钟 OFF
  23. @SYSCLK_16MHZ 功耗RUN 0.94ma 所有外设时钟 OFF
  24. @SYSCLK_48MHZ 功耗RUN 1.52ma 所有外设时钟 OFF 功耗RUN2.12ma 所有外设时钟 ON
  25. @SYSCLK_32KHZ 功耗RUN
  26. 返回:无
  27. */
  28. void SN_SYSCLK_set(uint32_t SYSCLK_from){
  29. /* 设置Flash读访问等待时间 */
  30. if(SYSCLK_from != SYSCLK_48MHZ){
  31. std_flash_set_latency(FLASH_LATENCY_0CLK);
  32. }else{
  33. std_flash_set_latency(FLASH_LATENCY_1CLK);
  34. }
  35. if(SYSCLK_from != SYSCLK_32KHZ){
  36. /* 使能RCH */
  37. std_rcc_rch_enable();
  38. while(std_rcc_get_rch_ready() != RCC_CSR1_RCHRDY);
  39. if(SYSCLK_from == SYSCLK_8MHZ){
  40. /* 设置系统时钟源为RCH/6 */
  41. std_rcc_set_sysclk_source(SYSCLK_8MHZ);
  42. while(std_rcc_get_sysclk_source() != RCC_SYSCLK_SRC_STATUS_RCHDIV6);
  43. SystemCoreClock = RCH_VALUE/6;
  44. }
  45. if(SYSCLK_from == SYSCLK_16MHZ){
  46. /* 设置系统时钟源为RCH/3 */
  47. std_rcc_set_sysclk_source(SYSCLK_16MHZ);
  48. while(std_rcc_get_sysclk_source() != RCC_SYSCLK_SRC_STATUS_RCHDIV3);
  49. SystemCoreClock = RCH_VALUE/3;
  50. }
  51. if(SYSCLK_from == SYSCLK_48MHZ){
  52. /* 设置系统时钟源为RCH/1 */
  53. std_rcc_set_sysclk_source(RCC_SYSCLK_SRC_RCH);
  54. while(std_rcc_get_sysclk_source() != RCC_SYSCLK_SRC_STATUS_RCH);
  55. SystemCoreClock = RCH_VALUE;
  56. }
  57. }else if(SYSCLK_from == SYSCLK_32KHZ){
  58. /* 使能RCL */
  59. std_rcc_rcl_enable();
  60. while(std_rcc_get_rcl_ready() != RCC_CSR2_RCLRDY);
  61. /* 设置系统时钟源为RCK 32KHZ */
  62. std_rcc_set_sysclk_source(RCC_SYSCLK_SRC_RCL);
  63. while(std_rcc_get_sysclk_source() != RCC_SYSCLK_SRC_STATUS_RCL);
  64. SystemCoreClock = RCL_VALUE;
  65. }
  66. /* 设置AHB分频因子 */
  67. std_rcc_set_ahbdiv(RCC_HCLK_DIV1);
  68. /* 设置APB分频因子 */
  69. std_rcc_set_apbdiv(RCC_PCLK_DIV1);
  70. /* 配置系统时钟全局变量 */
  71. }
  72. /*
  73. 函数 SN_CLK_MOC(uint32_t x)
  74. 功能: MOC引脚输出时钟信号
  75. (用于验证时钟设置是否正确,或是输出时钟信号驱动其他设备和ic)
  76. 参数:输出时钟信号引脚
  77. @MOC_PA7_OUT
  78. @MOC_PB1_OUT
  79. @MOC_PB6_OUT (注意:PB6是仿真引脚,在线仿真时不要使用这个引脚)
  80. 参数:时钟源选择
  81. @RCC_MCO_SRC_SYSCLK MCO选择SYSCLK输出
  82. @RCC_MCO_SRC_RCHDIV6 MCO选择RCHDIV6输出
  83. @RCC_MCO_SRC_EXTCLK MCO选择EXTCLK输出 (外部有源时钟源很贵,如果使用003做主控,这个没有意义)
  84. @RCC_MCO_SRC_RCL MCO选择RCL输出
  85. 参数:输出信号分频
  86. @RCC_MCO_DIV1 MCO不分频
  87. @RCC_MCO_DIV2 MCO分频因子 = 2
  88. @RCC_MCO_DIV4 MCO分频因子 = 4
  89. @RCC_MCO_DIV8 MCO分频因子 = 8
  90. @RCC_MCO_DIV16 MCO分频因子 = 16
  91. @RCC_MCO_DIV32 MCO分频因子 = 32
  92. @RCC_MCO_DIV64 MCO分频因子 = 64
  93. @RCC_MCO_DIV128 MCO分频因子 = 128
  94. 返回: 无
  95. 注意:如果没有开启对的时钟源,是没有信号输出的。
  96. */
  97. void SN_CLK_MOC(uint32_t PIN_X , uint32_t RCC_MCO_SRC, uint32_t RCC_MCO_DIV_x){
  98. GPIO_t * GPIO_X = NULL;
  99. uint16_t GPIO_PIN_x = 0;
  100. uint32_t RCC_PERIPH_CLK_GPIO_x = 0;
  101. uint8_t GPIO_AFx_MCO = 0;
  102. //设置IO口
  103. GPIO_X = (PIN_X == 1) ? GPIOA : GPIOB ; //选择io端口
  104. GPIO_PIN_x = (PIN_X == 1) ? (GPIO_PIN_7 ): ((PIN_X == 2) ? GPIO_PIN_1 : GPIO_PIN_6); //选择io引脚
  105. RCC_PERIPH_CLK_GPIO_x = (PIN_X == 1) ? RCC_PERIPH_CLK_GPIOA :RCC_PERIPH_CLK_GPIOB; //设置io时钟
  106. GPIO_AFx_MCO = (PIN_X != 3) ? GPIO_AF6_MCO : GPIO_AF7_MCO; //复用选择项
  107. std_gpio_init_t mco_gpio_cfg = {0};
  108. /* 配置PIN_X作为MCO输出引脚 */
  109. std_rcc_gpio_clk_enable(RCC_PERIPH_CLK_GPIO_x);
  110. mco_gpio_cfg.pin = GPIO_PIN_x;
  111. mco_gpio_cfg.mode = GPIO_MODE_ALTERNATE;
  112. mco_gpio_cfg.pull = GPIO_NOPULL;
  113. mco_gpio_cfg.alternate = GPIO_AFx_MCO;
  114. std_gpio_init(GPIO_X, &mco_gpio_cfg);
  115. //设置时钟输出源
  116. /* 使能MCO输出,系统时钟 16分频 */
  117. std_rcc_mco_config(RCC_MCO_SRC, RCC_MCO_DIV_x);
  118. }