简介
- 使用位域初始化RCC寄存器。
- 学习使用
CobeMX
生成代码。 - 使用RM0008.pdf创建自己的RCC寄存器。
- 初始化STM32时钟代替
CobeMX
生成的函数并运行查看RCC是否被正常初始化。
项目地址
实现
生成代码
- 使用
CobeMX
初始化代码
uVision
编写
-
创建自己的
RCC.h
-
参考文献可以看到
RCC
所有的寄存器,按照文献相应创建结构体,并设置位域。#ifndef __LkkRccInit_H_ #define __LkkRccInit_H_ #include "stm32f1xx_hal.h" typedef struct { uint32_t HSION : 1; uint32_t HSIRDY : 1; uint32_t RES0 : 1; uint32_t HSITRIM : 5; uint32_t HSICAL : 8; uint32_t HSEON : 1; uint32_t HSERDY : 1; uint32_t HSEBYP : 1; uint32_t CSSON : 1; uint32_t RES1 : 4; uint32_t PLLON : 1; uint32_t PLLRDY : 1; uint32_t RES2 : 6; }Rcc_CR; typedef struct { uint32_t SW : 2; uint32_t SWS : 2; uint32_t HPRE : 4; uint32_t PPRE1 : 3; uint32_t PPRE2 : 3; uint32_t ADCPRE : 2; uint32_t PLLSRC : 1; uint32_t PLLXTPRE : 1; uint32_t PLLMUL : 4; uint32_t USBPRE : 1; uint32_t RES0 : 1; uint32_t MCO : 3; uint32_t RES1 : 5; }Rcc_CFGR; typedef struct { uint32_t LSIRDYF : 1; uint32_t LSERDYF : 1; uint32_t HSIRDYF : 1; uint32_t HSERDYF : 1; uint32_t PLLRDYF : 1; uint32_t RES0 : 2; uint32_t CSSF : 1; uint32_t LSIRDYIE : 1; uint32_t LSERDYIE : 1; uint32_t HSIRDYIE : 1; uint32_t HSERDYIE : 1; uint32_t PLLRDYIE : 1; uint32_t RES1 : 3; uint32_t LSIRDYC : 1; uint32_t LSERDYC : 1; uint32_t HSIRDYC : 1; uint32_t HSERDYC : 1; uint32_t PLLRDYC : 1; uint32_t RES2 : 2; uint32_t CSSC : 1; uint32_t RES3 : 8; }Rcc_CIR; typedef struct { uint32_t AFIORST : 1; uint32_t RES0 : 1; uint32_t IOPARST : 1; uint32_t IOPBRST : 1; uint32_t IOPCRST : 1; uint32_t IOPDRST : 1; uint32_t IOPERST : 1; uint32_t IOPFRST : 1; uint32_t IOPGRST : 1; uint32_t ADC1RST : 1; uint32_t ADC2RST : 1; uint32_t TIM1RST : 1; uint32_t SPI1RST : 1; uint32_t TIM8RST : 1; uint32_t USART1RST : 1; uint32_t ADC3RST : 1; uint32_t RES1 : 3; uint32_t TIM9RST : 1; uint32_t TIM10RST : 1; uint32_t TIM11RST : 1; uint32_t RES2 : 10; }Rcc_APB2RSTR; typedef struct { uint32_t TIM2RST : 1; uint32_t TIM3RST : 1; uint32_t TIM4RST : 1; uint32_t TM5RST : 1; uint32_t TM6RST : 1; uint32_t TM7RST : 1; uint32_t TIM12RST : 1; uint32_t TIM13RST : 1; uint32_t TIM14RST : 1; uint32_t RES0 : 2; uint32_t WWDGRST : 1; uint32_t RES1 : 2; uint32_t SPI2RST : 1; uint32_t SPI3RST : 1; uint32_t RES2 : 1; uint32_t USART2RST : 1; uint32_t USART3RST : 1; uint32_t UART4RST : 1; uint32_t UART5RST : 1; uint32_t I2C1RST : 1; uint32_t I2C2RST : 1; uint32_t USBRST : 1; uint32_t RES3 : 1; uint32_t CANRST : 1; uint32_t RES4 : 1; uint32_t BKPRST : 1; uint32_t PWRRST : 1; uint32_t DACRST : 1; uint32_t RES5 : 2; }Rcc_APB1RSTR; typedef struct { uint32_t DMA1EN : 1; uint32_t DMA2EN : 1; uint32_t SRAMEN : 1; uint32_t RES0 : 1; uint32_t FLITFEN : 1; uint32_t RES1 : 1; uint32_t CRCEN : 1; uint32_t RES2 : 1; uint32_t FSMCEN : 1; uint32_t RES3 : 1; uint32_t SDIOEN : 1; uint32_t RES4 : 21; }Rcc_AHBENR; typedef struct { uint32_t AFIOEN : 1; uint32_t RES0 : 1; uint32_t IOPAEN : 1; uint32_t IOPBEN : 1; uint32_t IOPCEN : 1; uint32_t IOPDEN : 1; uint32_t IOPEEN : 1; uint32_t IOPFEN : 1; uint32_t IOPGEN : 1; uint32_t ADC1EN : 1; uint32_t ADC2EN : 1; uint32_t TIM1EN : 1; uint32_t SPI1EN : 1; uint32_t TIM8EN : 1; uint32_t USART1EN : 1; uint32_t ADC3EN : 1; uint32_t RES1 : 3; uint32_t TIM9EN : 1; uint32_t TIM10EN : 1; uint32_t TIM11EN : 1; uint32_t RES2 : 10; }Rcc_APB2ENR; typedef struct { uint32_t TIM2EN : 1; uint32_t TIM3EN : 1; uint32_t TIM4EN : 1; uint32_t TIM5EN : 1; uint32_t TIM6EN : 1; uint32_t TIM7EN : 1; uint32_t TIM12EN : 1; uint32_t TIM13EN : 1; uint32_t TIM14EN : 1; uint32_t RES0 : 2; uint32_t WWDGEN : 1; uint32_t RES1 : 2; uint32_t SPI2EN : 1; uint32_t SPI3EN : 1; uint32_t RES2 : 1; uint32_t USART2EN : 1; uint32_t USART3EN : 1; uint32_t UART4EN : 1; uint32_t UART5EN : 1; uint32_t I2C1EN : 1; uint32_t I2C2EN : 1; uint32_t USBEN : 1; uint32_t RES3 : 1; uint32_t CANEN : 1; uint32_t RES4 : 1; uint32_t BKPEN : 1; uint32_t PWREN : 1; uint32_t DACEN : 1; uint32_t RES5 : 2; }Rcc_APB1ENR; typedef struct { uint32_t LSEON : 1; uint32_t LSERDY : 1; uint32_t LSEBYP : 1; uint32_t RES0 : 5; uint32_t RTCSEL : 2; uint32_t RES1 : 5; uint32_t RTCEN : 1; uint32_t BDRST : 1; uint32_t RES2 : 15; }Rcc_BDCR; typedef struct{ uint32_t LSION:1; uint32_t LSIRDY:1; uint32_t RES0:22; uint32_t RMVF:1; uint32_t RES1:1; uint32_t PINRSTF:1; uint32_t PORRSTF:1; uint32_t SFTRSTF:1; uint32_t IWDGRSTF:1; uint32_t WWDGRSTF:1; uint32_t LPWRRSTF:1; }Rcc_CSR; typedef struct { Rcc_CR rcc_CR; Rcc_CFGR rcc_CFGR; Rcc_CIR rcc_CIR; Rcc_APB2RSTR rcc_APB2RSTR; Rcc_APB1RSTR rcc_APB1RSTR; Rcc_AHBENR rcc_AHBENR; Rcc_APB2ENR rcc_APB2ENR; Rcc_APB1ENR rcc_APB1ENR; Rcc_BDCR rcc_BDCR; Rcc_CSR rcc_CSR; }Lkk_Rcc; typedef struct { uint32_t LPDS : 1; uint32_t PDDS : 1; uint32_t CWUF : 1; uint32_t CSBF : 1; uint32_t PVDE : 1; uint32_t PLS : 3; uint32_t DBP : 1; uint32_t RES0 : 23; }Pwr_CR; typedef struct { uint32_t WUF : 1; uint32_t SBF : 1; uint32_t PVDO : 1; uint32_t RES0 : 5; uint32_t EWUP : 1; uint32_t RES1 : 23; }Pwr_CSR; typedef struct { Pwr_CR pwr_CR; Pwr_CSR pwr_CSR; }Lkk_Pwr; typedef struct { uint32_t LATENCY : 3; uint32_t HLFCYA : 1; uint32_t PRFTBE : 1; uint32_t PRFTBS : 1; uint32_t RES0 : 26; }Lkk_FLASH_ACR; typedef struct { Lkk_FLASH_ACR lkk_flash_ACR; }Lkk_FLASH; #endif /* __My_RCC_H_ */
-
-
编写
RCC.c
初始化RCC
- 为
RCC
分配地址
Lkk_Rcc *lkk_Rcc = (Lkk_Rcc *) 0x40021000UL; Lkk_FLASH *lkk_FlASH = (Lkk_FLASH *) 0x40022000UL; Lkk_Pwr *lkk_PWR = (Lkk_Pwr*)0x40007000UL;
这里也初始化了
FLASH
和PWR
,因为通过调试发现RCC
初始化时也会涉及到他俩。地址可以参考我上传的RM0008.pdf的第50页(
Memory Map
)。- 开启时钟,我选择的是
HSI
,与CobeMX
的时钟树相对应
/** Rcc_CR init **/ lkk_Rcc->rcc_CR.HSION = 0x1; //open HSI lkk_Rcc->rcc_CR.HSIRDY = 0x1;//ready HSI lkk_Rcc->rcc_CR.HSITRIM = 0x10;//HSI adjustment lkk_Rcc->rcc_CR.HSICAL = 0x0;//HSI correcting
-
关闭
HSE
//close HSE lkk_Rcc->rcc_CR.HSEON = 0x0; lkk_Rcc->rcc_CR.HSERDY = 0x0; lkk_Rcc->rcc_CR.HSEBYP = 0x0; lkk_Rcc->rcc_CR.CSSON = 0x0;
-
关闭
PLL
初始化PLLMUL
/** PLL frequency doubling coefficient The PLL frequency doubling coefficient is determined by software settings. It can only be written when PLL is off **/ lkk_Rcc->rcc_CR.PLLON = 0x0; lkk_Rcc->rcc_CFGR.PLLMUL = 0x0E;
-
初始化
RCC_CFGR
/** Rcc_CFGR init **/ lkk_Rcc->rcc_CFGR.SW = 0x02; //System clock switching lkk_Rcc->rcc_CFGR.SWS = 0x02; lkk_Rcc->rcc_CFGR.HPRE = 0x0; //AHB Prescaler lkk_Rcc->rcc_CFGR.PPRE1 = 0x04; //APB1 Prescaler lkk_Rcc->rcc_CFGR.PPRE2 = 0x0; //APB2 Prescaler lkk_Rcc->rcc_CFGR.ADCPRE = 0x0; //ADC Prescaler lkk_Rcc->rcc_CFGR.PLLSRC = 0x0; //PLL input clock source lkk_Rcc->rcc_CFGR.MCO = 0x0; //MCO microcontroller clock output : None
-
初始化
RCC_AHBENR
//Rcc_AHBENR init lkk_Rcc->rcc_AHBENR.SRAMEN = 0x1; //SRAM clock enable
-
初始化
FLASH
/** FLASH **/ lkk_FlASH->lkk_flash_ACR.LATENCY = 0x02; lkk_FlASH->lkk_flash_ACR.PRFTBE = 0x0; lkk_Rcc->rcc_AHBENR.FLITFEN = 0x1; //Flash memory interface circuit clock enable
-
初始化
RCC_APB2ENR
//Rcc_APB2ENR init lkk_Rcc->rcc_APB2ENR.AFIOEN = 0x1; //Auxiliary function IO clock enable lkk_Rcc->rcc_APB2ENR.IOPAEN = 0x1; //IO port a clock enable lkk_Rcc->rcc_APB2ENR.IOPCEN = 0x1; //IO port c clock enable lkk_Rcc->rcc_APB2ENR.IOPDEN = 0x1; //IO port d clock enable
-
初始化
RCC_APB1ENR
lkk_Rcc->rcc_APB1ENR.PWREN = 0x1;
-
初始化
RCC_BDCR
//Rcc_BDCR init lkk_Rcc->rcc_BDCR.RTCSEL = 0x0;
-
初始化
RCC_CSR
//Rcc_CSR init lkk_Rcc->rcc_CSR.PINRSTF = 0x1; lkk_Rcc->rcc_CSR.PORRSTF = 0x1; lkk_Rcc->rcc_CR.PLLON = 0x1; //初始化了RLLMUL后再打开!!! //原理见RM0008.pdf的第102页
-
初始化
PWR
//PWR lkk_PWR->pwr_CR.PLS = 0x00;
-
完整初始化函数
#include "LkkRccInit.h" void Lkk_Clock_Config(void){ Lkk_Rcc *lkk_Rcc = (Lkk_Rcc *) 0x40021000UL; Lkk_FLASH *lkk_FlASH = (Lkk_FLASH *) 0x40022000UL; Lkk_Pwr *lkk_PWR = (Lkk_Pwr*)0x40007000UL; /** Rcc_CR init **/ lkk_Rcc->rcc_CR.HSION = 0x1; //open HSI lkk_Rcc->rcc_CR.HSIRDY = 0x1;//ready HSI lkk_Rcc->rcc_CR.HSITRIM = 0x10;//HSI adjustment lkk_Rcc->rcc_CR.HSICAL = 0x0;//HSI correcting //close HSE lkk_Rcc->rcc_CR.HSEON = 0x0; lkk_Rcc->rcc_CR.HSERDY = 0x0; lkk_Rcc->rcc_CR.HSEBYP = 0x0; lkk_Rcc->rcc_CR.CSSON = 0x0; /** PLL frequency doubling coefficient The PLL frequency doubling coefficient is determined by software settings. It can only be written when PLL is off **/ lkk_Rcc->rcc_CR.PLLON = 0x0; lkk_Rcc->rcc_CFGR.PLLMUL = 0x0E; /** Rcc_CFGR init **/ lkk_Rcc->rcc_CFGR.SW = 0x02; //System clock switching lkk_Rcc->rcc_CFGR.SWS = 0x02; lkk_Rcc->rcc_CFGR.HPRE = 0x0; //AHB Prescaler lkk_Rcc->rcc_CFGR.PPRE1 = 0x04; //APB1 Prescaler lkk_Rcc->rcc_CFGR.PPRE2 = 0x0; //APB2 Prescaler lkk_Rcc->rcc_CFGR.ADCPRE = 0x0; //ADC Prescaler lkk_Rcc->rcc_CFGR.PLLSRC = 0x0; //PLL input clock source lkk_Rcc->rcc_CFGR.MCO = 0x0; //MCO microcontroller clock output : None //Rcc_AHBENR init lkk_Rcc->rcc_AHBENR.SRAMEN = 0x1; //SRAM clock enable /** FLASH **/ lkk_FlASH->lkk_flash_ACR.LATENCY = 0x02; lkk_FlASH->lkk_flash_ACR.PRFTBE = 0x0; lkk_Rcc->rcc_AHBENR.FLITFEN = 0x1; //Flash memory interface circuit clock enable //Rcc_APB2ENR init lkk_Rcc->rcc_APB2ENR.AFIOEN = 0x1; //Auxiliary function IO clock enable lkk_Rcc->rcc_APB2ENR.IOPAEN = 0x1; //IO port a clock enable lkk_Rcc->rcc_APB2ENR.IOPCEN = 0x1; //IO port c clock enable lkk_Rcc->rcc_APB2ENR.IOPDEN = 0x1; //IO port d clock enable //Rcc_APB1ENR init lkk_Rcc->rcc_APB1ENR.PWREN = 0x1; //Rcc_BDCR init lkk_Rcc->rcc_BDCR.RTCSEL = 0x0; //Rcc_CSR init lkk_Rcc->rcc_CSR.PINRSTF = 0x1; lkk_Rcc->rcc_CSR.PORRSTF = 0x1; lkk_Rcc->rcc_CR.PLLON = 0x1; //PWR lkk_PWR->pwr_CR.PLS = 0x00; }
- 为
-
main.c
添加自定的RCC头文件,引入初始化函数代替/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : main.c * @brief : Main program body ****************************************************************************** * @attention * * <h2><center>© Copyright (c) 2021 STMicroelectronics. * All rights reserved.</center></h2> * * This software component is licensed by ST under BSD 3-Clause license, * the "License"; You may not use this file except in compliance with the * License. You may obtain a copy of the License at: * opensource.org/licenses/BSD-3-Clause * ****************************************************************************** */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "main.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "LkkRccInit.h" /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); static void MX_GPIO_Init(void); /* USER CODE BEGIN PFP */ void Lkk_Clock_Config(void); /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ /** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ Lkk_Clock_Config(); /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); /* USER CODE BEGIN 2 */ /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ }
软仿真查看
- 选择RCC,单步跟踪查看