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再打开HSEON
RCC_HSEConfig(RCC_HSE_ON);
//do while 等待HSEON稳定
sta = RCC_WaitForHSEStartUp();
if(sta == SUCCESS)
{
//设置FLASH
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
FLASH_SetLatency(FLASH_Latency_2);
// FLASH->ACR |= 0x10;
// FLASH->ACR &= (~0x03);
// FLASH->ACR |= (0x02);
// 到这里HSE就ready了,下面再去配PLL并且等待他ready
//配HLCK为SYSCLK/1
RCC_HCLKConfig(RCC_SYSCLK_Div1);
//配置PLCK1为AHB的2分频
RCC_PCLK1Config(RCC_HCLK_Div2);
//配置PLCK2为AHB2的1分频
RCC_PCLK2Config(RCC_HCLK_Div1);
//设置HSE/1为PLL原始种,PLL倍频系数为9
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
//使能PLL
RCC_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 __main
IMPORT SystemInit
;LDR R0, =SystemInit
;BLX R0
LDR R0, =__main
BX R0
ENDP
#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();
}