国产毛片a精品毛-国产毛片黄片-国产毛片久久国产-国产毛片久久精品-青娱乐极品在线-青娱乐精品

嵌入式里的“延遲”

發布時間:2016-2-17 08:43    發布者:designapp
關鍵詞: 嵌入式 , C語言
  前些天在版主群里有人問“有沒有好用的延遲函數啊?”我的第一反應就是“延遲函數要視自己的應用而編寫,不可能千篇一律的應用。”可是回首一看,單片機的發展歷程,在不同時期里有著不一樣的延遲函數。
  在版主上學的年代里,單片機課程老師對匯編語言有著非常深入的了解,如XX指令是單指令周期,XX指令是雙指令周期。如果使用了C語言編程,也要仔細看生成的匯編代碼然后再調節。例如下面的代碼示例:
  功能 延時(12M 24M)
  誤差 Ms S 5% 10Us 8%-80%
  //24M晶振 延時 n毫秒
  void DelayMs_24M(unsigned int n)
  {
  unsigned int i=0,j=0;
  for(i=0;i
  for(j=0;j
  }
  延遲函數是通過的兩個循環計算而形成的停機等待而達到延遲的目的。代碼是通過查看由C語言生成的匯編代碼指令——那個357便是由此計算出來的。當然,延遲函數是否精準也完全取決于那個357數字的選擇了。
  單周期指令,雙周期指令,數一數便可以了?其實查看匯編代碼沒有這么簡單的,畢竟For循環也需要系統開銷的,還有其它比較,判斷指令什么的。但這一切在IAR for AVR編譯環境里似乎就簡單多了。
  在IAR for AVR編譯環境里,用戶只需要 #include "intrinsics.h"便可以調用void __delay_cycles(unsigned long);函數,這個函數是系統函數,其代表著一個機器周期。用戶不再需要計算匯編語言的指令周期,不必再細讀單片機的操作手冊,強大的IAR編譯環境自己就算好了——單片機發展到IAR for AVR時代,也基本代表著匯編退居二線。由于篇幅的原因,版主就不再這里為大家帖出代碼示例了。
  在Atmel的8位單片機AVR系列一統天下的時候,ARM內核為代表的單片機在悄然崛起。不知不覺,以ST公司stm32f103為代表的32位Cortex-M3內核的單片機占據了市場大部分分額,各大論壇爭先推出STM32版塊。
  其中,某位牛人推出的使用systick函數來完成延遲函數頗具人氣。我們來看一下源代碼:
  //初始化延遲函數
  void delay_init(u8 SYSCLK)
  {
  SysTick->CTRL&=0xfffffffb;//選擇內部時鐘 HCLK/8
  fac_us=SYSCLK/8;
  fac_ms=(u16)fac_us*1000;
  }
  void delay_ms(u16 nms)
  {
  SysTick->LOAD=(u32)nms*fac_ms; //時間加載
  SysTick->CTRL|=0x01; //開始倒數
  while(!(SysTick->CTRL&(1
  SysTick->CTRL&=0XFFFFFFFE; //關閉計數器
  SysTick->VAL=0X00000000; //清空計數器
  }
  牛人的代碼還是非常簡潔的,使用起來也方便,首先調用delay_init函數,然后,再調用delay_ms()函數。這個延遲函數也是非常準確的,因為其使用了單片機的硬件定時器模塊。在STM32F103高達72MHz的主頻,優化的指令集系統下,系統的開銷完成可以忽略。筆者也將其成功應用于單總線通訊方式的數字溫度采集傳感器18B20芯片上,測試良好。
  寫到這里,筆者已經介紹了三種延遲函數,它們三個都有一個共同的特點:阻塞延遲函數——在“等待”延遲函數到來的時候里,單片機并沒有處理其它有用,有意義的事情,而是停機在等待著時間的到來。對于我們要處理大量數據的單片機系統來說,這個劣勢有時就很難接受的。那么我們要怎么解決呢?
  我們仍然以STM32F103為例,仍然要使用強大的定時器,這里我們再次選用systick定時器。我們首先要初始化ST單片機systick,其每1ms進入中斷一次,代碼如下:
  if (SysTick_Config(72000)) //參數為系統時鐘的向上溢出值,此配置為72000,即1ms中斷一次
  {
  /* Capture error */
  while (1);
  }
  之后,我們在systick的中斷函數里計數,示例代碼如下:
  void SysTick_Handler(void)
  {
  if(gCntLed[0] > 0)
  {
  gCntLed[0]--;
  }
  else
  {
  gCntLed[0] = 0;
  }
  }
  從上面代碼可以清楚看到,每1ms,gCntLed[0]將計數值減1,直到為0時止。而main函數里,就要不斷的查詢這個gCntLed[0]的值,當未達到0值時,就去做別的事情,而查詢到0值時,再去處理自己的事情,示例代碼如下:
  while(1)
  {
  if(gCntLed[0] == 0)
  {
  LedToggle(0);
  gCntLed[0] = 200;
  }
  KeyScan();
  }
  通過未阻塞的延遲函數,我們實現了LED燈每隔200ms閃爍一次的效果,與其同時,我們也沒有停止不斷掃描按鍵。——這就是非阻塞延遲函數的強大優勢。非阻塞式延遲函數還主要應用于嵌入式操作系統函數里,喜歡的網友可以自己查看相關函數。
  隨著時代的進步,能源的問題逐漸突出出來。剛剛筆者介紹的幾種函數都是在不停的“運行”,看似什么事情也沒有做,但是單片機確實在全力的“奔跑”,這與當前節碳減排,低功耗格格不入。MSP430算得上是低功耗的代表了,其延遲函數可以拿來借鑒一下。
  在MSP430的低功耗設計中,阻塞式延遲函數是基本不用的——因為功耗太大,未阻塞式延遲函數是必備條件。設計主要思想是,定時讓MSP430從睡眠模式里“醒”過來,查看一下當前的時間與狀態,然后再做決定如何處理。換句話說,上面的示例就變成了,MSP430每1ms準時醒來一次,處理了一下gCntLed[0]的值,然后又查看了一下,如果非0值,則繼續“睡”去了;如果恰好是0值,則再干一會兒事情……這里,MSP430大部分時間里就處于了低功耗的睡眠模式,自然也就節能了。
  又到總結的時候了,幾種延遲函數各有特點與應用場景,各位親愛的網友們根據自己的需求來自行選擇吧!當然,也可以來論壇的ARM版塊發帖求助,版主也會傾力奉獻的。
                               
               
本文地址:http://m.qingdxww.cn/thread-160810-1-1.html     【打印本頁】

本站部分文章為轉載或網友發布,目的在于傳遞和分享信息,并不代表本網贊同其觀點和對其真實性負責;文章版權歸原作者及原出處所有,如涉及作品內容、版權和其它問題,我們將根據著作權人的要求,第一時間更正或刪除。
您需要登錄后才可以發表評論 登錄 | 立即注冊

廠商推薦

  • Microchip視頻專區
  • Dev Tool Bits——使用MPLAB® Discover瀏覽資源
  • Dev Tool Bits——使用條件軟件斷點宏來節省時間和空間
  • Dev Tool Bits——使用DVRT協議查看項目中的數據
  • Dev Tool Bits——使用MPLAB® Data Visualizer進行功率監視
  • 貿澤電子(Mouser)專區

相關視頻

關于我們  -  服務條款  -  使用指南  -  站點地圖  -  友情鏈接  -  聯系我們
電子工程網 © 版權所有   京ICP備16069177號 | 京公網安備11010502021702
快速回復 返回頂部 返回列表
主站蜘蛛池模板: a毛片在线免费观看 | 四虎影院免费在线 | 在线 中文字幕 日韩 欧美 | 69视频在线是免费观看 | 亚洲韩国欧美一区二区三区 | 久草网视频在线 | 最新国产精品自拍 | 国产综合精品久久亚洲 | 亚色中文 | 亚洲欧美一区二区三区在线观看 | 欧美v日本| 国产美女白丝袜精品_a不卡 | 日韩在线观看第一页 | 日日摸人人看97人人澡 | 久久99热只有视精品6国产 | 国产高清一区二区三区 | 韩国免费高清一级毛片性色 | 麻豆天美精东91制片厂 | 欧美人与动人物xxxx9296 | 在线视频精品一区 | 国产a久久精品一区二区三区 | 91久热 | 97国内免费久久久久久久久久 | 国产午夜人做人视频羞羞 | 亚洲日本中文 | 天天靠天天擦天天摸 | 国产微拍 | 久久国产成人精品国产成人亚洲 | 91视频一88av| 四虎网站 | 一区二区三区四区在线 | 青青在线视频 | 国产一区二区日韩欧美在线 | 丁香伊人 | 朝鲜一级一级妇女毛片 | 国产性生活视频 | 亚洲动漫在线观看 | 天天影视欧美 | 日韩美香港a一级毛片 | 天天舔天天干天天操 | 天天操一操 |