LinkedInSTM32F4时钟系统初始化的程序代码分享

发布时间:2023-10-09  

时钟系统   寄存器


LinkedInSTM32F4 时钟系统初始化是在system_stm32f4xx.c中的 SystemInit()函数中完成的。 对于系统时钟关键寄存器设置主要是在 SystemInit 函数中调用 SetSysClock()函数来设置的。我们可以先看看 SystemInit ()函数体:


LinkedInSTM32F4时钟系统初始化的程序代码分享



void SystemInit(void)

{

#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)

SCB-》CPACR |= ((3UL 《《 10*2)|(3UL 《《 11*2));

#endif

RCC-》CR |= (uint32_t)0x00000001;

RCC-》CFGR = 0x00000000;

RCC-》CR &= (uint32_t)0xFEF6FFFF;

RCC-》PLLCFGR = 0x24003010;

RCC-》CR &= (uint32_t)0xFFFBFFFF;

RCC-》CIR = 0x00000000;

#if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM)

SystemInit_ExtMemCtl();

#endif

SetSysClock();

#ifdef VECT_TAB_SRAM

SCB-》VTOR = SRAM_BASE | VECT_TAB_OFFSET;

#else

SCB-》VTOR = FLASH_BASE | VECT_TAB_OFFSET;

#endif

}

SystemInit函数开始先进行浮点运算单元设置,然后是复位PLLCFGR,CFGR寄存器,同时通过设置 CR 寄存器的 HSI 时钟使能位来打开 HSI 时钟。默认情况下如果 CFGR 寄存器复位,那么是选择HSI作为系统时钟,这点大家可以查看RCC-》CFGR 寄存器的位描述最低2位可以得知,当低两位配置为 00的时候(复位之后),会选择 HSI振荡器为系统时钟。也就是说,调用 SystemInit 函数之后,首先是选择 HSI 作为系统时钟。

在设置完相关寄存器后,接下来SystemInit函数内部会调用 SetSysClock函数。这个函数比较长,我们就把函数一些关键代码行截取出来给大家讲解一下。这里我们省略一些宏定义标识符值的判断而直接把针对STM32F407 比较重要的内容贴出来:

static void SetSysClock(void)

{

__IO uint32_t StartUpCounter = 0, HSEStatus = 0;

RCC-》CR |= ((uint32_t)RCC_CR_HSEON);

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;

}

if (HSEStatus == (uint32_t)0x01)

{

RCC-》APB1ENR |= RCC_APB1ENR_PWREN;

PWR-》CR |= PWR_CR_VOS;

RCC-》CFGR |= RCC_CFGR_HPRE_DIV1;

RCC-》CFGR |= RCC_CFGR_PPRE2_DIV2;

RCC-》CFGR |= RCC_CFGR_PPRE1_DIV4;

RCC-》CFGR |= RCC_CFGR_PPRE2_DIV1;

RCC-》CFGR |= RCC_CFGR_PPRE1_DIV2;

RCC-》PLLCFGR = PLL_M | (PLL_N 《《 6) | (((PLL_P 》》 1) -1) 《《 16) |

(RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q 《《 24);

RCC-》CR |= RCC_CR_PLLON;

while((RCC-》CR & RCC_CR_PLLRDY) == 0)

{

}

FLASH-》ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN

|FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;

RCC-》CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));

RCC-》CFGR |= RCC_CFGR_SW_PLL;

while ((RCC-》CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);

{

}

}

else

{

}

}

这段代码的大致流程是这样的:先使能外部时钟 HSE,等待 HSE 稳定之后,配置AHB,APB1,APB2 时钟相关的分频因子,也就是相关外设的时钟。等待这些都配置完成之后,打开主PLL时钟,然后设置主PLL作为系统时钟 SYSCLK时钟源。如果HSE 不能达到就绪状态(比如外部晶振不能稳定或者没有外部晶振),那么依然会是HSI作为系统时钟。

在这里要特别提出来,在设置主PLL时钟的时候,会要设置一系列的分频系数和倍频系数参数。大家可以从SetSysClock函数的这行代码看出:

RCC-》PLLCFGR = PLL_M | (PLL_N 《《 6) | (((PLL_P 》》 1) -1) 《《 16) |

(RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q 《《 24);

这些参数是通过宏定义标识符的值来设置的。默认的配置在 System_stm32f4xx.c 文件开头的地方配置。对于我们开发板,我们的设置参数值如下:

#define PLL_M 8

#define PLL_Q 7

#define PLL_N 336

#define PLL_P 2

所以我们的主PLL时钟为:

PLL=8MHz * N/ (M*P)=8MHz* 336 /(8*2) = 168MHz

在开发过程中,我们可以通过调整这些值来设置我们的系统时钟。

这里还有个特别需要注意的地方,就是我们还要同步修改 stm32f4xx.h 中宏定义标识符HSE_VALUE 的值为我们的外部时钟:

#if !defined (HSE_VALUE)

#define HSE_VALUE ((uint32_t)8000000)

#endif

这里默认固件库配置的是25000000,我们外部时钟为8MHz,所以我们根据我们硬件情况修改为8000000即可。

讲到这里,大家对 SystemInit 函数的流程会有个比较清晰的理解。那么 SystemInit 函数是怎么被系统调用的呢?SystemInit是整个设置系统时钟的入口函数。这个函数对于我们使用ST提供的 STM32F4 固件库的话,会在系统启动之后先执行main函数,然后再接着执行SystemInit函数实现系统相关时钟的设置。这个过程设置是在启动文件 startup_stm32f40_41xxx.s中间设置的,我们接下来看看启动文件中这段启动代码:

; Reset handler

Reset_Handler PROC

EXPORT Reset_Handler [WEAK]

IMPORT SystemInit

IMPORT __main

LDR R0, =SystemInit

BLX R0

LDR R0, =__main

BX R0

ENDP

这段代码的作用是在系统复位之后引导进入main函数,同时在进入main函数之前,首先

要调用 SystemInit系统初始化函数完成系统时钟等相关配置。

最后我们总结一下SystemInit()函数中设置的系统时钟大小:

SYSCLK(系统时钟) =168MHz

AHB总线时钟(HCLK=SYSCLK) =168MHz

APB1总线时钟(PCLK1=SYSCLK/4) =42MHz

APB2总线时钟(PCLK2=SYSCLK/2) =84MHz

PLL主时钟 =168MHz


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>