ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

STM32-时钟-时钟树-时钟初始化配置

2022-01-12 01:35:16  阅读:232  来源: 互联网

标签:初始化 HAL LATENCY FLASH 时钟 STM32 PLL RCC


1.STM32时钟

在这里插入图片描述

在这里插入图片描述

  • STM32有5个时钟源:HSI、HSE、LSI、LSE、PLL

  • HSI是高速内部时钟,RC振荡器,频率为16MHz,精度不高。可以直接作为系统时钟或者用作PLL时钟输入。

  • HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为4MHz~26MHz。

  • LSI是低速内部时钟,RC振荡器,频率为32kHz,提供低功耗时钟。主要供独立看门狗和自动唤醒单元使用。

  • LSE是低速外部时钟,接频率为32.768kHz的石英晶体。RTC

  • PLL为锁相环倍频输出。 STM32F4有三个PLL:

  • 主PLL(PLL)由HSE或者HSI提供时钟信号,并具有两个不同的输出时钟。

①第一个输出PLLP用于生成高速的系统时钟(最高180MHz)

②第二个输出PLLQ为48M时钟,用于USB OTG FS时钟,随机数发生器的时钟和SDIO时钟。

  • 第一个专用PLL(PLLI2S)生成精确时钟,在I2S和SAI1上实现高品质音频

    N是用于PLLI2S vco的倍频系数,其取值范围是:192~432;

    R是I2S时钟的分频系数,其取值范围是:2~7;

    Q是SAI时钟分频系数,其取值范围是:2~15;P没用到。

  • 第二个专用PLL(PLLSAI)同样用于生成精确时钟,用于SAI1输入时钟,同时还为LCD_TFT接口提供精确时钟。

    N是用于PLLSAI vco的倍频系数,其取值范围是:192~432;

    Q是SAI时钟分频系数,其取值范围是:2~15;

    R是LTDC时钟的分频系数,其取值范围是:2~7;P没用到。

  • PLLCLK=HSE*N/(M * P),可以通过改变N、M、P改变PLLCLK的频率

  • 系统时钟SYSCLK可来源于三个时钟源:

​ ①、HSI振荡器时钟

​ ②、HSE振荡器时钟

​ ③、PLL时钟

  • 任何外设在使用之前,必须使能相应的时钟

  • STM32F4时钟信号输出MCO1(PA8)和MCO2(PC9),MCO1:用户可以配置预分频器(1~ 5)向MCO1引脚PA8输出4个不同的时钟源:HIS、LSE、HSE、PLL。MCO2:用户可以配置预分频器(1~ 5)向MCO2引脚PC9输出4个不同的时钟源:HSE、PLL、SYSCLK、PLLI2S 。MCO最大输出时钟不超过100MHz。

  • RCC时钟控制相关寄存器定义在stm32f429xx.h中。结构体: RCC_TypeDef;RCC时钟相关定义和函数在文件stm32f4xx_hal_rcc.h、stm32f4xx_hal_rcc.c 。

2.Stm32_Clock_Init

在CORE-startup_stm32f429xx.s文件中找到Reset_Handler,这一部分代码作用是引导程序,可以看到先执行SystemInit函数再执行main。

; Reset handler
Reset_Handler    PROC
                 EXPORT  Reset_Handler             [WEAK]
        IMPORT  SystemInit
        IMPORT  __main

                 LDR     R0, =SystemInit
                 BLX     R0
                 LDR     R0, =__main
                 BX      R0
                 ENDP
    
; Dummy Exception Handlers (infinite loops which can be modified)

可以在USER-system_stm32f7xx.c文件中找到SystemInit函数。其中/* Set HSION bit */可以看出系统初始化之后默认使用HSI作为系统时钟来源,因为不知道外部时钟是否准备好。

void SystemInit(void)
{
  /* FPU settings ------------------------------------------------------------*/
  #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
    SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */
  #endif
  /* Reset the RCC clock configuration to the default reset state ------------*/
  /* Set HSION bit */
  RCC->CR |= (uint32_t)0x00000001;

  /* Reset CFGR register */
  RCC->CFGR = 0x00000000;

  /* Reset HSEON, CSSON and PLLON bits */
  RCC->CR &= (uint32_t)0xFEF6FFFF;

  /* Reset PLLCFGR register */
  RCC->PLLCFGR = 0x24003010;

  /* Reset HSEBYP bit */
  RCC->CR &= (uint32_t)0xFFFBFFFF;

  /* Disable all interrupts */
  RCC->CIR = 0x00000000;

  /* Configure the Vector Table location add offset address ------------------*/
#ifdef VECT_TAB_SRAM
  SCB->VTOR = RAMDTCM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
#else
  SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
#endif
}

时钟配置一般步骤:

  • 使能PWR时钟:调用函数 _HAL_RCC_PWR_CLK_ENABLE()。
  • 设置调压器输出电压级别:调用函数 _HAL_PWR_VOLTAGESCALING_CONFIG()。
  • 选择是否开启Over-Driver功能:调用函数HAL_PWREx_EnableOverDrive()。
  • 配置时钟源相关参数:调用函数HAL_RCC_OscConfig()。
  • 配置系统时钟源以及AHB,APB1和APB2的分频系数:调用函数HAL_RCC_ClockConfig()。

在STSTEM-sys.c文件中找到Stm32_Clock_Init函数:

//时钟设置函数
//Fvco=Fs*(plln/pllm);
//Fsys=Fvco/pllp=Fs*(plln/(pllm*pllp));
//Fusb=Fvco/pllq=Fs*(plln/(pllm*pllq));

//Fvco:VCO频率
//Fsys:系统时钟频率
//Fusb:USB,SDIO,RNG等的时钟频率
//Fs:PLL输入时钟频率,可以是HSI,HSE等. 
//plln:主PLL倍频系数(PLL倍频),取值范围:64~432.
//pllm:主PLL和音频PLL分频系数(PLL之前的分频),取值范围:2~63.
//pllp:系统时钟的主PLL分频系数(PLL之后的分频),取值范围:2,4,6,8.(仅限这4个值!)
//pllq:USB/SDIO/随机数产生器等的主PLL分频系数(PLL之后的分频),取值范围:2~15.

//外部晶振为25M的时候,推荐值:plln=432,pllm=25,pllp=2,pllq=9.
//得到:Fvco=25*(432/25)=432Mhz
//     Fsys=432/2=216Mhz
//     Fusb=432/9=48Mhz
//返回值:0,成功;1,失败
void Stm32_Clock_Init(u32 plln,u32 pllm,u32 pllp,u32 pllq)
{
    HAL_StatusTypeDef ret = HAL_OK;
    RCC_OscInitTypeDef RCC_OscInitStructure; 
    RCC_ClkInitTypeDef RCC_ClkInitStructure;
	
    __HAL_RCC_PWR_CLK_ENABLE(); //使能PWR时钟
 
    __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);//设置调压器输出电压级别,以便在器件未以最大频率工作
      
    RCC_OscInitStructure.OscillatorType=RCC_OSCILLATORTYPE_HSE;    //时钟源为HSE
    RCC_OscInitStructure.HSEState=RCC_HSE_ON;                      //打开HSE
    RCC_OscInitStructure.PLL.PLLState=RCC_PLL_ON;				   //打开PLL
    RCC_OscInitStructure.PLL.PLLSource=RCC_PLLSOURCE_HSE;          //PLL时钟源选择HSE
    RCC_OscInitStructure.PLL.PLLM=pllm;	//主PLL和音频PLL分频系数(PLL之前的分频)
    RCC_OscInitStructure.PLL.PLLN=plln; //主PLL倍频系数(PLL倍频)
    RCC_OscInitStructure.PLL.PLLP=pllp; //系统时钟的主PLL分频系数(PLL之后的分频)
    RCC_OscInitStructure.PLL.PLLQ=pllq; //USB/SDIO/随机数产生器等的主PLL分频系数(PLL之后的分频)
    ret=HAL_RCC_OscConfig(&RCC_OscInitStructure);//初始化
    if(ret!=HAL_OK) while(1);
    
    ret=HAL_PWREx_EnableOverDrive(); //开启Over-Driver功能
    if(ret!=HAL_OK) while(1);
    
    //选中PLL作为系统时钟源并且配置HCLK,PCLK1和PCLK2
    RCC_ClkInitStructure.ClockType=(RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2);
    RCC_ClkInitStructure.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK;//设置系统时钟时钟源为PLL
    RCC_ClkInitStructure.AHBCLKDivider=RCC_SYSCLK_DIV1;//AHB分频系数为1
    RCC_ClkInitStructure.APB1CLKDivider=RCC_HCLK_DIV4;//APB1分频系数为4
    RCC_ClkInitStructure.APB2CLKDivider=RCC_HCLK_DIV2;//APB2分频系数为2
    
    ret=HAL_RCC_ClockConfig(&RCC_ClkInitStructure,FLASH_LATENCY_7);//同时设置FLASH延时周期为7WS,也就是8个CPU周期。
    if(ret!=HAL_OK) while(1);
}

对于 __HAL_RCC_PWR_CLK_ENABLE();可以在stm32fxx_hal_rcc.h中找到:

#define __HAL_RCC_PWR_CLK_ENABLE()   do { \
                                        __IO uint32_t tmpreg; \
                                        SET_BIT(RCC->APB1ENR, RCC_APB1ENR_PWREN);\
                                        /* Delay after an RCC peripheral clock enabling */ \
                                        tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_PWREN);\
                                        UNUSED(tmpreg); \
                                      } while(0)	

因为后面设置调压器输出电压级别和选择是否开启Over-Driver功能要用到PWR时钟,所以先使能PWR时钟。

对于以下两函数头文件,都位于HALLIB-stm32f7xx_hal_rcc.h文件中

  • 配置时钟源相关参数:调用函数HAL_RCC_OscConfig()。
  • 配置系统时钟源以及AHB,APB1和APB2的分频系数:调用函数HAL_RCC_ClockConfig()。
HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct);
HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t FLatency);

HAL_RCC_OscConfig函数配置时钟源相关参数

选中RCC_OscInitTypeDef找到它的定义:

首先根据TYPE判断操作的是哪个时钟源,然后再对相应的时钟源配置。

typedef struct
{
  uint32_t OscillatorType;       /*!< The oscillators to be configured.
                                      This parameter can be a value of @ref RCC_Oscillator_Type                   */

  uint32_t HSEState;             /*!< The new state of the HSE.
                                      This parameter can be a value of @ref RCC_HSE_Config                        */

  uint32_t LSEState;             /*!< The new state of the LSE.
                                      This parameter can be a value of @ref RCC_LSE_Config                        */
                                          
  uint32_t HSIState;             /*!< The new state of the HSI.
                                      This parameter can be a value of @ref RCC_HSI_Config                        */

  uint32_t HSICalibrationValue;   /*!< The HSI calibration trimming value (default is RCC_HSICALIBRATION_DEFAULT).
                                       This parameter must be a number between Min_Data = 0x00 and Max_Data = 0x1F */
                               
  uint32_t LSIState;             /*!< The new state of the LSI.
                                      This parameter can be a value of @ref RCC_LSI_Config                        */

  RCC_PLLInitTypeDef PLL;        /*!< PLL structure parameters                                                    */      

}RCC_OscInitTypeDef;

其中的RCC_PLLInitTypeDef:可以看到里面有对PLL时钟源等一系列配置。

typedef struct
{
  uint32_t PLLState;   /*!< The new state of the PLL.
                            This parameter can be a value of @ref RCC_PLL_Config                      */

  uint32_t PLLSource;  /*!< RCC_PLLSource: PLL entry clock source.
                            This parameter must be a value of @ref RCC_PLL_Clock_Source               */           

  uint32_t PLLM;       /*!< PLLM: Division factor for PLL VCO input clock.
                            This parameter must be a number between Min_Data = 2 and Max_Data = 63    */        

  uint32_t PLLN;       /*!< PLLN: Multiplication factor for PLL VCO output clock.
                            This parameter must be a number between Min_Data = 50 and Max_Data = 432  */

  uint32_t PLLP;       /*!< PLLP: Division factor for main system clock (SYSCLK).
                            This parameter must be a value of @ref RCC_PLLP_Clock_Divider             */

  uint32_t PLLQ;       /*!< PLLQ: Division factor for OTG FS, SDMMC and RNG clocks.
                            This parameter must be a number between Min_Data = 2 and Max_Data = 15    */
#if defined (STM32F765xx) || defined (STM32F767xx) || defined (STM32F769xx) || defined (STM32F777xx) || defined (STM32F779xx)
  uint32_t PLLR;       /*!< PLLR: Division factor for DSI clock.
                            This parameter must be a number between Min_Data = 2 and Max_Data = 7    */
#endif /* STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx */  

}RCC_PLLInitTypeDef;   

调用HAL_RCC_OscConfig函数的方法如下:首先设置一下RCC_OscInitTypeDef类型的结构体。

    RCC_OscInitStructure.OscillatorType=RCC_OSCILLATORTYPE_HSE;    //时钟源为HSE
    RCC_OscInitStructure.HSEState=RCC_HSE_ON;                      //打开HSE
    RCC_OscInitStructure.PLL.PLLState=RCC_PLL_ON;				   //打开PLL
    RCC_OscInitStructure.PLL.PLLSource=RCC_PLLSOURCE_HSE;          //PLL时钟源选择HSE
    RCC_OscInitStructure.PLL.PLLM=pllm;	//主PLL和音频PLL分频系数(PLL之前的分频)
    RCC_OscInitStructure.PLL.PLLN=plln; //主PLL倍频系数(PLL倍频)
    RCC_OscInitStructure.PLL.PLLP=pllp; //系统时钟的主PLL分频系数(PLL之后的分频)
    RCC_OscInitStructure.PLL.PLLQ=pllq; //USB/SDIO/随机数产生器等的主PLL分频系数(PLL之后的分频)
    ret=HAL_RCC_OscConfig(&RCC_OscInitStructure);//初始化

如果要配置HSI:可以找到RCC_OSCILLATORTYPE_HSE的定义,然后发现如下代码块,在RCC_OscInitStructure.OscillatorType=RCC_OSCILLATORTYPE_HSE;代码中,将RCC_OSCILLATORTYPE_HSE修改成RCC_OSCILLATORTYPE_HSI即可。

#define RCC_OSCILLATORTYPE_NONE            ((uint32_t)0x00000000U)
#define RCC_OSCILLATORTYPE_HSE             ((uint32_t)0x00000001U)
#define RCC_OSCILLATORTYPE_HSI             ((uint32_t)0x00000002U)
#define RCC_OSCILLATORTYPE_LSE             ((uint32_t)0x00000004U)
#define RCC_OSCILLATORTYPE_LSI             ((uint32_t)0x00000008U)

同样的方法可以配置其他的成员变量。

可以理解main函数的Stm32_Clock_Init,可以找到:Stm32_Clock_Init(432,25,2,9); //设置时钟,216Mhz

然后找到Stm32_Clock_Init的定义,void Stm32_Clock_Init(u32 plln,u32 pllm,u32 pllp,u32 pllq)

由于外部晶振是25M,现在Stm32_Clock_Init第二个参数pllm是25,因此外部晶振是25M经过/M后,变成1。然后*n再/p最后得到216M 。

在这里插入图片描述

HAL_RCC_ClockConfig配置系统时钟源以及AHB,APB1和APB2的分频系数

然后再看一下HAL_RCC_ClockConfig函数,HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t FLatency)

对于第一个参数RCC_ClkInitTypeDef 在HALLIB-stm32f7xx_hal_rcc.h文件中可找到:

/**
  * @brief  RCC System, AHB and APB busses clock configuration structure definition  
  */
typedef struct
{
  uint32_t ClockType;             /*!< The clock to be configured.
                                       This parameter can be a value of @ref RCC_System_Clock_Type */
  
  uint32_t SYSCLKSource;          /*!< The clock source (SYSCLKS) used as system clock.
                                       This parameter can be a value of @ref RCC_System_Clock_Source    */

  uint32_t AHBCLKDivider;         /*!< The AHB clock (HCLK) divider. This clock is derived from the system clock (SYSCLK).
                                       This parameter can be a value of @ref RCC_AHB_Clock_Source       */

  uint32_t APB1CLKDivider;        /*!< The APB1 clock (PCLK1) divider. This clock is derived from the AHB clock (HCLK).
                                       This parameter can be a value of @ref RCC_APB1_APB2_Clock_Source */

  uint32_t APB2CLKDivider;        /*!< The APB2 clock (PCLK2) divider. This clock is derived from the AHB clock (HCLK).
                                       This parameter can be a value of @ref RCC_APB1_APB2_Clock_Source */

}RCC_ClkInitTypeDef;

对于第一个ClockType它可以选择哪些值:也可以在HALLIB-stm32f7xx_hal_rcc.h文件找到

#define RCC_CLOCKTYPE_SYSCLK             ((uint32_t)0x00000001U)
#define RCC_CLOCKTYPE_HCLK               ((uint32_t)0x00000002U)
#define RCC_CLOCKTYPE_PCLK1              ((uint32_t)0x00000004U)
#define RCC_CLOCKTYPE_PCLK2              ((uint32_t)0x00000008U)

对应于时钟系统:可以配置SYSCLK、HCLK、PCLK

在这里插入图片描述

SYSCLK、HCLK、PCLK都是占用不同的位,而且HAL_RCC_ClockConfig里面是用if进行判断而不是ifelse,所以可用或运算配置时钟。

//选中PLL作为系统时钟源并且配置HCLK,PCLK1和PCLK2
    RCC_ClkInitStructure.ClockType=(RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2);
    RCC_ClkInitStructure.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK;//设置系统时钟时钟源为PLL
    RCC_ClkInitStructure.AHBCLKDivider=RCC_SYSCLK_DIV1;//AHB分频系数为1
    RCC_ClkInitStructure.APB1CLKDivider=RCC_HCLK_DIV4;//APB1分频系数为4
    RCC_ClkInitStructure.APB2CLKDivider=RCC_HCLK_DIV2;//APB2分频系数为2
    
    ret=HAL_RCC_ClockConfig(&RCC_ClkInitStructure,FLASH_LATENCY_7);//同时设置FLASH延时周期为7WS,也就是8个CPU周期。

配置调压器输出级别:

__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);//设置调压器输出电压级别,以便在器件未以最大频率工作。

首先找到__HAL_PWR_VOLTAGESCALING_CONFIG的定义:可以发现是通过PWR->CR寄存器来配置的。

  • VOS[1:0] =“0x01”时,fHCLK 最大值为 144 MHz。

  • VOS[1:0] =“0x10”时,fHCLK 最大值为 168 MHz。激活过驱动模式可将其扩展到
    180 MHz。

  • VOS[1:0] =“0x11”时,fHCLK 最大值为 180 MHz。激活过驱动模式可将其扩展到
    216 MHz。

#define __HAL_PWR_VOLTAGESCALING_CONFIG(__REGULATOR__) do {                                                     \
                                                            __IO uint32_t tmpreg;                               \
                                                            MODIFY_REG(PWR->CR1, PWR_CR1_VOS, (__REGULATOR__)); \
                                                            /* Delay after an RCC peripheral clock enabling */  \
                                                            tmpreg = READ_BIT(PWR->CR1, PWR_CR1_VOS);           \
                                                            UNUSED(tmpreg);                                     \
				                                                	} while(0)

对于__HAL_PWR_VOLTAGESCALING_CONFIG的参数,可以找到:

#define PWR_REGULATOR_VOLTAGE_SCALE1         PWR_CR1_VOS
#define PWR_REGULATOR_VOLTAGE_SCALE2         PWR_CR1_VOS_1
#define PWR_REGULATOR_VOLTAGE_SCALE3         PWR_CR1_VOS_0

通过 ret=HAL_PWREx_EnableOverDrive(); //可以开启Over-Driver功能

配置FLASH等待周期

HAL_RCC_ClockConfig还有一个参数uint32_t FLatency,可以找到:

/** @defgroup FLASH_Latency FLASH Latency
  * @{
  */
#define FLASH_LATENCY_0                FLASH_ACR_LATENCY_0WS   /*!< FLASH Zero Latency cycle      */
#define FLASH_LATENCY_1                FLASH_ACR_LATENCY_1WS   /*!< FLASH One Latency cycle       */
#define FLASH_LATENCY_2                FLASH_ACR_LATENCY_2WS   /*!< FLASH Two Latency cycles      */
#define FLASH_LATENCY_3                FLASH_ACR_LATENCY_3WS   /*!< FLASH Three Latency cycles    */
#define FLASH_LATENCY_4                FLASH_ACR_LATENCY_4WS   /*!< FLASH Four Latency cycles     */
#define FLASH_LATENCY_5                FLASH_ACR_LATENCY_5WS   /*!< FLASH Five Latency cycles     */
#define FLASH_LATENCY_6                FLASH_ACR_LATENCY_6WS   /*!< FLASH Six Latency cycles      */
#define FLASH_LATENCY_7                FLASH_ACR_LATENCY_7WS   /*!< FLASH Seven Latency cycles    */
#define FLASH_LATENCY_8                FLASH_ACR_LATENCY_8WS   /*!< FLASH Eight Latency cycles    */
#define FLASH_LATENCY_9                FLASH_ACR_LATENCY_9WS   /*!< FLASH Nine Latency cycles     */
#define FLASH_LATENCY_10               FLASH_ACR_LATENCY_10WS  /*!< FLASH Ten Latency cycles      */
#define FLASH_LATENCY_11               FLASH_ACR_LATENCY_11WS  /*!< FLASH Eleven Latency cycles   */
#define FLASH_LATENCY_12               FLASH_ACR_LATENCY_12WS  /*!< FLASH Twelve Latency cycles   */
#define FLASH_LATENCY_13               FLASH_ACR_LATENCY_13WS  /*!< FLASH Thirteen Latency cycles */
#define FLASH_LATENCY_14               FLASH_ACR_LATENCY_14WS  /*!< FLASH Fourteen Latency cycles */
#define FLASH_LATENCY_15               FLASH_ACR_LATENCY_15WS  /*!< FLASH Fifteen Latency cycles  */
/**
  * @}
  */

CPU 时钟 (HCLK) 频率对应的等待周期数是通过一张表对应的:

在这里插入图片描述

然后就可以写:ret=HAL_RCC_ClockConfig(&RCC_ClkInitStructure,FLASH_LATENCY_7);//同时设置FLASH延时周期为7WS,也就是8个CPU周期。

标签:初始化,HAL,LATENCY,FLASH,时钟,STM32,PLL,RCC
来源: https://www.cnblogs.com/jiangyiming/p/15790850.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有