这几天在公司做项目,用到了C8T6作为主控,最开始写的代码是基于外部8MHZ晶振作为时钟源,后面和客户沟通不打算外接晶振使用内部时钟作为HSI作为时钟源,因此需要修改启动文件上的SystemInit函数,最终成功配置为64MHZ(内部时钟最高只能64),也是参考别的大佬写的,只是记录学习,有侵权联系删除。
在system_stm32f10x.c文件中,重新写systemInit()函数。可以注释掉原来的函数,重新写一下这个函数。
HSI为8MHZ,经过2分频后再通过锁相环16倍频即可达到最高64MHZ时钟,对应时钟树如下
如果不经过2分频的话则直接供给系统时钟SYSCLK,则系统时钟为8MHZ
经过配置后根据时钟树可得,AHB、APB2都为64MHZ,APB1为32MHZ
在开启内部时钟时,需要提前设置flash延时,并设置内部HSI校正值。最后才可以开启内部晶振时钟。内部RC默认为8M,将倍频数设置为16,这样使内部RC振荡器之后,时钟频率即为64MHz。
/*PLLCLK=8/2*16=64MHz 设置倍频得到时钟源PLL的频率*/
RCC->CFGR |= ( uint32_t ) RCC_CFGR_PLLMULL16; //设置倍频后的频率//注:HSI:内部晶振时钟
时钟初始化代码贴下
void SystemInit (void)
{
//set flash delay
/* Enable Prefetch Buffer */
FLASH->ACR |= FLASH_ACR_PRFTBE;
/* Flash 2 wait state */
FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;
while((uint32_t)(READ_BIT(FLASH->ACR, FLASH_ACR_LATENCY)) != FLASH_ACR_LATENCY_2){};
//set HSI校正值
RCC_AdjustHSICalibrationValue(16);
/* 开启HSI */
RCC->CR |= (uint32_t) 0x00000001;
/*选择HSI为PLL的时钟源HSI必须2分频给PLL*/
RCC->CFGR |= (uint32_t)RCC_CFGR_PLLSRC_HSI_Div2;
/*PLLCLK=8/2*9=36MHz 设置倍频得到时钟源PLL的频率*/
//设置倍频后的频率
RCC->CFGR |= (uint32_t)RCC_CFGR_PLLMULL16;
/* PLL不分频输出 */
RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
/* 使能 PLL时钟 */
RCC->CR |= RCC_CR_PLLON;
/* 等待PLL时钟就绪*/
while ((RCC->CR & RCC_CR_PLLRDY) == 0){};
/* 选择PLL为系统时钟的时钟源 */
RCC->CFGR &=(uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;
/* 等待PLL成为系统时钟的时钟源*/
while( (RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08){};
/* HCLK = SYSCLK */
RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
/* PCLK2 = HCLK */
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
/* PCLK1 = HCLK/2 */
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;
}
延时1us代码
void Delay_us(uint32_t xus)
{
SysTick->LOAD = 64 * xus; //设置定时器重装值
SysTick->VAL = 0x00; //清空当前计数值
SysTick->CTRL = 0x00000005; //设置时钟源为HCLK,启动定时器
while(!(SysTick->CTRL & 0x00010000)); //等待计数到0
SysTick->CTRL = 0x00000004; //关闭定时器
}
改完时钟后跑之前的72MHZ项目代码 没有问题
这样就可以省了两个晶振(8MHZ以及32.768KHZ),8MHZ是供给系统时钟源的,32.768是供给实时时钟RTC的,由于本项目用不到,所以就不用外接。