STM32---系统滴答定时器(systick)应用

发布者:大头玩家最新更新时间:2019-05-22 来源: eefocus关键字:STM32  系统滴答定时器  systick 手机看文章 扫描二维码
随时随地手机看文章

利用stm32的系统滴答滴来获取系统的时间基准,以此应用到接收串口数据的超时退出。具体如下:


    current_sys_time = SysTick->VAL;(获取当前时间基准)。


    while (com_available(&rx_buffer1) < 1)

    { 

      //超时退出接收串口数据


    if((SysTick->VAL - current_sys_time) > Delay) 

      { 

        return TRUE; //

      }

    } 


以下转自:http://blog.csdn.net/yx_l128125/article/details/7884423


1.systick介绍


Systick就是一个定时器而已,只是它放在了NVIC中,主要的目的是为了给操作系统提供一个硬件上的中断(号称滴答中断)。滴答中断?这里来简单地解释一下。操作系统进行运转的时候,也会有“心跳”。它会根据“心跳”的节拍来工作,把整个时间段分成很多小小的时间片,每个任务每次只能运行一个“时间片”的时间长度就得退出给别的任务运行,这样可以确保任何一个任务都不会霸占整个系统不放。或者把每个定时器周期的某个时间范围赐予特定的任务等,还有操作系统提供的各种定时功能,都与这个滴答定时器有关。因此,需要一个定时器来产生周期性的中断,而且最好还让用户程序不能随意访问它的寄存器,以维持操作系统“心跳”的节律。 只要不把它在SysTick控制及状态寄存器中的使能位清除,就永不停息。


知道systick在系统中的地位后,我们来了解systick的实现。这里只是举例说明systick的使用。它有四个寄存器,笔者把它列出来:


    SysTick->CTRL,        --控制和状态寄存器


    SysTick->LOAD,        --重装载寄存器


    SysTick->VAL,          --当前值寄存器


   SysTick->CALIB,        --校准值寄存器    


下图有他们的分别描述:     下图引用地址:http://blog.csdn.net/marike1314/article/details/5673684


2.systick编程


    现在我们想通过Systick定时器做一个精确的延迟函数,比如让LED精确延迟1秒钟闪亮一次。


    思路:利用systick定时器为递减计数器,设定初值并使能它后,它会每个1系统时钟周期计数器减,计数到 0时,SysTick计数器自动重装初值并继续计数,同时触发中断。


那么每次计数器减到0,时间经过了:系统时钟周期 *计数器初值。我们使用72M作为系统时钟,那么每次计数器减1所用的时间是1/72M,计数器的初值如果是72000,那么每次计数器减到0,时间经过(1/72M)*72000= 0.001,即1ms。(简单理解:用72M的时钟频率,即1s计数72M=72000000次,那1ms计数72000次,所以计数值为72000) 


 


首先,我们需要有一个72M的systick系统时钟,那么,使用下面这个时钟OK就 !


    SystemInit();


    这个函数可以让主频运行到72M。可以把它作为systick的时钟源。


    接着开始配置systick,实际上配置systick的严格过程如下:


    1、调用SysTick_CounterCmd()       --失能SysTick计数器


    2、调用SysTick_ITConfig()          --失能SysTick中断


    3、调用SysTick_CLKSourceConfig()  --设置SysTick时钟源。


    4、调用SysTick_SetReload()         --设置SysTick重装载值。


    5、调用SysTick_ITConfig()          --使能SysTick中断


    6、调用SysTick_CounterCmd()       --开启SysTick计数器                                                      


    这里大家一定要注意,必须使得当前寄存器的值VAL等于0!


    SysTick->VAL  = (0x00);只有当VAL值为0时,计数器自动重载RELOAD。


接下来就可以直接调用Delay();函数进行延迟了。延迟函数的实现中,要注意的是,全局变量TimingDelay必须使用volatile,否则可能会被编译器优化。


下面我们来做一下程序分析:


(1)系统时钟进配置


首先我们对系统时钟进行了配置并且SetSysClock(void)函数使用72M作为系统时钟;


为了方面看清代码我选择截图:


(2)先来看看主函数


[plain] view plaincopy


int main(void)  

  

{            unsigned char i=0;  

  

        unsigned char a[] = "abncdee";  

  

          

  

        SystemInit1();//系统初始化  

  

   

  

       if (SysTick_Config(72000))  //1ms响应一次中断  

  

        {   

  

            /* Capture error */  

  

                 while (1);  

  

        }   

  

        /*解析:因为要求是每500ms往中位机发数据一件事,所以放在while语句中,  

  

*送据+延时可以完成相当于中断的效果;  

  

               *若是多任务中,其中一个任务需要中断,这把这个任务放在中断函数中调用;  

  

               */  

  

        while (1)  

  

        {  

  

             //测试代码:测试定时器功能,通过延时来测试  

  

   

  

             GPIO_SetBits(GPIOC, GPIO_Pin_6);      //V6  

  

             Delay(50);  

  

             GPIO_ResetBits(GPIOC, GPIO_Pin_6);         //V6  

  

             Delay(50);  

  

                        

  

            //功能1代码:每500ms发送数据  

  

               /*  

  

                      UART2_TX485_Puts("123450");  

  

                      Delay(500);  

  

           */  

  

            //功能2代码:上位发特定指令,中位机执行相应操作  

  

              //     RS485_Test();  

  

              }       

  

}  

(3)系统滴答定时器的配置--主角登场:


主函数中: SysTick_Config(72000) ;滴答定时器的参数是72000即计数72000


(因为我们使用72M的时钟频率,即1s计数72M=72000000次,那1ms计数72000次,所以计数值为72000) 


在文件Core_cm3.h中


SysTick_Config函数的具体实现如下:


[html] view plaincopy


static __INLINE uint32_t SysTick_Config(uint32_t ticks)  

  

{   

  

    if (ticks>SYSTICK_MAXCOUNT)    

  

     return (1);      /* Reload value impossible */  

  

    SysTick->LOAD = (ticks & SYSTICK_MAXCOUNT) - 1;//systick重装载值寄存器   /* set reload register */  

  

    NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts */  

  

    SysTick->VAL = (0x00);  //systick当前值寄存器                                

  

   /* Load the SysTick Counter Value */  

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

}                                         

我们来看一下这句代码:SysTick->CTRL = (1 << SYSTICK_CLKSOURCE) | (1<

下面我们来看一下stm32f10x_it.h文件中:


找到滴答定时器中断函数:SysTickHandler()


void SysTickHandler(void)


{


    TimingDelay_Decrement();


}


从上文我们通过装载的计数值72000知道每1ms发生一次中断,在中断函数中调用一个函数TimingDelay_Decrement();-----即每1ms发生中断时就调用到此函数;


下面我们来看看TimingDelay_Decrement();在干些什么?


[html] view plaincopy


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

  

*函数名称:TimingDelay_Decrement  

  

*功能描述:中断里调用此函数,即没发生一次中断,此函数被调用,此函数里       

  

*          的变量TimingDelay 相当于减法计数器  

  

*   

  

*输入参数:无  

  

*返回值:无  

  

*其他说明:无  

  

*当前版本:v1.0  

  

*作    者: 梁尹宣  

  

*完成日期:2012年8月3日  

  

*修改日期      版本号      修改人      修改内容  

  

*-----------------------------------------------------------------  

  

*  

  

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

  

     

  

void TimingDelay_Decrement(void)    

  

{    

  

    

  

  if (TimingDelay != 0x00)    

  

  {     

  

    TimingDelay--;    

  

  }  

  

}    

  

我们看了TimingDelay的定义,又看了还有哪些函数调用到这个变量,如下:  

  

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

  

*                                        全局变量  

  

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

  

   

  

static __IO uint32_t TimingDelay=0;  

  

           

  

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

  

*函数名称:    Delay  

  

*功能描述:    利用系统时钟计数器递减达到延时功能  

  

*   

  

*输入参数:nTime :需要延的时毫秒数  

  

*返回值:无  

  

*其他说明:无  

  

*当前版本:v1.0  

  

*作    者: 梁尹宣  

  

*完成日期:2012年8月3日  

  

*修改日期      版本号      修改人      修改内容  

  

*-----------------------------------------------------------------  

  

*  

  

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

  

   

  

void Delay(__IO uint32_t nTime)//delay被调用时,nTime=500  

  

{   

  

  TimingDelay = nTime;  

  

   

  

  while(TimingDelay != 0);  

[1] [2]
关键字:STM32  系统滴答定时器  systick 引用地址:STM32---系统滴答定时器(systick)应用

上一篇:STM32 systick做为系统时间使用(非简单延时)
下一篇:stm32 备份寄存器 读写数据

推荐阅读最新更新时间:2024-11-08 22:09

STM32 FSMC驱动TFTLCD 难点解析
本篇文章三个主题:FSMC有关配置、一串字符显示原理、汉字显示原理。。下面进入正题 一、FSMC的有关配置(博主用的是FSMC_A10): 来自别人家的博客http://blog.csdn.net/jxnu_xiaobing/article/details/8718566 FSMC的介绍就不介绍了,网上一大片。我们就讨论讨论为什么用FSMC的地址线与TFTLCD的RS引脚相连?以及我们如何往LCD写数据/命令? FSMC称为可变静态存储控制器。可变:之所以称为“可变”,是由于通过对特殊功能寄存器的设置,FSMC 能够根据不同的外部存储器类型,发出相应的数据/地址/控制信号类型以匹配信号的速度。(这点很重要,后文会
[单片机]
STM32SYSTICK_Init()配置
void SYSTICK_Init(void) { /* SysTick end of count event each 1ms with input clock equal to 4.5MHz (HCLK/8, default) SysTick_SetReload(4500); /* Enable SysTick interrupt SysTick_ITConfig(ENABLE); /* Enable the SysTick Counter SysTick_CounterCmd(SysTick_Counter_Enable); } 系统时钟定时器的周期与驱动的时钟频率和Reload值相关。
[单片机]
基于STM32 MCU的太阳能-LED街灯解决方案
随着化石类能源的日益减少,以及温室气体的过度排放导致全球变暖问题越来越受到重视,人们一方面在积极开发各类可再生新能源,另一方面也在倡导节能减排的绿色环保技术。太阳能作为取之不尽、用之不竭的清洁能源,成为众多可再生能源的重要代表;而在照明领域,寿命长、节能、安全、绿色环保、色彩丰富、微型化的LED固态照明也已被公认为世界一种节能环保的重要途径。太阳能-LED街灯同时整合了这两者的优势,利用清洁能源以及高效率的LED实现绿色照明。 本文介绍的太阳能-LED街灯方案,能自动检测环境光以控制路灯的工作状态,最大功率点追踪(MPPT)保证最大太阳能电板效率,恒电流控制LED,并带有蓄电池状态输出以及用户可设定LED工作时间等功能。
[单片机]
基于<font color='red'>STM32</font> MCU的太阳能-LED街灯解决方案
stm32实现LED灯亮灭
一、概述 本章中,不特殊说明都以stm32F103VET6为例,软件平台为iar6.4 通过查看原理图,我们的LED指示灯配置在PB8、PB9管脚上,通过配置GPIOB时钟及引脚来控制指示灯的亮灭。 二、本章学习目标 学会查看原理图 理解stm32端口配置 学会操作使用iar编程工具 三、GPIO端口配置 1.配置开启GPIO时钟 STM32上电时外设时钟默认不开启,用要时需要先开启时钟,本例开启GPIOA和GPIOB的时钟。 参考代码: RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2
[单片机]
<font color='red'>stm32</font>实现LED灯亮灭
stm32的存储器结构
首先,先看一下stm32的存储器结构。 Flash,SRAM寄存器和输入输出端口被组织在同一个4GB的线性地址空间内。可访问的存储器空间被分成8个主要块,每个块为512MB。FLASH存储下载的程序,FLASH是ROM的一种。SRAM是存储运行程序中的数据,SRAM是RAM的一种。所以,只要你不外扩存储器,写完的程序中的所有东西也就会出现在这两个存储器中。 1. STM32中的堆栈。 首先要说明的是单片机是一种集成电路芯片,集成CPU、RAM、ROM、多种I/O口和中断系统、定时器/计数器等功能。CPU中包括了各种总线电路,计算电路,逻辑电路,还有各种寄存器。Stm32有通用寄存器R0‐R15 以及一些特殊功能寄
[单片机]
<font color='red'>stm32</font>的存储器结构
STM32 AT24C128简单读写程序
目前个人测试过AT24C02-AT24C128,感觉还可以。里面没有页写函数,有兴趣的伙伴可以补充一下,该程序仅供参考 单片机源程序如下: #include led.h #include delay.h #include sys.h #include usart.h #include key.h #include 24cxx.h #include myiic.h //要写入到24c128的字符串数组 const u8 TEXT_Buffer ={ STM32 AT24c128 }; #define SIZE sizeof(TEXT_Buffer) #define ADDRESS 163 //读
[单片机]
STM32-GPRS模块连接系统主站
一、GPRS基础讲解(GSM/CDMA/GPRS介绍) 1、通信专业术语 BSS--基站子系统,通过无线接口与移动台直接联系,负责在一定区域内和移动台通信。(GSM) BTS--基站收发台,可以看作一复杂的无线调制器,BSS的主要部分,每个分配有若干信道。(GSM) RBS--Radio Base Station,无线基站:RBS是基站内所有设备的总称,在GSM规范中对应的主要部分是BTS,它由BSC来控制,用来提供移动台与系统的无线接口,它是CME20系统中的无线设备部分,主要由无线收发信机构成。 BSC--基站控制器,其功能是作为无线电设备与MSC的控制和通信的接口,直接控制BTS。(GSM) GPRS--Ge
[单片机]
STM32-GPRS模块连接<font color='red'>系统</font>主站
STM32之Flash
1. 在默认情况下,只有执行FLASH设置(延迟,预取指,半周期)的函数式允许执行的。 如果想要执行FLASH编写/擦除/保护函数,必须在文件“stm32f10x_conf.h”中定义_FLASH_PROG如下: #define _FLASH_PROG 2.按照不同容量,存储器组织成32个1K字节/页(小容量)、128个1K字节/页(中容量),万利板子是中容量 #define FLASH_PAGE_SIZE ((u16)0x400) //一页为1024个字节 3. /* Get pages write protection status */ WRPR_Value = FLASH_GetWriteProte
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved