zoukankan      html  css  js  c++  java
  • 浅析STM32 中常用的三个函数(sys.c,delay.c,usart.c)之二

    2.delay函数也是非常常用的函数

      提到delay延时,我就想到了STM32里面专门用来延时的systick定时器,常用 ck定时器是一个24位倒计数定时器,当计到0时,将从RELOAD寄存器重新自动装载初值。只要不把Systick的控制使能位及状态寄存器中的使能位清除,就会永不停息的工作。这个定时器的优点如下:

      1)不占用中断       2)也不占用系统定时器

    #include "delay.h"
    #include "stm32f10x.h"
    void delay_init()
    {
    
        SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);    //选择外部时钟  HCLK/8
        fac_us=SystemCoreClock/8000000;            //为系统时钟的1/8    f=72000000/8/(10^6)=9    t=(1/9)/10^6s  =(1/9)us
                                 //因此,时基fac_us=9,因为9*(1/9us)=1us,使滴答定时器计数9次就是1us
        fac_ms=(u16)fac_us*1000;               //fac_us*1000就是9000,9000*(1/9us)=1000us=1ms    
    
    
    //延时nus
    //nus为要延时的us数.                                               
    void delay_us(u32 nus)
    {        
        u32 temp;             
        SysTick->LOAD=nus*fac_us;                     //时间加载               
        SysTick->VAL=0x00;                            //清空计数器
        SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;    //开始倒数      
        do
        {
            temp=SysTick->CTRL;
        }while((temp&0x01)&&!(temp&(1<<16)));        //等待时间到达   
        SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;    //关闭计数器
        SysTick->VAL =0X00;                           //清空计数器     
    }
    //延时nms
    //注意nms的范围
    //SysTick->LOAD为24位寄存器,所以,最大延时为:
    //nms<=0xffffff*8*1000/SYSCLK
    //SYSCLK单位为Hz,nms单位为ms
    //对72M条件下,nms<=1864 
    void delay_ms(u16 nms)
    {                     
        u32 temp;           
        SysTick->LOAD=(u32)nms*fac_ms;                //时间加载(SysTick->LOAD为24bit)
        SysTick->VAL =0x00;                            //清空计数器
        SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;    //开始倒数  
        do
        {
            temp=SysTick->CTRL;
        }while((temp&0x01)&&!(temp&(1<<16)));        //等待时间到达   
        SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;    //关闭计数器
        SysTick->VAL =0X00;                           //清空计数器              
    } 

     此时,没有什么比一个权威的M3中文手册来说明更合适的了!!!

    这个是CTRL寄存器,即SysTick->CTRL所指向的寄存器,他是SysTick控制及状态寄存器。

    其中值得一提的是位0(使能位)以及位16(COUNTFLAG)

      SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数  

      在延时函数里面SysTick_CTRL_ENABLE_Msk的定义是#define SysTick_CTRL_ENABLE_Msk            (1ul << 0)

      其实就是把CTRL寄存器的位0(开始计数使能位)置1,方式是|=0x01. 

      SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器


    关闭计数器函数,通过把除使能位之外的位置1,使能位清零,即&=(~0x01)

    位16是SysTick定时器中的一个计数完成一周期的标志位,当SysTick定时器从装载值计到0时,读取该位就是1,读取该位之后该位置0.
    常用于等待计数程序中,当作计数结束标志位,表明已经计时规定时间。
     do
        {
            temp=SysTick->CTRL;
        }while((temp&0x01)&&!(temp&(1<<16)));        //等待时间到达



    SysTick->LOAD=(u32)nms*fac_ms;                //时间加载(SysTick->LOAD为24bit)
    SysTick->LOAD所指向的就是SysTick重装载数值寄存器,他的作用如他的描述所述,就是当SysTick定时器计数到0时,自动装载RELOAD
    SysTick重装载数值寄存器里面的值。



    SysTick->VAL =0x00;                            //清空计数器
    SysTick->VAL所指向的就是SysTick当前数值寄存器,他保存的是计数器当前的值,会随着倒计数一直不断变小。




    注意:
    fac_us 微妙级时基是计数到一微妙所要计数的次数
    f=72*(10^6)/8=9*(10^6)HZ=9MHZ    //SysTick 定时器的计数频率
    t=1/f=1/9us              //SysTick 定时器的计数时间
    fac_us=1us/t=1us/(1/9us)=9 //即9为微妙级时基
    而fac_us毫秒级时基是计数到一毫秒所要计数的次数
    fac_ms=1000*fac_us

    最大计时时间T
    SysTick->LOAD为24位寄存器,因此,最大装载值是0xFFFFFF,
    而T=0xFFFFFF*1/9us=1864135us=1864ms;





  • 相关阅读:
    数据结构矩阵问题总结
    数据结构:二维ST表
    mysql--时区表问题(Windows环境下)
    mysql--基本命令
    Django2.0--创建缓存表
    git--基本命令
    阿里云主机--重置系统后的登录问题
    链表中倒数第K个结点
    从尾到头打印链表
    替换空格
  • 原文地址:https://www.cnblogs.com/18689400042qaz/p/13377720.html
Copyright © 2011-2022 走看看