ST公司默认是将系统时钟配置到72MHZ。
以下的七个步奏是设置系统时钟的函数,该函数截取自库文件system_stm32f10x.c。
将互联型相关的代码删掉便于分析,并标上了序号,总共七个步奏,这个顺序也是系统时钟配置的
的步奏,通过直接操作寄存器,主要相关的寄存器,主要是时钟配置寄存器RCC_CFGR,具体位的设置
和bit的含义,参考STM32参考手册
static void SetSysClockTo72(void)
{
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
// SYSCLK, HCLK, PCLK2 and PCLK1 配置过程的顺序
//(1)使能 HSE(高速外部时钟),并等待 HSE 稳定
RCC->CR |= ((uint32_t)RCC_CR_HSEON);
// 等待 HSE 启动稳定,并做超时处理
// Wait till HSE is ready and if Time out is reached exit
do
{
HSEStatus = RCC->CR & RCC_CR_HSERDY;
StartUpCounter++;
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
if ((RCC->CR & RCC_CR_HSERDY) != RESET)
{
HSEStatus = (uint32_t)0x01;
}
else
{
HSEStatus = (uint32_t)0x00;
}
//HSE启动成功,则继续往下处理
if (HSEStatus == (uint32_t)0x01)
{
// 使能FLASH预存取缓冲区
FLASH->ACR |= FLASH_ACR_PRFTBE;
FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;
//(2)设置AHB、APB2、APB1预分频因子
// HCLK = SYSCLK
RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
// PCLK2 = HCLK
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
//PCLK1 = HCLK
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;
// (3)设置PLL的时钟来源,设置PLL的倍频因子, PLLCLK = HSE * 9 = 72 MHz
RCC->CFGR &= (uint32_t)((uint32_t)
~(RCC_CFGR_PLLSRC
| RCC_CFGR_PLLXTPRE
| RCC_CFGR_PLLMULL));
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE
| RCC_CFGR_PLLMULL9);
//(4) 使能 PLL
RCC->CR |= RCC_CR_PLLON;
//(5) 等待PLL的稳定
while((RCC->CR & RCC_CR_PLLRDY) == 0)
{
}
// (6)选择PLL作为时钟来源
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;
//(7)读取时钟切换状态,确保PLLCLK被选为系统时钟
while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)
{
}
}
else
{ // 如果HSE启动失败,用户可以再这里添加错误代码出来
}
}
#endif
系统是时钟配置代码学习中遇到的基础的函数定义、杂文集。。
一、__IO uint32_t (很早之前遇到的一个问题,记录一下
库文件的定义如下:
#define __IO volatile
可以看出 __IO 其实就是 volatile 的意思。
volatile 的作用就是指示编译器不要因优化而省略此指令,必须每次都直接读写其值。
写一段测试代码如下
u8 test;
test = 1;
test = 2;
test = 3;
设置优化级别中级
运行后test会被直接取值为3 只有最后一个语句被编译
如用volatile
volatile u8 test;
test = 1;
test = 2;
test = 3;
则所有语句都会被编译。test先后被设置成1、2、3
由此可以看出这个作用在IO操作,寄存器操作,特殊变量,多线程变量读写都是很重要。
二、(uint32_t)0x01
uint32_t 是系统定义的 typedef uint32_t unsigned int
(uint32_t)0x01
的作用就是将0x01装换成32位的进行操作。
上一篇:STM32关于外部时钟晶振为什么选用8MHz
下一篇:STM32与上位机发送和接收数据
推荐阅读最新更新时间:2024-03-16 15:42