編寫51程序的時候,有時候會在主函數和中斷函數里面調用同一個函數,如果正的出現這種情況,編譯器會提出 這種警告: *** WARNING L15: MULTIPLE CALL TO SEGMENT(重復調用同一個函數)
這種情況時因為函數發生了重入,
盡管這樣出現錯誤的概率很低,但是一旦出現錯誤,將會是很討厭的錯誤,在網上我看到的一篇博文里面,說這個錯誤必須引起注意,特別是像我們這種做控制和自動化的,一點小小的錯誤和異常都可能引起一次事故和災難,必須小心謹慎。
因為它可能引起程序沖突,導致信號產生尖峰。 產生這一警告的一個根源是:你在主循環 里調用了一個函數(如aaa),而在中斷服務函數里,你用調用了這個函數(如aaa)。這樣當主循環運行到該函數中 是,一旦產生中斷,則在中斷里又再次調用該函數!這時,很可能出錯! 避免這種情況的方法很多:如,在進中斷的時候置需調用該函數的標志,而在主循環中調用該函數。
解決方法:
1、可以定義兩個功能相同的函數,在中斷和主函數里面分別調用,但是需要很多額外重復函數;
2、在中斷函數里面設置一個標志,然后在主循環里面調用該函數。
下面具體說說的我的情況和解決辦法。
在主函數里面我多次調用 show_string函數,用TFT來顯示需要的信息,當中斷產生的時候,我又需要在TFT里面顯示其他信息,這樣就出現了函數的重入,但是又不能取消,進入中斷和主函數都是必須的。
當我用第一種方法來解決的時候,發現需要重新定義的函數太多了,太占內存,不能用。於是考慮第二種方法,在中斷里面設置標志,然后在主循環里面實現。
void int0() interrupt 0{ delayms(5); if(k3_set==0){ set_flag = ~set_flag;//標志 chose_flag = 0; ds1302_init();//如果沒有這句的話,設置完后又會回到原來的數字 } }
在主循環里面:
while(1){ if(set_flag==0){//正常 ds1302_readtime(); show_string(120,16," ");//刷新提示區,就是這個,不能寫在中斷里面 } else{ key_init(); }
這樣這個問題就解決了。當然,當你調用的函數不是很大的情況下,第一種方法也不錯。
