[HAL]5.中斷里調用HAL_Delay()進入死循環的原因


 

中斷里調用HAL_Delay()進入死循環的原因 

摘自:http://blog.csdn.net/alwxkxk/article/details/47204677

CUBE生成的程序中, SysTick是中斷型延時(利用中斷來查詢時間到了沒)。

 

  /* Use systick as time base source and configure 1ms tick (default clock after Reset is MSI) */

  HAL_InitTick(TICK_INT_PRIORITY);

#define  TICK_INT_PRIORITY            ((uint32_t)0x000F)    /*!< tick interrupt priority */    

SysTick是內核中斷,優先級別默認最低。

(可以用內核函數來修改~   當然,這就要看內核M3的書了,而不是看STM32的參考手冊那么簡單。暫時就不深入研究,日后更新。)

 

總結起來就是,就是傳說中優先級別默認最低,雖然SysTick一直在跑,但是沒進入到中斷來讀取它的值~

(不知是哪里讓我潛意識地認為SysTick級別比外設都高,導致這問題)

 

如果中斷里調用HAL_Delay就會停在那里,因為根本不會進入那個級別更低的中斷。

 

 資料補充:

 

 網上還有一種寫 法是時間摘取法,是一直讀取SysTick產生延時函數~(原子的例程就是用這種方法)

其次,有人提到,中斷里面不應該使用延時,中斷所占的時間越短越好~有道理~

附上原子的時間摘取法的程序,很有學習價值~

  1 //////////////////////////////////////////////////////////////////////////////////  
  2 
  3 //本程序只供學習使用,未經作者許可,不得用於其它任何用途
  4 
  5 //Mini STM32開發板
  6 
  7 //使用SysTick的普通計數模式對延遲進行管理
  8 
  9 //包括delay_us,delay_ms
 10 
 11 //正點原子@ALIENTEK
 12 
 13 //技術論壇:www.openedv.com
 14 
 15 //修改日期:2010/5/27
 16 
 17 //版本:V1.2
 18 
 19 //版權所有,盜版必究。
 20 
 21 //Copyright(C) 正點原子 2009-2019
 22 
 23 //All rights reserved
 24 
 25 //********************************************************************************
 26 
 27 //V1.2修改說明
 28 
 29 //修正了中斷中調用出現死循環的錯誤
 30 
 31 //防止延時不准確,采用do while結構!
 32 
 33 //////////////////////////////////////////////////////////////////////////////////  
 34 
 35 static u8  fac_us=0;//us延時倍乘數
 36 
 37 static u16 fac_ms=0;//ms延時倍乘數
 38 
 39 //初始化延遲函數
 40 
 41 //SYSTICK的時鍾固定為HCLK時鍾的1/8
 42 
 43 //SYSCLK:系統時鍾
 44 
 45 void delay_init(u8 SYSCLK)
 46 
 47 {
 48 
 49 SysTick->CTRL&=0xfffffffb;//bit2清空,選擇外部時鍾  HCLK/8
 50 
 51 fac_us=SYSCLK/8;     
 52 
 53 fac_ms=(u16)fac_us*1000;
 54 
 55 }     
 56 
 57 //延時nms
 58 
 59 //注意nms的范圍
 60 
 61 //SysTick->LOAD為24位寄存器,所以,最大延時為:
 62 
 63 //nms<=0xffffff*8*1000/SYSCLK
 64 
 65 //SYSCLK單位為Hz,nms單位為ms
 66 
 67 //對72M條件下,nms<=1864 
 68 
 69 void delay_ms(u16 nms)
 70 
 71 {        
 72 
 73 u32 temp;    
 74 
 75 SysTick->LOAD=(u32)nms*fac_ms;//時間加載(SysTick->LOAD為24bit)
 76 
 77 SysTick->VAL =0x00;           //清空計數器
 78 
 79 SysTick->CTRL=0x01 ;          //開始倒數  
 80 
 81 do
 82 
 83 {
 84 
 85 temp=SysTick->CTRL;
 86 
 87 }
 88 
 89 while(temp&0x01&&!(temp&(1<<16)));//等待時間到達   
 90 
 91 SysTick->CTRL=0x00;       //關閉計數器
 92 
 93 SysTick->VAL =0X00;       //清空計數器        
 94 
 95 }   
 96 
 97 //延時nus
 98 
 99 //nus為要延時的us數.         
100 
101 void delay_us(u32 nus)
102 
103 {
104 
105 u32 temp;       
106 
107 SysTick->LOAD=nus*fac_us; //時間加載     
108 
109 SysTick->VAL=0x00;        //清空計數器
110 
111 SysTick->CTRL=0x01 ;      //開始倒數   
112 
113 do
114 
115 {
116 
117 temp=SysTick->CTRL;
118 
119 }
120 
121 while(temp&0x01&&!(temp&(1<<16)));//等待時間到達   
122 
123 SysTick->CTRL=0x00;       //關閉計數器
124 
125 SysTick->VAL =0X00;       //清空計數器  
126 
127 }
128 
129  

 


免責聲明!

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



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