STM32时钟与定时器

目录

一、STM32的时钟系统

二、SysTick定时器

三、HAL_Delay的实现

四、通用定时器


一、STM32的时钟系统

概念

        时钟系统是由振荡器(信号源)、定时唤醒器、分频器等组成的电路。常用的信号源有晶体振荡器和RC振荡器。

意义

        时钟是嵌入式系统的脉搏,处理器内核在时钟驱动下完成指令执行,状态变换等动作,外设部件在时钟的驱动下完成各种工作,比如串口数据的发送、A/D转换、定时器计数等等。因此时钟对于计算机系统是至关重要的,通常时钟系统出现问题也是致命的,比如振荡器不起振、振荡不稳、停振等。

概念

       振荡器是用来产生重复电子讯号的电子元件。其构成的电路叫振荡电路,能将直流电转换为具有一定频率交流信号输出的电子电路或装置。

分类

       振荡器主要分为RC,LC振荡器和晶体振荡器。RC振荡器是采用RC网络作为选频移相网络的振荡器。LC振荡器是采用LC振荡回路作为移相和选频网络的正反馈振荡器。晶体振荡器的振荡频率受石英晶体控制。

RC振荡器

        RC振荡器是又电阻电容构成的振荡电路,能将直流电转换为具有一定频率交流信号输出的电子电路或装置。

优点

     实现的成本比较低,毕竟就是一个电阻电容

缺点
        是由于电阻电容的精度问题所以RC振荡器的震荡频率会有误差,同时受到温度、湿度的影响

 晶体振荡器

           石英晶体振荡器是高精度和高稳定度的振荡器,被广泛应用于彩电、计算机、遥控器等各类振荡电路中,以及通信系统中用于频率发生器、为数据处理设备产生时钟信号和为特定系统提供基准信号

优点

   是相对来说震荡频率一般都比较稳定,同时精度也较高

缺点

   就是价格要稍微高点了,还有用晶体振荡器一般还需要接两个15-33pF起振电容

 

STM32 中有四个时钟源
lHSI:高速内部时钟,RC振荡器,频率为8MHz;
lHSE:高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为4MHz~16MHz
lLSI:低速内部时钟,RC振荡器,频率为40KHz。独立看门狗时钟源只能是这个,还可做RTC时钟源
lLSE:低速外部时钟,接32.768KHz的石英晶体。这个主要是RTC的时钟源

有的教材会把PLL也写上,其实它只是一个倍频器。 它用的是别的时钟源进行倍频后输出

 

 

void SystemInit(void)

            System_stm32f0xx.c中定义,在系统启动之后,程序会先执行 HAL 库定义的 SystemInit 函数,进行系统一些初始化配置,复位 RCC 时钟配置为默认复位值(默认开启 HSI)

nvoid SystemClock_Config(void)

       在main.c中定义,实现时钟的具体配置,配置PLL, 配置AHB和HPB的时钟

 那么具体怎么用呢

 

把这个配置成可用

接到外部时钟的两个管脚就可用了。

时钟树配置的外部晶振就亮了

选择倍频,切换时钟为PLCK这样所有的时钟频率就都变成48M了

不同的芯片他的频率限制不同这个不能大于48M,在超频状态下可能会损坏。

二、SysTick定时器

概念

        定时器,能够定时、计数的器件称为定时器

        SysTick,  称作系统滴答定时器,简称滴答定时器。是一个定时设备,位于Cortex-M0内核中,可以对输入的时钟进行计数,当然,如果时钟信号是周期性的,计数也就是计时。

        系统定时器一般用于操作系统,用于产生时基,维持操作系统的心跳。根据这个中断,系统就可以实现时间片的计算从而切换进程。

工作原理

      滴答定时器是一个24位定时器,也就是最多能计数2^24。在使用的时候,我们一般给计数器送一个初始的计数值,计数器向下计数,每来一个时钟信号,计数初值就减一,计数值减到0的时候,就会发出一次中断。然后重新从计数初值再减一计数,循环不断

 当然,不止M0,所有的型号貌似都有,暂时么见过没有的。

 

n Main中已经实现对SysTick定时器的初始化

void SystemClock_Config(void)

  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);

         SysTick_Config(TicksNumb);

n  在core_cm0.h定义了SysTick_Config(uint32_t ticks)

三、HAL_Delay的实现

  利用SysTick实现精准的延时

__weak void HAL_Delay(__IO uint32_t Delay)
{
  uint32_t    tickstart = 0U;

  tickstart     = HAL_GetTick();
  while((HAL_GetTick() - tickstart) < Delay) ; 
}



//下面代码均在文件 stm32f0xx_hal.c 中

static __IO uint32_t uwTick; //定义计数全局变量

//获取全局变量 uwTick 的值
__weak uint32_t HAL_GetTick(void)
{
	return uwTick;
}


//全局变量 uwTick 递增
__weak void HAL_IncTick(void)
{
	uwTick++;
}


//Systick 中断服务函数:文件 stm32f0xx_it.c 中

void SysTick_Handler(void)
{
	HAL_IncTick();
  	HAL_SYSTICK_IRQHandler();
}

每隔 1ms, uwTick增加 1

HAL_Delay()  的局限  

        HAL库的延时函数有一个局限性,在中断服务函数中使用HAL_Delay会引起混乱,因为它是通过中断方式实现,而 Systick 的中断一般操作系统优先级是最低的,所以在中断中运行 HAL_Delay

会导致死锁的现象。

四、通用定时器

 STM32F051xx 系列器件包括多达 6 个通用定时器,1个基本定时器和1个高级定时器。

通用定时器TIMx功能

● 定时器定时计数

● 输入捕获

● 输出比较

● PWM输出

● 使用外部信号控制定时器和定时器互连的同步电路

高级定时器TIM1功能

 

● 通用定时器的有功能

● 带死区控制和紧急刹车,可用于PWM控制电机

基本定时器TIM1功能
● 主要运用于定时计数以及驱动DAC
n向上计数模式

计数器从0计数到自动加载值(TIMx_ARR),然后重新从0开始计数并且产生一个计数器溢出事件。

n向下计数模式

计数器从自动装入的值(TIMx_ARR)开始向下计数到0,然后从自动装入的值重新开始,并产生一个计数器向下溢出事件。

n中央对齐模式(向上/向下计数)

计数器从0开始计数到自动装入的值-1,产生一个计数器溢出事件,然后向下计数到1并且产生一个计数器溢出事件;然后再从0开始重新计数。

n 时钟源:定时器时钟 TIMxCLK,即内部时钟 CK_INT,经 APB 预分频器后分频提供
n 计数器时钟:定时器时钟经过 PSC 预分频器之后,即 CK_CNT,用来驱动计数器计数
n 计数器CNT: 是一个 16 位/32的计数器
n 自动重装载寄存器:这里面装着计数器能计数的最大数值。当计数到这个值的时候,如果使能了中断的话,定时器就产生溢出中断
n 计时中断时间:

    1/(TIMxCLK/(PSC+1))  *  (ARR+1)

 

n输入捕获

 输入捕获可以用来捕获外部事件,比如引脚的电平变化(上升沿,下降沿),并记录下变化的时间,通常可以用来测量外部信号的频率或者电平持续的时间

n输出比较

 此项功能是用来控制一个输出波形,当计数器与捕获/比较寄存器的内容相同时,输出比较功能做出相应动作,比如电平的翻转。通常用于生产PWM波形

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance == TIM2)
	{
		HAL_UART_Transmit(&huart1, "TIM2 INT\n", 9, 100);
	}
}

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

宇努力学习

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值