您的位置 首页 编程

STM32学习笔记(3):体系时钟和SysTick定时器

1STM32的时钟系统在STM32中,一共有5个时钟源,分别是HSI、HSE、LSI、LSE、PLL(1)HSI是高速内部时钟,RC振荡器,频率为8MHz;(2)HSE是

1.STM32的时钟体系

在STM32中,一共有5个时钟源,分别是HSI、HSE、LSI、LSE、PLL

(1)HSI是高速内部时钟,RC振荡器,频率为8MHz;

(2)HSE是高速外部时钟,可接石英/陶瓷谐振器,或许接外部时钟源,频率规模是4MHz – 16MHz;

(3)LSI是低速内部时钟,RC振荡器,频率为40KHz;

(4)LSE是低速外部时钟,接频率为32.768KHz的石英晶体;

(5)PLL为锁相环倍频输出,严厉的来说并不算一个独立的时钟源,PLL的输入能够接HSI/2、HSE或许HSE/2。倍频可挑选为2 – 16倍,可是其输出频率最大不得超越72MHz。

其间,40kHz的LSI供独立看门狗IWDG运用,别的它还能够被挑选为实时时钟RTC的时钟源。别的,实时时钟RTC的时钟源还能够挑选LSE,或许是HSE的128分频。

STM32中有一个全速功用的USB模块,其串行接口引擎需求一个频率为48MHz的时钟源。该时钟源只能从PLL端获取,能够挑选为1.5分频或许1分频,也便是,当需运用到USB模块时,PLL有必要使能,而且时钟装备为48MHz或72MHz。

别的STM32还能够挑选一个时钟信号输出到MCO脚(PA.8)上,能够挑选为PLL输出的2分频、HSI、HSE或许体系时钟。

体系时钟SYSCLK,它是供给STM32中绝大部分部件作业的时钟源。体系时钟能够挑选为PLL输出、HSI、HSE。系体系时钟最大频率为72MHz,它经过AHB分频器分频后送给各个模块运用,AHB分频器能够挑选1、2、4、8、16、64、128、256、512分频,其分频器输出的时钟送给5大模块运用:

(1)送给AHB总线、内核、内存和DMA运用的HCLK时钟;

(2)经过8分频后送给Cortex的体系守时器时钟;

(3)直接送给Cortex的闲暇运转时钟FCLK;

(4)送给APB1分频器。APB1分频器能够挑选1、2、4、8、16分频,其输出一路供APB1外设运用(PCLK1,最大频率36MHz),另一路送给守时器(Timer)2、3、4倍频器运用。该倍频器能够挑选1或许2倍频,时钟输出供守时器2、3、4运用。

(5)送给APB2分频器。APB2分频器能够挑选1、2、4、8、16分频,其输出一路供APB2外设运用(PCLK2,最大频率72MHz),别的一路送给守时器(Timer)1倍频运用。该倍频器能够挑选1或2倍频,时钟输出供守时器1运用。别的APB2分频器还有一路输出供ADC分频器运用,分频后送给ADC模块运用。ADC分频器可挑选为2、4、6、8分频。

需求留意的是守时器的倍频器,当APB的分频为1时,它的倍频值为1,不然它的倍频值就为2。

连接在APB1(低速外设)上的设备有:电源接口、备份接口、CAN、USB、I2C1、I2C2、UART2、UART3、SPI2、窗口看门狗、Timer2、Timer3、Timer4。留意USB模块尽管需求一个独自的48MHz的时钟信号,可是它应该不是供USB模块作业的时钟,而仅仅供给给串行接口引擎(SIE)运用的时钟。USB模块的作业时钟应该是由APB1供给的。

连接在APB2(高速外设)上的设备有:UART1、SPI1、Timer1、ADC1、ADC2、GPIOx(PA~PE)、第二功用IO口。

2.STM32时钟的初始化

由于我现在所用的开发板现已外接了一个8MHz的晶振,因而将选用HSE时钟,在MDK编译平台中,程序的时钟设置参数流程如下:

(1)将RCC寄存器从头设置为默认值:RCC_DeInit;

(2)翻开外部高速时钟晶振HSE:RCC_HSEConfig(RCC_HSE_ON);

(3)等候外部高速时钟晶振作业:HSEStartUpStatus = RCC_WaitForHSEStartUp();

(4)设置AHB时钟(HCLK):RCC_HCLKConfig;

(5)设置高速AHB时钟(APB2):RCC_PCLK2Config;

(6)设置低速AHB时钟(APB1):RCC_PCLK1Config;

(7)设置PLL:RCC_PLLConfig;

(8)翻开PLL:RCC_PLLCmd(ENABLE);

(9)等候PLL作业:while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);

(10)设置体系时钟:RCC_SYSCLKConfig;

(11)判别PLL是否是体系时钟:while(RCC_GetSYSCLKSource() != 0x08);

(12)翻开要运用的外设时钟:RCC_APB2PerphClockCmd()….

某些函数的详细的运用方法,能够参阅ST公司出书的《STM32F10xxx_Library_Manual》

3.SysTick守时器

NVIC中,捆绑着一个SysTick守时器,它是一个24位的倒数计数守时器,当计到0时,将从RELOAD寄存器中主动重装载守时初值并持续计数,一起内部的COUNTFLAG标志会置位,触发中止(假如中止使能情况下)。只需不把它在SysTick操控及状况寄存器中的使能位铲除,就用不停息。Cortex-M3答应为SysTick供给2个时钟源以供挑选,第一个是内核的“自在运转时钟”FCLK,“自在”表现在它不是来自体系时钟HCLK,因而在体系时钟中止时,FCLK也能持续运转。第2个是一个外部的参阅时钟,可是运用外部时钟时,由于它在内部是经过FCLK来采样的,因而其周期有必要至少是FCLK的两倍(采样定理)。

下面介绍一下STM32中的SysTick,它归于NVIC操控部分,一共有4个寄存器:

STK_CSR,0xE000E010:操控寄存器

STK_LOAD,0xE000E014:重载寄存器

STK_VAL,0xE000E018:当时值寄存器

STK_CALRB,0xE000E01C:校准值寄存器

首先看STK_CSR操控寄存器,有4个bit具有含义:

第0位:ENABLE,SysTick使能位(0:封闭SysTick功用,1:敞开SysTick功用);

第1位:TICKINT,SysTick中止使能位(0:封闭SysTick中止,1:敞开SysTick中止);

第2位:CLKSOURCE,SysTick时钟挑选(0:运用HCLK/8作为时钟源,1:运用HCLK);

第3为:COUNTFLAG,SysTick计数比较标志,假如在前次读取本寄存器后,SysTick现已数到0了,则该位为1,假如读取该位,该位主动清零。

STK_LOAD重载寄存器:

Systick是一个递减的守时器,当守时器递减至0时,重载寄存器中的值就会被重装载,持续开端递减。STK_LOAD重载寄存器是个24位的寄存器最大计数0xFFFFFF。

STK_VAL当时值寄存器:

也是个24位的寄存器,读取时回来当时倒计数的值,写它则使之清零,一起还会铲除在SysTick操控及状况寄存器中的COUNTFLAG标志。

STK_CALRB校准值寄存器:

其间包含着一个TENMS位段,详细信息不详。暂时用不到。

在MDK开发环境中,咱们不必要非得去操作每一个寄存器,能够经过调用ST函数库中的函数来进行相关的操作,其过程如下:

(1)调用SysTick_CounterCmd()失能SysTick计数器

(2)调用SysTick_ITConfig()失能SysTick中止

(3)调用SysTick_CLKSourceConfig()设置SysTick时钟源

(4)调用SysTick_SetReload()设置SysTick重装载值

(5)调用NVIC_SystemHandlerPriorityConfig()设置SysTick守时器中止优先级

(6)调用SysTick_ITConfig()使能SysTick中止

(7)在stm32f10x_it.c中SysTickHandler()下写中止服务函数。

(8)在需求的时分调用SysTick_CounterCmd()敞开SysTick计数器

4.工程完成

依据以上描绘,预备运用开发板上的LED灯做一个小试验,将第一个跑马灯的试验略微改善一下,以1s准确延时的状况来次序点亮LED灯,选用的守时器便是SysTick。

规划思路是先装备好体系的各个参数,然后设置SysTick守时器每1ms就进入一次中止,再界说一个全局变量作为守时长短的参数,然后将从延时函数中得到的参数赋值给这个全局变量,每进入一次中止,这个全局变量就减一次,直到减为0,才跳出延时函数。

1.装备体系时钟

void RCC_cfg()

{

//界说过错状况变量

ErrorStatus HSEStartUpStatus;

//将RCC寄存器从头设置为默认值

RCC_DeInit();

//翻开外部高速时钟晶振

RCC_HSEConfig(RCC_HSE_ON);

//等候外部高速时钟晶振作业

HSEStartUpStatus = RCC_WaitForHSEStartUp();

if(HSEStartUpStatus == SUCCESS)

{

//设置AHB时钟(HCLK)为体系时钟

RCC_HCLKConfig(RCC_SYSCLK_Div1);

//设置高速AHB时钟(APB2)为HCLK时钟

RCC_PCLK2Config(RCC_HCLK_Div1);

//设置低速AHB时钟(APB1)为HCLK的2分频

RCC_PCLK1Config(RCC_HCLK_Div2);

//设置FLASH代码延时

FLASH_SetLatency(FLASH_Latency_2);

//使能预取指缓存

FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

//设置PLL时钟,为HSE的9倍频8MHz * 9 = 72MHz

RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);

//使能PLL

RCC_PLLCmd(ENABLE);

//等候PLL预备就绪

while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);

//设置PLL为体系时钟源

RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

//判别PLL是否是体系时钟

while(RCC_GetSYSCLKSource() != 0x08);

}

//翻开PB和PD用于点亮LED灯

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOD, ENABLE);

}

其间运用到了NVIC的函数,需求将stm32f10xR.lib加入到工程中。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/fangan/biancheng/255709.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部