#include "SN_RCC.h" /* 文件名:SN_RCC.c/.h 作者: SN_FAE_黄泽洪 免责声明:无版权,可随意传播和篡改,该代码仅供开发参考,如需使用请自行验证 本人不担负商业使用上带来的风险。 */ /* SN_RCC模块使用方法: int main(){ //配置系统时钟 SN_SYSCLK_set(SYSCLK_16MHZ); //通过PB1输出系统时钟信号 SN_CLK_MOC( MOC_PB1_OUT,RCC_MCO_SRC_SYSCLK, RCC_MCO_DIV1); while(1); } */ /* 函数名称 void SN_SYSCLK_set(uint8_t SYSCLK_from) 功能:设置系统时钟频率 (未调用该函数时,MCU上电默认时8M) 参数: 系统时钟频率 SYSCLK_from @SYSCLK_8MHZ 功耗RUN 0.9ma 所有外设时钟 OFF @SYSCLK_16MHZ 功耗RUN 0.94ma 所有外设时钟 OFF @SYSCLK_48MHZ 功耗RUN 1.52ma 所有外设时钟 OFF 功耗RUN2.12ma 所有外设时钟 ON @SYSCLK_32KHZ 功耗RUN 返回:无 */ void SN_SYSCLK_set(uint32_t SYSCLK_from){ /* 设置Flash读访问等待时间 */ if(SYSCLK_from != SYSCLK_48MHZ){ std_flash_set_latency(FLASH_LATENCY_0CLK); }else{ std_flash_set_latency(FLASH_LATENCY_1CLK); } if(SYSCLK_from != SYSCLK_32KHZ){ /* 使能RCH */ std_rcc_rch_enable(); while(std_rcc_get_rch_ready() != RCC_CSR1_RCHRDY); if(SYSCLK_from == SYSCLK_8MHZ){ /* 设置系统时钟源为RCH/6 */ std_rcc_set_sysclk_source(SYSCLK_8MHZ); while(std_rcc_get_sysclk_source() != RCC_SYSCLK_SRC_STATUS_RCHDIV6); SystemCoreClock = RCH_VALUE/6; } if(SYSCLK_from == SYSCLK_16MHZ){ /* 设置系统时钟源为RCH/3 */ std_rcc_set_sysclk_source(SYSCLK_16MHZ); while(std_rcc_get_sysclk_source() != RCC_SYSCLK_SRC_STATUS_RCHDIV3); SystemCoreClock = RCH_VALUE/3; } if(SYSCLK_from == SYSCLK_48MHZ){ /* 设置系统时钟源为RCH/1 */ std_rcc_set_sysclk_source(RCC_SYSCLK_SRC_RCH); while(std_rcc_get_sysclk_source() != RCC_SYSCLK_SRC_STATUS_RCH); SystemCoreClock = RCH_VALUE; } }else if(SYSCLK_from == SYSCLK_32KHZ){ /* 使能RCL */ std_rcc_rcl_enable(); while(std_rcc_get_rcl_ready() != RCC_CSR2_RCLRDY); /* 设置系统时钟源为RCK 32KHZ */ std_rcc_set_sysclk_source(RCC_SYSCLK_SRC_RCL); while(std_rcc_get_sysclk_source() != RCC_SYSCLK_SRC_STATUS_RCL); SystemCoreClock = RCL_VALUE; } /* 设置AHB分频因子 */ std_rcc_set_ahbdiv(RCC_HCLK_DIV1); /* 设置APB分频因子 */ std_rcc_set_apbdiv(RCC_PCLK_DIV1); /* 配置系统时钟全局变量 */ } /* 函数 SN_CLK_MOC(uint32_t x) 功能: MOC引脚输出时钟信号 (用于验证时钟设置是否正确,或是输出时钟信号驱动其他设备和ic) 参数:输出时钟信号引脚 @MOC_PA7_OUT @MOC_PB1_OUT @MOC_PB6_OUT (注意:PB6是仿真引脚,在线仿真时不要使用这个引脚) 参数:时钟源选择 @RCC_MCO_SRC_SYSCLK MCO选择SYSCLK输出 @RCC_MCO_SRC_RCHDIV6 MCO选择RCHDIV6输出 @RCC_MCO_SRC_EXTCLK MCO选择EXTCLK输出 (外部有源时钟源很贵,如果使用003做主控,这个没有意义) @RCC_MCO_SRC_RCL MCO选择RCL输出 参数:输出信号分频 @RCC_MCO_DIV1 MCO不分频 @RCC_MCO_DIV2 MCO分频因子 = 2 @RCC_MCO_DIV4 MCO分频因子 = 4 @RCC_MCO_DIV8 MCO分频因子 = 8 @RCC_MCO_DIV16 MCO分频因子 = 16 @RCC_MCO_DIV32 MCO分频因子 = 32 @RCC_MCO_DIV64 MCO分频因子 = 64 @RCC_MCO_DIV128 MCO分频因子 = 128 返回: 无 注意:如果没有开启对的时钟源,是没有信号输出的。 */ void SN_CLK_MOC(uint32_t PIN_X , uint32_t RCC_MCO_SRC, uint32_t RCC_MCO_DIV_x){ GPIO_t * GPIO_X = NULL; uint16_t GPIO_PIN_x = 0; uint32_t RCC_PERIPH_CLK_GPIO_x = 0; uint8_t GPIO_AFx_MCO = 0; //设置IO口 GPIO_X = (PIN_X == 1) ? GPIOA : GPIOB ; //选择io端口 GPIO_PIN_x = (PIN_X == 1) ? (GPIO_PIN_7 ): ((PIN_X == 2) ? GPIO_PIN_1 : GPIO_PIN_6); //选择io引脚 RCC_PERIPH_CLK_GPIO_x = (PIN_X == 1) ? RCC_PERIPH_CLK_GPIOA :RCC_PERIPH_CLK_GPIOB; //设置io时钟 GPIO_AFx_MCO = (PIN_X != 3) ? GPIO_AF6_MCO : GPIO_AF7_MCO; //复用选择项 std_gpio_init_t mco_gpio_cfg = {0}; /* 配置PIN_X作为MCO输出引脚 */ std_rcc_gpio_clk_enable(RCC_PERIPH_CLK_GPIO_x); mco_gpio_cfg.pin = GPIO_PIN_x; mco_gpio_cfg.mode = GPIO_MODE_ALTERNATE; mco_gpio_cfg.pull = GPIO_NOPULL; mco_gpio_cfg.alternate = GPIO_AFx_MCO; std_gpio_init(GPIO_X, &mco_gpio_cfg); //设置时钟输出源 /* 使能MCO输出,系统时钟 16分频 */ std_rcc_mco_config(RCC_MCO_SRC, RCC_MCO_DIV_x); }