淺析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;






免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM