STM32&Systick(HAL库)

可以说,32系列的Systick就是一个加强功能了的51定时器。抛开HAL库不谈,Systick本身主要是寄托于三个寄存器运作的。本文章主要讲述运作框架;寄存器用法;Systick手动配置。

目录

1.Systick运作框架

2.SysTick的三个寄存器

CTRL

VAL&LOAD

3.SysTick配置

先说情况一:

再说情况二:

4.SysTick中断配置:


1.Systick运作框架

先看图:

然后讲原理:
Systic本质上就是一个按照LOAD的值不断递减的一个时钟。其来源于HCLK(所以在配置的时候一定要初始化时钟树,否则频率未知),也就是说HCLK频率是多少,那么Systick的频率也是多少。然后VAL是一个记录器,就是说当前Systick的值是多少那么VAL就是多少。最后是countflag,当它为1时标志这此时VAL为了,将要reload。

2.SysTick的三个寄存器

CTRL

也是直接看图:

这里科普一个常识,寄存器是从0位开始算的,就象数组一样。
该寄存器主要配置SysTick中断,使能,分频。

VAL&LOAD


功能就和上述的一样,非常简单直接。

3.SysTick配置

在使用中,其实分两种情况:
一:单纯使用单片机的定时功能,用Systick重写delay函数。
二:在运行着操作系统的情况下(比如FreeRTOS)执行上述情况

先说情况一:

这种情况很简单,就是按照上述的情况来配置你的delay就行:

1.获取要演示的us--->2.按照频率对应到SysTick要记录的次--->3.清空当前SysTick的值--->4.使能定时器--->5.记录countflag值,当时间足够跳出定时--->6.关闭定时器.

直接上代码:

void delay_us(uint32_t nus){
    uint32_t temp;
    SysTick->LOAD = 72 * nus;                           
    SysTick->VAL = 0x00;                               
    SysTick->CTRL |= 1 << 2;                           
    SysTick->CTRL |= 1 << 0;                            
    do
    {
        temp = SysTick->CTRL;
    } while ((temp & 0x01) && !(temp & (1 << 16)));     
    SysTick->CTRL &= ~(1<<0);     
}                   

这里如果你对C中的按位操作不熟悉的话,很可能看不懂这里的部分配置,我稍微讲解一下:
对于 
SysTick->CTRL |= 1 << 2;                 给寄存器第三位(2)置1           
SysTick->CTRL |= 1 << 0;                 给寄存器第一位(0)置1
SysTick->CTRL &= ~(1<<0);           给寄存器第一位(0)置0

1<<0是在位的概念上把1左移0位。所谓在位的概念上,这个事情需要从定义来讲起:
        定义一个变量比如char是1字节,就是8位。这里的八位就是二进制概念的八位
也就是说,当你char一个变量a,在内存看来变量a就是0000 0000,当然了,肯定不都是0。
由于STM32中uint是指的无符号int类型,所以:
uint8 a = 1,在内存上就是 0000 0001,那么此时对 a << 1: 0000 0010;
仍然不理解,我回头再从新出一篇文章专门细讲这个。

再说情况二:

假设此时单片机上运行着一个FreeRTOS,那么此时是不可以随意的关闭再打开SysTick的。因为操作系统以SysTcik为时基。

所以我们在重写delay时有一个新的思路:我们不关心LOAD的值,不关心此时VAL的值,我们只关心在单位时间内,SysTcik记录了多少次就行。
直接上代码:

void delay_us(uint32_t nus)
{
	uint16_t tnow,told,tcnt = nus*72;	//这里*72是因为Systick的时钟来源是HLCK,
                                        //而HLCK是72M也就是72*10^6,按照s和us的换算就是72
	uint32_t load = SysTick->LOAD;
	told = SysTick->VAL;
	while(1){
		tnow = SysTick->VAL;
		
		if(tnow > told){
			tcnt -= load + (tnow - told);
		}else if(tnow < told){
			tcnt -= told - tnow;
		}
		told = tnow;
		if(tcnt <= 0) break;
	}
}

看一遍代码就能看出思路,这里只说一个点:
当tnow<told时,说明此时在同意周期内。当tnow>told时,说明此时已经reload了一次。tnow在told之上,此时不能单纯计算差值,需要加上一个load值。 

4.SysTick中断配置:

默认情况下,SysTick的中断被配置为1ms触发一次,配置的地方在这里:

按F12进入函数定义:
 
在STM32中,__weak就是用来给开发者重写函数的,所以如果你想要配置SysTick的中断服务部分,就在这里面配就行。
注意:这里的文件和函数位置都是HAL库版本的,至于标准库请再查询其他文章

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值