历史上的今天
返回首页

历史上的今天

今天是:2025年07月17日(星期四)

正在发生

2018年07月17日 | STM32中sysTick的设置

2018-07-17 来源:eefocus


SysTick_Config(SystemFrequency / 10)   函数的形参就是systick重装定时器的值。



systck计数频率为每秒72000000次,所以7200000次就是1/10秒,也就是100ms。


SysTick是1个24bit递减计数器,通过对SysTick控制与状态寄存器的设置,可选择HCLK时钟(72M)或HCLK的8分频(9M,缺省是这个)作为SysTick的时钟源。

SysTick的重装寄存器决定了定时器频率。


若SysTick的时钟源是72M,   SystemFrequency = 72000000Hz

所以 SysTick_Config(SystemFrequency / 1000); 就是1ms时基。

//     1/1000 s=1ms





STM32中sysTick的设置(转) 


我不得不说意法半导体确实有点风骚!甚至有点变态。我对ST文档 STM32F10XXX参考手册的编辑水平真是不敢恭维。手册中好多说明都是含糊不清,甚至将好多对初学者来说很重要的地方都一笔带过,让人着实摸不着头脑。比如前面我说过的关于NVIC嵌套向量中断控制器的介绍,这部分我认为是非常重要的,但当你看完他这部分介绍,你根本不会设置中断服务程序,他有哪些寄存器都不知道,更别说去设置了,NVIC的详细介绍是在Cotex-M3中有详细的介绍,不多说。今天我们说的是systick定时器。 


systick定时器和我上面说的情况一样,在手册中根本没有介绍。我费了九牛二虎之力才在一个犄角格拉里找到systick定时器的英文版的说明。在Cotex-M3有介绍,为什么要找STM32的介绍,是因为功能设置上还有点区别。首先看一下systick定时器的作用,下面是Cotex-M3里的一段话: 

SysTick定时器被捆绑在NVIC中,用于产生SYSTICK异常(异常号:15)。在以前,大多操作系统需要一个硬件定时器来产生操作系统需要的滴答中断,作为整个系统的时基。例如,为多个任务许以不同数目的时间片,确保没有一个任务能霸占系统;或者把每个定时器周期的某个时间范围赐予特定的任务等,还有操作系统提供的各种定时功能,都与这个滴答定时器有关。因此,需要一个定时器来产生周期性的中断,而且最好还让用户程序不能随意访问它的寄存器,以维持操作系统“心跳”的节律。 

Cortex‐M3处理器内部包含了一个简单的定时器。因为所有的CM3芯片都带有这个定时器,软件在不同 CM3器件间的移植工作得以化简。该定时器的时钟源可以是内部时钟(FCLK,CM3上的自由运行时钟),或者是外部时钟( CM3处理器上的STCLK信号)。不过,STCLK的具体来源则由芯片设计者决定,因此不同产品之间的时钟频率可能会大不相同,你需要检视芯片的器件手册来决定选择什么作为时钟源。(知道我为什么找ST关于systick的说明了吧)。 

下面介绍STM32中的systick,Systick 部分内容属于NVIC控制部分,一共有4个寄存器,名称和地址分别是: 


STK_CSR,        0xE000E010  --  控制寄存器 

STK_LOAD,     0xE000E014  --  重载寄存器 

STK_VAL,        0xE000E018  --  当前值寄存器 

STK_CALRB,   0xE000E01C  --   校准值寄存器 

首先看STK_CSR控制寄存器:寄存器内有4个位t具有意义 


   




第0位:ENABLE,Systick 使能位  (0:关闭Systick功能;1:开启Systick功能) 

第1位:TICKINT,Systick 中断使能位    (0:关闭Systick中断;1:开启Systick中断) 

第2位:CLKSOURCE,Systick时钟源选择  (0:使用HCLK/8 作为Systick时钟;1:使用HCLK作为Systick时钟) 

第3位:COUNTFLAG,Systick计数比较标志,如果在上次读取本寄存器后,SysTick 已经数到了0,则该位为1。如果读取该位,该位将自动清零 


STK_LOAD  重载寄存器: 





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


  


STK_VAL当前值寄存器: 





也是个24位的寄存器,读取时返回当前倒计数的值,写它则使之清零,同时还会清除在SysTick 控制及状态寄存器中的COUNTFLAG 标志。 

STK_CALRB  校准值寄存器: 





这个寄存器好像目前的水平我还用不到,大体意思明白点,把英文说明放这吧: 

位31 NOREF :1=没有外部参考时钟(STCLK 不可用)0=外部参考时钟可用 

位30 SKEW:1=校准值不是准确的1ms 0=校准值是准确的1ms 

位[23:0] :Calibration value 

Indicates the calibration value when the SysTick counter runs on HCLK max/8 as external clock. The value is product dependent, please refer to the Product Reference Manual, SysTick Calibration Value section. When HCLK is programmed at the maximum frequency, the SysTick period is 1ms. If calibration information is not known, calculate the calibration value required from the frequency of the processor clock or external clock. 

SysTick定时器除了能服务于操作系统之外,还能用于其它目的:如作为一个闹铃,用于测量时间等。要注意的是,当处理器在调试期间被喊停(halt)时,则SysTick定时器亦将暂停运作。 

下面我们就应用SysTick定时器来裸奔,把它作为一个定时器来用,还是老一套,在寄存器头文件中添加定义寄存器: 

//***************************************************************** 

//*                               SystemTick-Register                                   

//******************************************************************* 

#define SYSTICK_TENMS    (*((volatile unsigned long *)0xE000E01C)) 

#define SYSTICK_CURRENT  (*((volatile unsigned long *)0xE000E018)) 

#define SYSTICK_RELOAD   (*((volatile unsigned long *)0xE000E014)) 

#define SYSTICK_CSR       (*((volatile unsigned long *)0xE000E010)) 

  


配置systick寄存器: 

void SysTick_Configuration(void) 

   SYSTICK_CURRENT=0; //当前值寄存器 

   SYSTICK_RELOAD=20000; //重装载寄存器,系统时钟20M中断一次1mS 

   SYSTICK_CSR|=0x06;// HCLK作为Systick时钟,Systick中断使能位 

 } 

中断处理: 

void SysTick_Handler(void) //中断函数 

extern unsigned long TimingDelay; // 延时时间,注意定义为全局变量 

  


SYSTICK_CURRENT=0; 

if (TimingDelay != 0x00) 

TimingDelay--; 

利用systick的延时函数: 

  


unsigned long TimingDelay;  // 延时时间,注意定义为全局变量 

void Delay(unsigned long nTime)  //延时函数 

SYSTICK_CSR|=0x07;   // 使能SysTick计数器 

TimingDelay = nTime; // 读取延时时间 

while(TimingDelay != 0); // 判断延时是否结束 

SYSTICK_CSR|=0x06;// 关闭SysTick计数器 

  


int main() 

 { 

  SystemInit0();    //系统(时钟)初始化 

 stm32_GpioSetup (); //GPIO初始化 


  SysTick_Configuration(); //配置systick定时器 


 while(1) 

 { 

  GPIO_PORTB_ODR|=(1<<5); 

Delay(1000); //1S 

 GPIO_PORTB_ODR&=~(1<<5); 

 Delay(1000); //1S                                                                                

  } 

完成!Delay(1000);实现了1S的精确延时,利用Delay(unsigned long nTime);配合systick定时器可以实现任意时间的精确延时,当然通过定时器TIMx也是可以这样做的,我只是用它来说明systick定时器的用法。 

__________________________

学习学习 kill stm32

2011-09-25,13:37:54

 资料  邮件  回复  引用回复   ↑↑   ↓↓         编辑  删除    

广告投诉、提议置酷等

提交

【1楼】 jan828 jan

积分:39

派别:

等级:------

来自:

 

STK_CSR控制寄存器 (原文件名:116357_1273766307pD7D.jpg?imageView2/2/w/550) 



 

STK_LOAD  重载寄存器 (原文件名:116357_1273766309wDDo.jpg?imageView2/2/w/550) 



 

STK_VAL当前值寄存器: (原文件名:116357_1273766310b3SW.jpg?imageView2/2/w/550) 



 

STK_CALRB  校准值寄存器: (原文件名:116357_12737663101BH1.jpg?imageView2/2/w/550) 

__________________________

学习学习 kill stm32

NVIC_SetPriority(SysTick_IRQn, n); 

n=0x00~0x03 设置Systick为抢占优先级0 

n=0x04~0x07 设置Systick为抢占优先级1 

n=0x08~0x0B 设置Systick为抢占优先级2 

n=0x0C~0x0F 设置Systick为抢占优先级3

 

NVIC_SetPriority函数指定中断优先级的寄存器位(STM32只用4位来表示优先级)的数据,例如中断优先级组设置为了2,即高2位用于指定抢占式优先级,低2位用于指定响应优先级,0x00~0x03高2位为0,所以抢占优先级为0;0x04~0x07高2位为1,所以抢占优先级为1,以此类推。  

 static __INLINE uint32_t SysTick_Config(uint32_t ticks)

  if (ticks > SYSTICK_MAXCOUNT)  return (1);                          


  SysTick->LOAD  =  (ticks & SYSTICK_MAXCOUNT) - 1;          

  NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);     

  SysTick->VAL   =  (0x00);                                                              

  SysTick->CTRL = (1 << SYSTICK_CLKSOURCE) | (1<

  return (0);                                                                            

}

这是这个函数的定义,在core_cm3.h里面,是有返回值的,如果你设置的SystemFrequency / 1000不符合该函数要求就会返回1,这样这个while循环是跳不出的,一直在循环,只有你设置的值符合要求,程序才能跳出循环继续执行,这句话一般在SysTick_Config(SystemCoreClock / 1000);这句之后,上面这句已经配置好Systick的定时时间为1ms,紧接着 while(SysTick_Config(SystemFrequency / 1000)); 是判断你配置的定时频率是否可以实现,如果可以就继续往下执行,如果不可以就一直停在这里。

SysTick_Config(uint32_t ticks):设置系统嘀嗒时钟并使能中断


在STM32中与CM3内核描述不太一样,这个时钟源有两个选择:AHB/8和AHB,在该函数中是选择了HCLK(SysTick_CTRL_CLKSOURCE_Msk),

所以定时时间=ticks / HCLK,当要定时10ms,而HCLK为24MHz时,ticks = 10000 * 24 = 240000。


如果需要选择HCLK/8,可以直接修改这个函数,或在这个函数后跟随misc中的SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)来设置。


推荐阅读

史海拾趣

ADPOW公司的发展小趣事

随着电源管理技术的不断成熟,ADPOW公司开始将技术应用于更多领域,推出了一系列创新产品。这些产品不仅在性能上有所提升,更在外观设计、用户体验等方面进行了优化。同时,公司积极拓展市场,与多家电子设备制造商建立合作关系,将产品广泛应用于手机、电脑、家电等领域。

Artaflex公司的发展小趣事

随着电子行业的快速发展,市场竞争日益激烈。为了保持领先地位,Artaflex公司积极寻求与其他企业的技术合作。通过与一家知名半导体公司的合作,双方共同研发了一款新型芯片,不仅提升了产品的性能,还降低了生产成本。这一合作不仅增强了Artaflex的技术实力,也为其打开了更广阔的市场空间。

ALPS公司的发展小趣事

在电子行业的初创时期,Artaflex公司以其敏锐的市场洞察力和技术创新能力脱颖而出。公司创始人凭借对电子技术的深入理解和前瞻性思维,带领团队开发了一款具有革命性的电子元件,极大地提高了电子设备的性能和稳定性。这一突破不仅为Artaflex赢得了市场的认可,也奠定了其在电子行业中的坚实地位。

AMICC [AMIC TECHNOLOGY]公司的发展小趣事

近年来,电子行业面临着技术升级、市场变革等多重挑战。AMICC积极应对这些挑战,不断调整战略和业务模式。公司加大了对新兴技术的研发投入,加快了产品更新换代的速度。同时,AMICC还加强了与产业链上下游企业的合作,共同应对市场变化。这些措施使AMICC在行业中保持了领先地位,实现了持续稳健的发展。

ADL [ADL Embedded Solutions Inc]公司的发展小趣事

近年来,电子行业面临着技术升级、市场变革等多重挑战。AMICC积极应对这些挑战,不断调整战略和业务模式。公司加大了对新兴技术的研发投入,加快了产品更新换代的速度。同时,AMICC还加强了与产业链上下游企业的合作,共同应对市场变化。这些措施使AMICC在行业中保持了领先地位,实现了持续稳健的发展。

CDI-DIODE公司的发展小趣事

在电子行业中,产品质量是企业生存和发展的关键。CDI-DIODE公司始终坚持品质至上的原则,从原材料采购到生产流程控制,再到产品检测,都严格把关。这种对品质的执着追求赢得了客户的信任和口碑,使公司在激烈的市场竞争中脱颖而出。

问答坊 | AI 解惑

一个嵌入式开发的资料(希望抛砖引玉)

嵌入式的开发如今是变的越来越复杂,对嵌入式工程师的要求越来越高。如何从一个应届毕业生, 或者普通的工程师向嵌入式迈进呢。网络上的资料很多,书店的书籍也很多,但大家都很难下手或者靠自学提高。 在最近的公司招聘面试的过程中,发现很多面试者( ...…

查看全部问答>

LCD501液晶屏电子钟和电压表程序

本帖最后由 paulhyde 于 2014-9-15 08:57 编辑 见附件  …

查看全部问答>

TMS320C6713DSP地址线问题

TMS320C6713DSP 地址线是20根吗?为什么它的标号是从EA2开始?(其地址标号为EA2-EA21) datasheet中所说的每个CE可选择128MB空间是怎么算出来的? 先谢谢您的答复!…

查看全部问答>

请问没有系统的UART编程和CE下的UART编程的区别?

撇开软件部分不说,单看硬件方面的设置: 1)基于ARM7裸机的串口简单的编程:如串口初始化,设置波特率,寄存器设置,中断向量设置等 2)自己基于CE下编一个串口驱动,也是要向上面一样设置ARM芯片的初始化吗?和裸机的那些设置是一样 ...…

查看全部问答>

求救,按键驱动

现在我想写一个2440的按键驱动,只需要几个按键就可以了,比较(上,下,左,右功能)。 要求能够传递给任意进程中,比如按上下左右键能够操作控制界面(UI)。 请问是不是只能在提供的标准的键盘驱动中写,有没有更简单的方法,哪位大哥给点思路呀…

查看全部问答>

ATMEGA8--想要爱你不容易!!

      在这夏天,炎热酷暑。在这夏天,躲在架设有几十台电脑的实验室,狭窄的空间,空气是凝固的,室内气温自然上去了。就这样,度过了一个刻骨铭心的暑假!然而,一个暑假下来,付出是多,收获也是多的。你们是否记得, ...…

查看全部问答>

高品质LED产品指标性能

replyreload += \',\' + 756734;Timson,如果您要查看本帖隐藏内容请回复…

查看全部问答>

IAR使用J-Link仿真的问题

我写了一个LM3S9B92的UART简单收发程序,想下载到开发板中,用的是IAR软件,和J-LINK仿真器,请高手指教一下具体的步骤,比如说软件的相关配置等等问题,谢了   我在下载的 过程中出现了这个问题 Fatal Error[Lc002]: could not open file ...…

查看全部问答>

STM32的页擦除的擦除范围

页擦除 闪存的任何一页都可以通过FPEC的页擦除功能擦除;擦除一页应遵守下述过程: 检查FLASH_SR寄存器的BSY位,以确认没有其他正在进行的闪存操作; 设置FLASH_CR寄存器的PER位为’1’; 用FLASH_AR寄存器选择要擦除的页; 设置FLASH_C ...…

查看全部问答>

关于自适应相干模板法的问题

小弟接触单片机编程不到一年,最近在尝试用自适应相干模板法做50HZ工频干扰信号的数字陷波器,照着《自适应相干模板法在5 1系列单片机中的实现》里的算法写了C代码,用430运行后发现,不管输入什么频率的信号,输出都差不多,就是一串奇怪的方波, ...…

查看全部问答>