1.宏定义
.c —-就当前c文件使用
.h —-可能多个文件使用
数据封装
2.位段操作
/* ------------ RCC registers bit address in the alias region ----------- */ RCC位段#define RCC_OFFSET (RCC_BASE - PERIPH_BASE) 偏移/* --- CR Register ---*//* Alias word address of HSION bit */#define CR_OFFSET (RCC_OFFSET + 0x00) 基地址#define HSION_BitNumber 0x00 位#define CR_HSION_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (HSION_BitNumber * 4)) 别名区地址 BIT Band/* Alias word address of PLLON bit */#define PLLON_BitNumber 0x18#define CR_PLLON_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (PLLON_BitNumber * 4))#ifdef STM32F10X_CL/* Alias word address of PLL2ON bit */#define PLL2ON_BitNumber 0x1A#define CR_PLL2ON_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (PLL2ON_BitNumber * 4))/* Alias word address of PLL3ON bit */#define PLL3ON_BitNumber 0x1C#define CR_PLL3ON_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (PLL3ON_BitNumber * 4))#endif /* STM32F10X_CL *//* Alias word address of CSSON bit */#define CSSON_BitNumber 0x13#define CR_CSSON_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (CSSON_BitNumber * 4))
3.位掩码
移位
按位取反等
在库中已经构造好了
Reset是位或清零
Set是与或置1
/* CR register bit mask */#define CR_HSEBYP_Reset ((uint32_t)0xFFFBFFFF) //置0#define CR_HSEBYP_Set ((uint32_t)0x00040000) //#define CR_HSEON_Reset ((uint32_t)0xFFFEFFFF)#define CR_HSEON_Set ((uint32_t)0x00010000)#define CR_HSITRIM_Mask ((uint32_t)0xFFFFFF07)/* CFGR register bit mask */#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL) || defined (STM32F10X_CL)#define CFGR_PLL_Mask ((uint32_t)0xFFC2FFFF)#else#define CFGR_PLL_Mask ((uint32_t)0xFFC0FFFF)#endif /* STM32F10X_CL */#define CFGR_PLLMull_Mask ((uint32_t)0x003C0000)#define CFGR_PLLSRC_Mask ((uint32_t)0x00010000)#define CFGR_PLLXTPRE_Mask ((uint32_t)0x00020000)#define CFGR_SWS_Mask ((uint32_t)0x0000000C)#define CFGR_SW_Mask ((uint32_t)0xFFFFFFFC)#define CFGR_HPRE_Reset_Mask ((uint32_t)0xFFFFFF0F)#define CFGR_HPRE_Set_Mask ((uint32_t)0x000000F0)#define CFGR_PPRE1_Reset_Mask ((uint32_t)0xFFFFF8FF)#define CFGR_PPRE1_Set_Mask ((uint32_t)0x00000700)#define CFGR_PPRE2_Reset_Mask ((uint32_t)0xFFFFC7FF)#define CFGR_PPRE2_Set_Mask ((uint32_t)0x00003800)#define CFGR_ADCPRE_Reset_Mask ((uint32_t)0xFFFF3FFF)#define CFGR_ADCPRE_Set_Mask ((uint32_t)0x0000C000)
分频
static __I uint8_t APBAHBPrescTable[16] = {0, 0, 0, 0, 1, 2, 3, 4, 1, 2, 3, 4, 6, 7, 8, 9};static __I uint8_t ADCPrescTable[4] = {2, 4, 6, 8};
assert断言:
C语言用来判断一个东西是对的还是错的,如果是对的就忽略过去,如果错的以某种方式告诉我们
断言机制使用最多的是:库函数中用断言来检查用户调用该库函数的参数对不对
4.使用标准库实现RCC切换
#include "clock.h"void Set_SysClockTo72M(void){ErrorStatus sta = ERROR;//先关闭HSEON再打开HSEONRCC_HSEConfig(RCC_HSE_ON);//do while 等待HSEON稳定sta = RCC_WaitForHSEStartUp();if(sta == SUCCESS){//设置FLASHFLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);FLASH_SetLatency(FLASH_Latency_2);// FLASH->ACR |= 0x10;// FLASH->ACR &= (~0x03);// FLASH->ACR |= (0x02);// 到这里HSE就ready了,下面再去配PLL并且等待他ready//配HLCK为SYSCLK/1RCC_HCLKConfig(RCC_SYSCLK_Div1);//配置PLCK1为AHB的2分频RCC_PCLK1Config(RCC_HCLK_Div2);//配置PLCK2为AHB2的1分频RCC_PCLK2Config(RCC_HCLK_Div1);//设置HSE/1为PLL原始种,PLL倍频系数为9RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);//使能PLLRCC_PLLCmd(ENABLE);while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET){}//设置PLL为系统时钟RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);//等待PLL设置好时钟while(RCC_GetSYSCLKSource() != 0x08){}}else{while(1){}}}
PS:
注意:
在启动文件中
调用SystemInit函数,会初始化为72
我们关掉之后就可以看到速度的差别了
EXPORT Reset_Handler [WEAK]IMPORT __mainIMPORT SystemInit;LDR R0, =SystemInit;BLX R0LDR R0, =__mainBX R0ENDP
#include "stm32f10x.h"#include "clock.h"void led_init(void);void Delay(void);void flash(void);int main(void){led_init();flash();Set_SysClockTo72M();while(1){flash();};return 0;}void led_init(void){RCC->APB2ENR = 0x00000100;GPIOG->CRL = (0x33 << 24);}void Delay(void){unsigned int i = 0, j = 0;for( i = 0; i < 2000; i++){for( j = 0; j < 2000; j++);}}void flash(void){GPIOG->BSRR = 0x000000080;Delay();GPIOG->BSRR = 0x00000040;Delay();GPIOG->BSRR = 0x00ff0000;Delay();}
