stm32f103c8t6资源 systick时钟问题

查看: 40411|回复: 4
STM32的SYSTICK详解
什么是SYSTICK:
这是一个24位的系统节拍定时器system tick timer,SysTick,具有自动重载和溢出中断功能,所有基于Cortex_M3处理器的微控制器都可以由这个定时器获得一定的时间间隔。作用:在单任务引用程序中,因为其架构就决定了它执行任务的串行性,这就引出一个问题:当某个任务出现问题时,就会牵连到后续的任务,进而导致整个系统崩溃。要解决这个问题,可以使用实时操作系统(RTOS).因为RTOS以并行的架构处理任务,单一任务的崩溃并不会牵连到整个系统。这样用户出于可靠性的考虑可能就会基于RTOS来设计自己的应用程序。这样SYSTICK存在的意义就是提供必要的时钟节拍,为RTOS的任务调度提供一个有节奏的“心跳”。微控制器的定时器资源一般比较丰富,比如STM32存在8个定时器,为啥还要再提供一个SYSTICK?原因就是所有基于ARM Cortex_M3内核的控制器都带有SysTick定时器,这样就方便了程序在不同的器件之间的移植。而使用RTOS的第一项工作往往就是将其移植到开发人员的硬件平台上,由于SYSTICK的存在无疑降低了移植的难度。
&&SysTick定时器除了能服务于操作系统之外,还能用于其它目的:如作为一个闹铃,用于测量时间等。要注意的是,当处理器在调试期间被喊停(halt)时,则SysTick定时器亦将暂停运作。
时钟的选择:用户可以在位于Cortex_M3处理器系统控制单元中的系统节拍定时器控制和状态寄存器(SysTick control and status register ,SCSR)选择systick 时钟源。如将SCSR中的CLKSOURCE位置位,SysTick会在CPU频率下运行;而将CLKSOUCE位清除则SysTick会以CPU主频的1/8频率运行。3.5版本的库函数与以往的有所区别不存在stm32f10x_systick.c文件,故原来的一些函数也不存在,比如SysTick_SetReload(u32 reload);SysTick_ITConfig(FunctionalState NewState);等
在3.5版本的库函数中与systick相关的函数只有两个第一个,SysTick_Config(uint32_t ticks),在core_cm3.h头文件中进行定义的。第二个,void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource),在misc.c文件中定义的。
SysTick_Config(uint32_t ticks),在core_cm3.h主要的作用:1、初始化systick2、打开systick3、打开systick的中断并设置优先级4、返回一个0代表成功或1代表失败注意:Uint32_t ticks&&即为重装值,这个函数默认使用的时钟源是AHB,即不分频。要想分频,调用void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource),但是要注意函数调用的次序,先SysTick_Config(uint32_t ticks),后SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)
函数说明:
/** * @brief&&Initialize and start the SysTick counter and its interrupt. * * @param& &ticks& &number of ticks between two interrupts * @return&&1 = failed, 0 = successful * * Initialise the system tick timer and its interrupt and start the * system tick timer / counter in free running mode to generate
* periodical interrupts. */static __INLINE uint32_t SysTick_Config(uint32_t ticks){ &&if (ticks & SysTick_LOAD_RELOAD_Msk)&&return (1);& && && && &&&/* Reload value impossible */重装载值必须小于0XFF FFFF,为什么,这是一个24位的递减计数器。
&&SysTick-&LOAD&&= (ticks & SysTick_LOAD_RELOAD_Msk) - 1; & &&&/* set reload register */设置重装载值,SysTick_LOAD_RELOAD_Msk定义见后面&&NVIC_SetPriority (SysTick_IRQn, (1&&__NVIC_PRIO_BITS) - 1);
/* set Priority for Cortex-M0 System Interrupts */&&SysTick-&VAL& &= 0; &&/* Load the SysTick Counter Value */&&SysTick-&CTRL&&= SysTick_CTRL_CLKSOURCE_Msk | & && && && && && & SysTick_CTRL_TICKINT_Msk& &| & && && && && && & SysTick_CTRL_ENABLE_M& && && && && && &
/* Enable SysTick IRQ and SysTick Timer */&&return (0);&&/* Function successful */}#endif与systick相关的寄存器定义
/** @addtogroup CMSIS_CM3_SysTick CMSIS CM3 SysTick&&memory mapped structure for SysTick&&@{ */typedef struct{&&__IO uint32_t CTRL; /*!& Offset: 0x00&&SysTick Control and Status Register */&&__IO uint32_t LOAD; /*!& Offset: 0x04&&SysTick Reload Value Register& && & */&&__IO uint32_t VAL; /*!& Offset: 0x08&&SysTick Current Value Register& && &*/&&__I&&uint32_t CALIB; /*!& Offset: 0x0C&&SysTick Calibration Register& && &&&*/} SysTick_T
与systick寄存器相关的寄存器及位的定义
/* SysTick Control / Status Register Definitions */控制/状态寄存器#define&&SysTick_CTRL_COUNTFLAG_Pos&&16& && &/*!& SysTick CTRL: COUNTFLAG Position */
#define SysTick_CTRL_COUNTFLAG_Msk& && && &(1ul && SysTick_CTRL_COUNTFLAG_Pos)& && && &/*!& SysTick CTRL: COUNTFLAG Mask */ 溢出标志位
#define SysTick_CTRL_CLKSOURCE_Pos& &2& && & /*!& SysTick CTRL: CLKSOURCE Position */#define SysTick_CTRL_CLKSOURCE_Msk& && && &(1ul && SysTick_CTRL_CLKSOURCE_Pos)&&/*!& SysTick CTRL: CLKSOURCE Mask */时钟源选择位,0=外部时钟;1=内核时钟
#define SysTick_CTRL_TICKINT_Pos& && &1& && &&&/*!& SysTick CTRL: TICKINT Position */#define SysTick_CTRL_TICKINT_Msk& && && &&&(1ul && SysTick_CTRL_TICKINT_Pos)& && && & /*!& SysTick CTRL: TICKINT Mask */异常请求位
#define SysTick_CTRL_ENABLE_Pos& && && && & 0& && & /*!& SysTick CTRL: ENABLE Position */#define SysTick_CTRL_ENABLE_Msk& && && && &(1ul && SysTick_CTRL_ENABLE_Pos)& && && && && &/*!& SysTick CTRL: ENABLE Mask */使能位
/* SysTick Reload Register Definitions */#define SysTick_LOAD_RELOAD_Pos& && && && & 0& & /*!& SysTick LOAD: RELOAD Position */#define SysTick_LOAD_RELOAD_Msk& && && && &(0xFFFFFFul && SysTick_LOAD_RELOAD_Pos)& && &&&/*!& SysTick LOAD: RELOAD Mask */
/* SysTick Current Register Definitions */#define SysTick_VAL_CURRENT_Pos& && && && & 0& && & /*!& SysTick VAL: CURRENT Position */#define SysTick_VAL_CURRENT_Msk& && && && &(0xFFFFFFul && SysTick_VAL_CURRENT_Pos)& && &&&/*!& SysTick VAL: CURRENT Mask */
/* SysTick Calibration Register Definitions */#define SysTick_CALIB_NOREF_Pos& && && && &31& && &/*!& SysTick CALIB: NOREF Position */#define SysTick_CALIB_NOREF_Msk& && && && &(1ul && SysTick_CALIB_NOREF_Pos)& && && && &&& /*!& SysTick CALIB: NOREF Mask */
#define SysTick_CALIB_SKEW_Pos& && && && & 30& && & /*!& SysTick CALIB: SKEW Position */#define SysTick_CALIB_SKEW_Msk& && && && & (1ul && SysTick_CALIB_SKEW_Pos)& && && && && & /*!& SysTick CALIB: SKEW Mask */
#define SysTick_CALIB_TENMS_Pos& && && && & 0& && & /*!& SysTick CALIB: TENMS Position */#define SysTick_CALIB_TENMS_Msk& && && && &(0xFFFFFFul && SysTick_VAL_CURRENT_Pos)& && &&&/*!& SysTick CALIB: TENMS Mask *//*@}*/ /* end of group CMSIS_CM3_SysTick */
与systick相关的寄存器的说明
void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)作用:选择systick的时钟源,AHB时钟或AHB的8分频默认使用的是AHB时钟,即72MHz
函数说明:/**&&* @brief&&Configures the SysTick clock source.&&* @param&&SysTick_CLKSource: specifies the SysTick clock source.&&*& &This parameter can be one of the following values:&&*& &&&@arg SysTick_CLKSource_HCLK_Div8: AHB clock divided by 8 selected as SysTick clock source.&&*& &&&@arg SysTick_CLKSource_HCLK: AHB clock selected as SysTick clock source.&&* @retval None&&*/void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource){&&/* Check the parameters */&&assert_param(IS_SYSTICK_CLK_SOURCE(SysTick_CLKSource));&&if (SysTick_CLKSource == SysTick_CLKSource_HCLK)&&{& & SysTick-&CTRL |= SysTick_CLKSource_HCLK;&&}&&else&&{& & SysTick-&CTRL &= SysTick_CLKSource_HCLK_Div8;&&}}
Systick时钟源的定义:/** @defgroup SysTick_clock_source &&* @{&&*/
#define SysTick_CLKSource_HCLK_Div8& & ((uint32_t)0xFFFFFFFB)//将控制状态寄存器的第二位置0,即用外部时钟源#define SysTick_CLKSource_HCLK& && && &((uint32_t)0x)//将控制状态寄存器的第二位置1,即用内核时钟#define IS_SYSTICK_CLK_SOURCE(SOURCE) (((SOURCE) == SysTick_CLKSource_HCLK) || \& && && && && && && && && && && && && &((SOURCE) == SysTick_CLKSource_HCLK_Div8))
Systick定时时间的设定:
重装载值=systick 时钟频率(Hz)X想要的定时时间(S)如:时钟频率为:AHB的8分频;AHB=72MHz那么systick的时钟频率为72/8MHz=9MHz;要定时1秒,则重装载值==9000000;定时10毫秒重状态值=.01=90000Systick的中断处理函数,在startup_stm32f10x_hd.s启动文件中有定义。DCD& &&&SysTick_Handler& && && && &; SysTick Handler根据需要直接编写中断处理函数即可:Void SysTick_Handler (void){ ;}注意:如果在工程中,加入了stm32f10x_it.c,而又在主函数中编写中断函数,则会报错。
因为在stm32f10x_it.c文件中,也有这个中断函数的声明,只是内容是空的。/**&&* @brief&&This function handles SysTick Handler.&&* @param&&None&&* @retval None&&*/void SysTick_Handler(void){}
中断优先级的修改在调用SysTick_Config(uint32_t ticks)之后,调用 void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)。这个函数在core_cm3.h头文件中。具体内容如下:
/** * @brief&&Set the priority for an interrupt * * @param&&IRQn& && &The number of the interrupt for set priority * @param&&priority&&The priority to set * * Set the priority for the specified interrupt. The interrupt
* number can be positive to specify an external (device specific)
* interrupt, or negative to specify an internal (core) interrupt. * * Note: The priority cannot be set for every core interrupt. */
static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority){&&if(IRQn & 0) {& & SCB-&SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority && (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M3 System Interrupts */&&else {& & NVIC-&IP[(uint32_t)(IRQn)] = ((priority && (8 - __NVIC_PRIO_BITS)) & 0xff);& & }& && &&&/* set Priority for device specific Interrupts&&*/}
下面以一个实例来说明:利用systick来实现以1秒的时间间隔,闪亮一个LED指示灯,指示灯接在GPIOA.8,低电平点亮。
#include &stm32f10x.h&//函数声明void GPIO_Configuration(void);//设置GPIOA.8端口u32//定义一个全局变量int main(void){ // SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);& && & SysTick_Config(9000000);& && & SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);& && & GPIO_Configuration();& && & while(1);& && & }
//GPIOA.8设置函数void GPIO_Configuration(void){ GPIO_InitTypeDef&&GPIO_InitS//定义一个端口初始化结构体& && & RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//打开GPIOA口时钟& && & GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;//设置为推挽输出& && & GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;//设置输出频率50M& && & GPIO_InitStruct.GPIO_Pin=GPIO_Pin_8;//指定第8脚& && & GPIO_Init(GPIOA,&GPIO_InitStruct);//初始化GPIOA.8& && & & && & GPIO_SetBits( GPIOA,&&GPIO_Pin_8);//置高GPIOA.8,关闭LED}//systick中断函数void SysTick_Handler(void){ t++;& && & if(t&=1)& && & {& && && && &&&if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8)==1)& && && && &&&{GPIO_ResetBits( GPIOA, GPIO_Pin_8);}& && & & && & }& && & if(t&=2)& && & {& && && && &&&if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8)==0)& && && && && && && &{GPIO_SetBits( GPIOA, GPIO_Pin_8);}& && && && && && && &t=0;& && & }}
模拟后的结果1、8分频后结果
2、直接调用SysTick_Config(9000000);即不分频的结果,间隔为1/8=0.125s
总结:1、要使用systick定时器,只需调用SysTick_Config(uint32_t ticks)函数即可,& &自动完成了,重装载值的装载,时钟源选择,计数寄存器复位,中断优先级的设置(最低),开中断,开始计数的工作。2、要修改时钟源调用SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)。3、要修改中断优先级调用& &&&void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)应用说明:1、因systick是一个24位的定时器,故重装值最大值为2的24次方=16 777 215,& &要注意不要超出这个值。2、systick是cortex_m3的标配,不是外设。故不需要在RCC寄存器组打开他的时钟。3、每次systick溢出后会置位计数标志位和中断标志位,计数标志位在计数器重装载后被清除,而中断标志位也会随着中断服务程序的响应被清除,所以这两个标志位都不需要手动清除。4、采用使用库函数的方法,只能采用中断的方法响应定时器计时时间到,如要采用查询的方法,那只能采用设置systick的寄存器的方法,具体操作以后再做分析。
systick的寄存器操作比较灵活可控!
滴答还是比较方便使用的~
分析的很详细,值得学习
好好好,51黑有你更精彩!!!
Powered by电力改变了世界,也造福了我们的生产生活。电力安全大于……
近日尼吉康在北京召开了关于锂离子二次电池的新品发布会……
1930年首届世界杯没有预选赛,只有13支国家队报名参赛。……
秉承&创新&的设计理念,罗德与施瓦茨公司不……
作为业界最强大的电源技术供应商Vicor最近有点忙,自从谷……
演讲人:黄科涛时间: 10:00:00
演讲人:Tracy Ma时间: 10:00:00
演讲人:Jim时间: 10:00:00
预算:小于¥10000预算:¥50000
广东省江苏省
STM32入门学习之_SysTick_Config()函数的SysTick时钟配置
[导读]上来就是systick定时器,因为GPIO等的基础操作过于简单,网上资料太多了。这里讨论的是基于STM32F10x 的基于 V3.5.0库的库函数配置方法。Systick又叫系统嘀答定时器,是一个24位的硬件定时器。嵌入式操作系统常有一个
上来就是systick定时器,因为GPIO等的基础操作过于简单,网上资料太多了。这里讨论的是基于STM32F10x 的基于 V3.5.0库的库函数配置方法。Systick又叫系统嘀答定时器,是一个24位的硬件定时器。嵌入式操作系统常有一个类似“心跳”的定时器,来分配时间片,实现宏观上的多任务。其实,操作系统的多任务,在微观上,CPU对多任务的管理是分时的。每个任务都给一定的时间片,就是把时间分成N个等份,优先级高或是重要的任务多占几个时间片,优先级低的或是不重要的任务就少占几个时间片。大部分嵌入式操作系统基于时间片的。如ucos。那基于STM32F10x V3.5.0库如何操作Systick定时器呢。首先: 的内核库已经提供了这个功能。只要配置SysTick_Config()即可实现。看下面的程序段。/** 函数名:SysTick_Init* 描述
:启动系统滴答定时器 SysTick* 输入 : 无* 输出 :无* 调用 : 外部调用*/void SysTick_Init(void){
if(SysTick_Config(SystemCoreClock/1000))
//1ms定时器
//SysTick->CTRL &= ~SysTick_CTRL_ENABLE_M
//若无法启动则关闭}SysTick_Config的参数,其实就是一个时钟次数,叫systick重装定时器的值。意思就是我要多少个1/fosc 时间后中断一下。根据学过的物理中的时间与频率的公式:fosc=1/T
T=1/fosc ,fosc为系统的频率。如果时钟频率为:72MHz,每次的时间为:T=1/72MHz。1秒钟为:1/(每次的时间)=1/(1/72MHz)=72 000 000次。1MHz是:。反过来讲。SysTick_Config(72000)代表:72000*(1/72MHz)=1/1000=1(ms)。即定时为1ms。如果需要1S则,可以通一设置一个全局变量,然后定初值得为1000,这样,每个systick中断一次,这个全局变量减1,减到0,即systick中断1000次,时间为:1ms*1000=1S。从而实现1S的定时。本文引用地址: 因为SysTick定时器是:24位的,最大定时时间为:2的24次方*(1/72MHz)的时间,这里系统频率为:72MHz的情况下。如何使用这个Systick用于程序设计上的延时或是定时作用呢?如下:__IO uint32_t TimingD定义一个全局变量,注意类型为 volatile的。volatile的作用: 作为指令关键字,确保本条指令不会因为编译器的优化而省略,且要求每次直接读值.然后定义一个延时或是定时函数:/** 函数名:Delay_ms* 描述
:ms延时程序,1ms为一个单位* 输入 : - nTime* 输出 :无* 示例 : Delay_ms(1) 实现的延时为:1*ms=1ms* 调用 :外部调用*/void Delay_ms(uint16_t nTime){
TimingDelay = nT
//使能系统滴答定时器
while(TimingDelay !=0);}
还要在系统的中断函数文件:stm32f10x_it.c/h里面,修改系统自带的systick函数。这个函数要么没有声明或是为空操作。这里加入定时延时里的处理。
即中断后,全局变量做个--处理即可。
在::stm32f10x_it.c里修改如下:添加外部的声明:extern __IO uint32_t TimingD
修改这个函数: SysTick_Handler,这是系统的关于SysTick_Handler的中断服务程序名,在启动文件里如:startup_stm32f10x_hd.s
有它的定义的名字。不要弄错了。否则无法中断处理。/** * @brief This function handles SysTick Handler. * @param None * @retval None */void SysTick_Handler(void){if (TimingDelay != 0x00)
TimingDelay--;
以上,即定义配置好了Systick定时器。如何使用呢?很简单。
Delay_ms(500); 即为延时500ms。
当然,使用前,请先初始化:SysTick_Init();
否则无法使用并影响后续的程序运行,这个很重要,就像打开了串口中断,你不清标志位,也同样在接收字符后,CPU中断在那里,而不能继续执行!。使用外设功能,需要初始化!以上基本讲完了。主要是加入了自己的理解。以下为搜索的一些其他理解。SysTick_Config(SystemFrequency / 10)
函数的形参就是systick重装定时器的值。systck计数频率为每秒次,所以7200000次就是1/10秒,也就是100ms。SysTick是1个24bit递减计数器,通过对SysTick控制与状态寄存器的设置,可选择HCLK时钟(72M)或HCLK的8分频(9M,缺省是这个)作为SysTick的时钟源。SysTick的重装寄存器决定了定时器频率。若SysTick的时钟源是72M,
SystemFrequency = Hz所以 SysTick_Config(SystemFrequency / 1000); 就是1ms时基。
贸泽电子(Mouser Electronics) 开始分销Netduino 3电子平台,能够使商业硬件解决方案和个人电子项目快速上市,同时提供了最大的设计灵活性并降低了风险。最新版本的开源Netduino平台不但具有让先前版本广受欢迎的最佳......关键字:
意法半导体(STMicroelectronics,简称ST;纽约证券交易所代码:STM)宣布正式收购专业软件开发公司Draupner Graphics。Draupner Graphics是TouchGFX软件框架的开发商和供应商。......关键字:
中国,日――通过使最新的STM32 PMSM FOC软件开发套件(SDK)支持STM32Cube开发生态系统(订货代码: X-CUBE-MCSDK),意法半导体进一步简化在STM32* 微控制器上开发先进的高能效电机驱动器......关键字:
Arm平台安全架构(PSA)采用高性价比、领先技术全面提升物联网市场的安全技术支持
基于STM32H7系列开发的Arm® Cortex®-M7微控制器整合PSA概念和先进的安全功能服务......关键字:
马上就到一年一度的2018年春节了,金三银四,而春节过后往往是跳槽的高峰期.作为一名程序员,应该如何准备自己的简历呢?我们程序员一般在什么时机需要更新简历呢?......关键字:
一名曾在谷歌任职13年的工程师周三对该公司提出批评,他指责这家科技巨头“100%关注竞争对手”,还认为它“已经无力创新”。这位工程师名叫史蒂夫?耶格(SteveYegge),2005年从亚马逊跳槽到谷歌。他在博文中谈到自己离开谷歌的决定时说......关键字:
我 要 评 论
热门关键词
深圳市中悦科技有限公司25K-35K | 广东省 深圳市
深圳市中悦科技有限公司10K-15K | 广东省 深圳市
深圳安科高技术股份有限公司南京分公司面议 | 江苏省 南京市
北京建工京精大房工程建设监理公司深圳市分公司6K-8K | 广东省 深圳市
深圳金鑫世纪实业有限公司8K-10K | 广东省 深圳市查看: 16298|回复: 0
stm32F103的systick时间不准终于找到原因了
& &主函数已经定义SysTick_Config(0);但是中断void SysTick_Handler(void) 中PIO引脚闪烁的时间总感觉不对,最后在sdk中观察systick寄存器发现ctrl一直为0x,本来默认的是系统时钟/8为systick的时钟,我已经在主函数中更改为SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);了,
psb(13).jpeg (30.63 KB, 下载次数: 63)
06:10 上传
psb(14).jpeg (97.95 KB, 下载次数: 76)
06:10 上传
但是CTRL就是没有改变,看SysTick_Config,“systick_ctrl _clksource_msk”(红色部分)已经指出需要添加SysTick_CLKSource_HCLK,害得我搞了一晚上,都是E文差文化低害的。。。。。。!当然也可以在主函数内加SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);,但是是在SysTick_Config(0);后加而不是之前。
Powered by

我要回帖

更多关于 stm32systick不准 的文章

 

随机推荐