×
单片机 > 单片机程序设计 > 详情

用keil C使单片机获得随机数

发布时间:2020-08-25 发布时间:
|
一、前言

1、本文主要讨论系统时钟以至外设时钟之间的源流关系。介绍stm32的片上时钟系统,描述系统时钟初始化函数SystemInit()对时钟的控制(从HSE到SYSCLK,第二节)与配置(SYSCLK到外设,第三节)。

2、103与107所用时钟系统略有不同,但系统时钟(SYSCLK)都是72MHz。

3、f107应当使用25MHz晶振。若采用8MHz的晶振,搭配3.0.0版固件库,则将f107当做f103使用,不能驱动通信线产品所有功能(以太网)。

4、以太网的时钟可以参考f107数据手册,附录A2.

5、RTC时钟源来自32.768kHZ晶振。

二、系统时钟SYSCLK

本节关注SYSCLK的来源。

f107与f103时钟系统略有不同,以下讨论除非特别说明,全都针对f107,采用25MHz晶振,时钟树见附录。

1、系统时钟:SYSCLK

系统复位后,HSI振荡器被选为系统时钟(8MHz),通过软件(SystemInit()函数)将系统时钟源切换到PLLCLK。

PLLCLK的来源是外部晶振HSE,由HSE信号经过5分频、8倍频、5分频得到8MHz的PLL时钟源,将其9倍频得到72MHzPLLCLK。(若在f107上采用8MHz晶振,则将HSE信号9倍频得到PLLCLK(72MHz),即系统时钟)

2、SystemInit()函数对时钟的控制(时钟控制寄存器CR,时钟配置寄存器2CFGR2)

此函数在3.0.0与3.1.2版本固件库中是不同的。相较于f103,f107在硬件上多了两个锁相环和一个CFGR2寄存器,并且定义了CR寄存器的26~29位。3.0.0版本固件库升级为3.1.2版本,正是为了配合这种变化,并实现新增的功能。

调用3.0.0库中的SystemInit()函数,结果如下:

寄存器

CR

0101 0083

CFGR

001D 0402

CFGR2

函数未涉及此寄存器

CIR

0000 0000

 

对此不作过多讨论,这样的方式会使以太网无法使用。

调用3.1.2库中的SystemInit()函数,结果如下:

寄存器

CR

0501 0083

CFGR

001D 0402

CFGR2

0001 0644

CIR

009F 0000

前三个寄存器配置了系统时钟,CIR是对中断的设置。这样,系统时钟的来源如下图。蓝色为复位后的时钟系统,红色为软件设置的时钟。

3.1.0版本的固件库中,SystemInit()函数有bug,会在下文提到。

三、总线时钟与外设时钟。

本节关注从SYSCLK生发出的时钟(PCLK等)。

1、特性与相互关系

由系统时钟分频得AHB时钟(也称为HCLK),AHB时钟供给内核的有三路:HCLK、FCLK、系统定时器(可能需要分频,视芯片型号而定)。

①两个高速外设总线的最高时钟不同,但都来自于HCLK。

②定时器有硬件设置的分频器,所以CK_INT(internal clock,或称作TIMxCLK)并不一定等于相应总线的频率,其规则为:如果相应的APB预分频系数是1,定时器的时钟频率与所在APB总线频率一致。否则,定时器的时钟频率被设为与其相连的APB总线频率的2倍。 

③ADC时钟ADCCLK有最大限制,对于103和107,最大为14MHz。所谓最快AD时间为1M分之一秒的说法是这么来的:

TCONV = 采样时间+ 12.5个周期

采样时间设为最短的1.5个周期,这样TCONV就是14个ADCCLK周期,当ADCCLK取最大的14MHz时,TCONV的时间就是1M分之一秒。

④有个有趣的现象:系统时钟配置成72MHz时,无法实现最快ADC。这是因为由于ADCCLK的上限限制,要对PCLK2进行分频,而72M无法分频为14M,最大可用只能为12M,这样自然不能实现最快ADC。

2、SystemInit()对RCC的配置(时钟配置寄存器CFGR)

AHBCLK=HCLK=SYSCLK=72MHz

PCLK1=HCLK/2=36MHz,  

PCLK2=HCLK=72MHz

TIMx(所有定时器)=PCLK1*2=PCLK2=72MHz

ADCCLK=36MHz

以上就是正常情况下SystemInit()的配置。所谓“正常”,是针对3.1.0版本固件库的bug来说的。此固件库的SetSysClockTo72函数(在system_stm32f10x.c文件中,被SystemInit调用),在配置通信线产品的PREDIV1时(或称为prediv1factor),错将5分频配置成3分频,导致芯片的系统时钟超频运行在120MHz。3.1.2版本外设固件库修正了这个bug。出错代码如下图:

 另外,在调用SystemInit()函数以后,ADCCLK是超频的(PCLK2/2, 36M),无法有保障地使用,需要调用RCC_ADCCLKConfig(RCC_PCLK2_Div6)将其配置成12MHz。这种麻烦特性到3.5.0版本固件库仍然存在,不知是什么意图。

附录:f107时钟树,或见参考手册7.2,图11



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
Keil(MDK-ARM)系列教程(七)_菜单