<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          STM32延時函數(shù)

          作者: 時間:2016-12-01 來源:網(wǎng)絡(luò) 收藏
          void delay_init(u8 SYSCLK)
          {
          SysTick->CTRL&=0xfffffffb;

          fac_us=SYSCLK/8;
          fac_ms=(u16)fac_us*1000;
          }

          Systick 主要的作用就是拿來計時,其原理和應(yīng)用簡述一下就是這樣的:通過配置寄存器 SysTick->CTRL來設(shè)定Systick的計時頻率并Enable使Systick開始計數(shù),這里的 SysTick->CTRL&=0xfffffffb應(yīng)該很好理解,把第2位設(shè)定為0,查找應(yīng)用手冊可以知道這是把Systick的計時頻率設(shè)定為CPU主頻(SYSCLK)的1/8。

          假定我們板子默認(rèn)的晶振頻率是8Mhz,默認(rèn)CPU工作頻率(SYSCLK)是9倍頻,即72M,那Systick的頻率就是72/8=9Mhz。

          知道了Systick的頻率,下一步就是確定倒時計數(shù)器的數(shù)值,即SysTick-> LOAD這個寄存器的配置。上面已經(jīng)知道了,Systick的工作頻率F=9Mhz=SYSCLK/8,即每秒鐘計數(shù)器自減900萬次,也就是說,SYSCLK/8次的自減耗時1秒,那么(8/SYSCLK)/1000,000次自減就耗時1微秒了,這也就是fac_us的值了。那么上面函數(shù)中的fac_us為什么是SYSCLK/8呢?這里先搞清楚一點,函數(shù)中SYSCLK的單位是Mhz,所以SYSCLK的值是72(這個以Mhz為單位應(yīng)該是STM32基礎(chǔ)庫里面做過宏定義的),否則也不可能用一個8位整形去表示一個7200萬的數(shù)值;而我們這里計算的SYSCLK是以Hz為單位的,即 72Mhz/1000,000=72,所以這個SYSCLK/8是對的。

          你可能還沒搞清楚 fac_us到底是干嘛的。很簡單,fac_us就是要寫入SysTick-> LOAD寄存器的值,Systick的工作原理是這個寄存器的值在Systick被Enable之后就開始以設(shè)定的工作頻率自減,減到0的時候就發(fā)出中斷,實現(xiàn)定時。所以,寫入fac_us到SysTick-> LOAD寄存器,就是要Systick在自減了fac_us次以后發(fā)出中斷,自減fac_us所耗的時間已經(jīng)說了,1微秒。

          下面的fac_ms應(yīng)該很好理解了,就是1毫秒的計數(shù)次數(shù),剛好是1微妙的1000倍,注意9×1000超出了8位整形的表示范圍,所以要用(u16)先把fac_us轉(zhuǎn)成16位變量,以保證計算的正確。

          具體的應(yīng)用函數(shù)是用來做延時,如下:

          void delay_us(u32 nus)
          {
          u32 temp;
          SysTick->LOAD=nus*fac_us; //時間加載
          SysTick->VAL=0x00; //清空計數(shù)器
          SysTick->CTRL=0x01 ; //Enable Systick,開始倒數(shù)
          do
          {
          temp=SysTick->CTRL;
          }
          while(temp&0x01&&!(temp&(1<<16)));//等待時間到達(dá)
          SysTick->CTRL=0x00; //Disable Systick

          SysTick->VAL =0X00; //清空計數(shù)器
          }

          具體的寄存器配置只要看手冊就知道了,這里只需要理解一句:

          do
          {
          temp=SysTick->CTRL;
          }
          while(temp&0x01&&!(temp&(1<<16)));//等待時間到達(dá)

          核心就是while(temp&0x01&&!(temp&(1<<16)));//等待時間到達(dá)

          temp 已經(jīng)是Systick控制寄存器的值了,temp&0x01就是把該寄存器的值讀出并且把除第一位之外位都清零(當(dāng)然要通過temp變量來傳遞值而不是直接修改寄存器),第一位就是Systick的Enable配置信息,寫入1就是Enable,寫入0就是Disable,讀這一位是判斷 Systick是否仍然處于Enable狀態(tài)(可能被其他中斷禁用掉),temp&(1<<16)就是讀取第16位的值,這一位如果為0就表示計數(shù)器的值不是0(即還在計數(shù)),如果是1就表示計數(shù)器已經(jīng)自減到0了。

          那么這段就很好理解了,即判斷,如果Systick還在Enable的狀態(tài),并且計數(shù)器還沒數(shù)到0,就不停的循環(huán)把當(dāng)前的 SysTick->CTRL寄存器值寫入變量temp,繼續(xù)下一次判斷。當(dāng)Systick被Disable或者計數(shù)器數(shù)到0了,就停止循環(huán)。因為只是做延時,也不需要跳到任何中斷服務(wù)那邊去處理什么,只要這個循環(huán)的耗時過程完成就可以了。


          關(guān)鍵詞: STM32延時函

          評論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();