历史上的今天
返回首页

历史上的今天

今天是:2025年01月15日(星期三)

正在发生

2019年01月15日 | STM32的Systick滴答定时器及延时函数编写

2019-01-15 来源:eefocus

一、Systick滴答定时器是什么?

    

Systick定时器就是系统滴答定时器,一个24 位的倒计数定时器,计到0 时,将从RELOAD 寄存器中自动重装载定时初值。只要不把它在SysTick 控制及状态寄存器中的使能位清除,就永不停息,即使在睡眠模式下也能工作。


定时器既是在规定时间之后执行某个操作。


 Systick定时器常用来做延时,或者实时系统的心跳时钟。这样可以节省MCU资源,不用浪费一个定时器。比如UCOS中,分时复用,需要一个最小的时间戳,一般在STM32+UCOS系统中,都采用Systick做UCOS心跳时钟。


------------------------------------------------------------------------------------------------------------------------------------------------------


二、Systick一般用来做延时,精确延时。


一共4个Systick寄存器


    CTRL             SysTick 控制和状态寄存器 


    LOAD             SysTick 自动重装载初值寄存器 


    VAL              SysTick 当前值寄存器 


    CALIB            SysTick 校准值寄存器


------------------------------------------------------------------------------------------------------------------------------------------------------


三、systick定时器原理


这个定时器是设置一个初值,然后这个初值减数到0,就是定时完成,完成之后可以产生中断,也可以不使用中断。



第0位是使能位,可以使能或者使能定时器


第1位是使能中断位,减数结束之后是否产生中断。


第2位是时钟选择位,可以选择外部的或者内部时钟作为时钟源。


第16位是标志位,减数到0之后该位被置位1,读取过后自动清清零。


------------------------------------------------------------------------------------------------------------------------------------------------------


四、uSysTick 重装载数值寄存器-LOAD



当当前值寄存器减数到0,自动会将把这个RELOAD的值赋给当前值寄存器。


if(VAL == 0)


    VAL = RELOAD


------------------------------------------------------------------------------------------------------------------------------------------------------


五、SysTick 当前值寄存器- VAL



VAL就是从初值(RELOAD)一直减一,倒数到0的时候,重新将初值(RELOAD)赋给VAL。


------------------------------------------------------------------------------------------------------------------------------------------------------


六、滴答定时器的实现


对于STM32,外部时钟源是HCLK(AHB总线时钟)的1/8内核时钟是HCLK时钟


1、选择时钟源


    SysTick_CLKSourceConfig();//选择时钟源 misc.c文件中



    SysTick_Config(uint32_t ticks) //初始化systick,时钟为HCLK,并开启中断 core_cm4.h文件中



2、编写延时函数


3、设置中断优先级分组


    NVIC_PriorityGroupConfig( NVIC_PriorityGroup_2);


    一般使用中断都需要在最开始对我们的优先级进行分组,分好之后再进行优先级的设置。


    尽量不要在同一个程序里面频繁的改变分组,频繁切换分组可能会使程序出现不可预料错误。


------------------------------------------------------------------------------------------------------------------------------------------------------


七、用中断的方式实现delay延时

Systick中断服务函数:void SysTick_Handler(void);



-----------------------------------------------------------------------------------------------------------------


注意:


  uCortex-M系统中,Systick代码可以通用。


  如果使用中发现延时不一致,问题一般都是因为不同内核时钟不一样而已。修改ticks值即可。


------------------------------------------------------------------------------------------------------------------------------------------------------


参考代码如下:


void init_delay(void)

{

    /*我们外部晶振为8MHz,然后倍频到168M,那么Systick时钟即为21M,也就是Systick的计数器

    VAL每减1就代表过了1/21us*/

 

    //1.选择时钟源(选择外部时钟)

    //外部时钟要/8,内部始终不用

    SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); 

}

 

//2.编写延时函数

//最大延时不超过798.915ms,即(2^24)/21/1000

void delay_us(u32 nus)

{

    u32 temp = 0;

 

    //1、实现1us*nus的延时

    //21外是外部时钟频率,如果选择内部时钟就是168M/8

    SysTick->LOAD = 21*nus;//设置自动装载值为21(1us)

    SysTick->VAL = 0x00;//设置当前初值为0

    SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; // 开启(使能)计数:使能SysTick定时器

 

    do

    {

        //读取控制寄存器

        temp = SysTick->CTRL;

    }while(!(temp & (1<<16)));//等待计数时间到达(位16)

 

    SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; // 关闭(失能)计数

    SysTick->VAL = 0x00;//再设置当前初值为0,重置VAL 

}

 

void delay_ms(u32 nms)

{

    u32 temp = 0;

 

    //1、实现1us*nus的延时

    SysTick->LOAD = 21000*nms;//设置自动装载值为21(1us)

    SysTick->VAL = 0x00;//设置当前初值为0

    SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; // 开启(使能)计数

 

    do

    {

        //读取控制寄存器

        temp = SysTick->CTRL;

    }while(!(temp & (1<<16)));

 

    SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; // 关闭(失能)计数

    SysTick->VAL = 0x00;//再设置当前初值为0 

}

 

void delay_s(u32 s)

{

    while(s--)

    {

        delay_ms(500);

        delay_ms(500);

    }

}

 

推荐阅读

史海拾趣

Franz Binder GmbH & Co公司的发展小趣事

Franz Binder GmbH & Co公司的发展故事

故事一:初创与奠基

Franz Binder GmbH & Co公司,简称宾德集团,成立于1960年,由Franz Binder在德国创立。起初,公司仅是一个机械加工车间,专注于加工车削件。然而,随着技术的不断积累和市场需求的增长,宾德开始专注于圆形连接器的生产。1967年,公司成功生产出第一只连接器,这标志着宾德正式进入连接器制造领域。此后,宾德不断投入研发,提升产品质量,逐渐在行业内崭露头角。

故事二:全球化布局

随着业务的不断扩展,宾德集团开始寻求全球化发展。1979年,宾德在瑞士成立了分公司Binder Electronic Components,标志着公司正式走向世界。此后,宾德在全球范围内迅速扩张,相继在美国、中国、法国、瑞典、英国、新加坡、荷兰和韩国等国家成立了子公司,并与全球45个经销商建立了合作关系。这一全球化布局不仅提升了宾德的品牌影响力,还为公司带来了更多的市场机会。

故事三:技术创新与产品多样化

宾德集团始终将技术创新视为企业发展的核心动力。公司不断投入研发资源,推出了一系列具有创新性的连接器产品。从微型连接器到电源连接器,再到医疗设备连接器和自动化技术连接器,宾德的产品线日益丰富,满足了不同行业的需求。特别是在工业自动化领域,宾德连接器以其高可靠性、高传输率和易于安装的特点,赢得了众多客户的青睐。

故事四:品质与认证

品质是宾德集团赖以生存和发展的基石。公司始终坚持高标准、严要求,确保每一件产品都符合国际质量标准。为此,宾德不仅通过了ISO 9001和ISO 14001等国际质量管理体系认证,还获得了UL、VDE和ESTI+等多项国际认证。这些认证不仅证明了宾德产品的卓越品质,也为客户提供了更多的信心和保障。

故事五:中国市场的发展

中国作为全球最大的电子市场之一,对宾德集团的发展具有重要意义。2001年,宾德在中国成立了全资子公司——南京宾德电气有限公司(宾德中国),负责中国地区的销售和客户服务。自成立以来,宾德中国凭借优质的产品和服务,迅速赢得了中国市场的认可。特别是在智能制造、自动化技术和医疗等领域,宾德连接器的应用越来越广泛,为中国电子行业的发展做出了积极贡献。

CHERRY公司的发展小趣事

1953年,一位名叫Walter Lorain CHERRY的德国年轻人在美国创立了Cherry公司,地点选在了一家餐厅的地下室。当时,Cherry的主要业务是生产微动开关,这种开关被广泛应用于各种电子设备中。Cherry的微动开关因其高品质和可靠性而赢得了市场的广泛认可,逐渐成为了行业内的佼佼者。

Crystal Semiconductor Corp公司的发展小趣事

近年来,随着人工智能、物联网等新兴技术的快速发展,半导体行业正面临着前所未有的变革。Crystal Semiconductor Corp积极应对这一挑战,加大了对新兴技术的研发投入,推出了一系列适应市场需求的新产品。同时,公司还加强了与上下游企业的合作,共同推动产业链的发展。

CDI-DIODE公司的发展小趣事

随着环保意识的日益增强,电子行业也开始向绿色生产转型。CDI-DIODE公司积极响应这一趋势,投入大量资源研发环保型二极管产品,并采用环保材料和生产工艺。这种绿色生产方式不仅降低了公司的生产成本,也符合了社会的可持续发展需求,为公司的未来发展奠定了坚实的基础。

这五个故事虽然是虚构的,但它们反映了电子行业中企业可能面临的一些共同挑战和机遇。无论对于CDI-DIODE公司还是其他企业,这些故事都具有一定的借鉴意义。

川晶科技公司的发展小趣事

在市场竞争日益激烈的背景下,川晶科技始终坚持创新驱动的发展战略。公司不断加大产品创新和自主研发的力度,推动产品向微型化、低耗能方向发展。通过引入新技术、新工艺,川晶科技成功开发出了一系列具有竞争力的新产品,满足了市场的多样化需求。同时,公司还积极探索新的应用领域,努力拓展市场空间,为公司的持续发展注入了新的动力。

Burr-Brown公司的发展小趣事

2000年,Burr-Brown被著名的美国德州仪器公司(Texas Instruments)收购,成为其高性能模拟器件部门的一部分。这一收购为Burr-Brown提供了更强大的资源和支持,使其能够继续专注于模拟器件(如ADC、DAC等)的生产和创新。在德州仪器的引领下,Burr-Brown持续保持技术领先,为全球电子行业的发展做出了重要贡献。

这五个故事共同展现了Burr-Brown公司从创立到发展壮大的历程,以及其在电子行业中的卓越成就和持续创新的精神。通过不断适应市场变化和技术进步,Burr-Brown成功地在竞争激烈的电子行业中脱颖而出,成为一家备受尊敬的企业。

问答坊 | AI 解惑

对噪声增益作斩波以实时测量运放失调电压

运算放大器的一个最重要的指标就是它的输入失调电压。对很多运放可以忽略这个电压,但问题是:失调电压会随着温度、闪烁噪声和长期漂移而改变。斩波与自动调零技术已经出现多年,它们能够将输入失调电压减小到微伏以下。这种技术的精度非常好,甚至 ...…

查看全部问答>

超声波测距精度有多高

想用超声波测量物体长度,长度范围大约几厘米到几十厘米不等 想听听有经验的大虾这方面的经验,测量精度能达到多少…

查看全部问答>

MCD2/ICD2菜鸟超级入门篇

本帖最后由 paulhyde 于 2014-9-15 09:37 编辑  …

查看全部问答>

键盘折叠式笔记本.我们中国人的设计

这款概念笔记本电脑是由中国设计师杨永昌设计的,160 x 106 x 18 mm的规格,是不是让你吓了一跳,光看外形跟普通的袖珍笔记本没什么差别,但是当你打开之后,才发现内藏玄机。 与屏幕链接的是一个折叠的无线键盘,并且每一个键位没有被缩小化, ...…

查看全部问答>

开发问题

请教一个初级问题:   wince中可以使用MFC,ATL,COM。他们可以同时使用吗?还是只能选一个。他们各有什么好处呢?…

查看全部问答>

★★★有wince开发经验的进来,我要买!★★★

★★★有wince开发经验的进来,我要买!★★★我想做一个wince或者linux的手持终端,做过的朋友加我聊聊价格,qq 15251276 ,手机:130 5197 1688,非诚勿扰。…

查看全部问答>

S3C2410技术交流QQ群

S3C2410技术交流QQ群68766459…

查看全部问答>

vb vc里的精确延时问题

vb里 1ms以下的延时怎么做啊 timer不行了 还有vb中的pc机的中断怎么实现啊 比如想用8259A做延时 用8号中断 vc里的也是同样的问题 TC我会 这两个不太会 想请教一下 谢谢啦~~…

查看全部问答>

谁做过无线通信模块(GW200KB),可以给个参考程序吗?

据说无线通信模块(GW200KB)能传输1.5Km,想用这个做个无线通信,看了一下说明书,只有引脚说明。谁能提供一个参考程序啊,谢谢啦…

查看全部问答>