123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 |
- #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);
- }
-
-
-
-
-
-
-
|