久久ER99热精品一区二区-久久精品99国产精品日本-久久精品免费一区二区三区-久久综合九色综合欧美狠狠

新聞中心

EEPW首頁 > 嵌入式系統 > 設計應用 > 51內核單片機中斷優先級的理解

51內核單片機中斷優先級的理解

作者: 時間:2016-11-23 來源:網絡 收藏
由于項目的需要,這兩天正好在研究應用層協議的格式與規范,參考了吳老師給的ZLG的RS-485_Guide。
RS-485標準是基于PC的UART芯片上的處理方式(8-N-1格式),只涉及到電氣特性規定,而沒有對上層協議作出規定,因此,需要用戶自己設計網絡應用層協議。大部分用戶都自行定義自己的應用層協議,或者直接取自部分ModBus協議。國內根據不同的設備類型也頒布了各類通訊協議,如CDT、SC-1801、u4F、DNP3.0 規約和1995年的IEC60870-5-101 傳輸規約、1997 年的國際101 規約的國內版本DL/T634-1997規約;在電表應用中,國內大多數地區的廠商采用多功能電能表通訊規約(DL/T645-1997)。
主要研究多功能電能表通訊規約(DL/T645-1997),這是江浙滬地區電表廠商的行業標準,利用飛利浦公司的P89LPC931單片機對RS-485的應用層協議進行實現。LPC900 系列單片機是一個基于 80C51內核的增強型單片機。手冊里給出了整個通訊程序的實現,程序主要分為三個部分:數據接收部分、命令執行部分、數據發送部分。
通常在串口通信的程序實現中,發送數據一般采用查詢模式,接收數據一般采用中斷方式。關于接收數據的程序大部分實現是這樣的:每次接收中斷中只是將接收緩沖區的數據讀出,而數據幀協議則交由前臺大循環做。但是在ZLG的手冊中給出了接收中斷程序直接處理數據幀的方式。

圖1接收程序流程圖(ZLG RS-485_Guide)
接收一個字節通訊函數
原型:uchar Receive_Data();
功能:接收一個字節通訊
入口參數:無
出口參數:返回接收值
********************************************************************/
uchar Receive_Data()
{
RI=0;
while(!RI);
RI=0;
ACC=SBUF;
if(P!=RB8)
{
SP--;SP--;CY=0;return CY;
}
return (ACC);
}


bit Receive_One(uchar *s)
{
uchar CS=0x00,Serial_data;
char i,j;
RI=0;
Serial_data=SBUF;
while(Serial_data!=0xfe)
return 0;
do
Serial_data=Receive_Data();
while(Serial_data==0xfe);
if(Serial_data!=0x68)
return 0;
CS+=0x68;
for(i=0;i<=5;i++)
{
*(s+i)=Receive_Data();
CS+=*(s+i);
}
if(Receive_Data()!=0x68)
return 0;
CS+=0x68;
CS+=(*(s+6)=Receive_Data());
j=*(s+7)=Receive_Data();
CS+=j;
for(i=0;i<=(j-1);i++)
{
CS+=(*(s+i+8)=Receive_Data());
*(s+i+8)-=0x33;
}
if(CS!=Receive_Data())
return 0;
if(Receive_Data()!=0x16)
return 0;
ESR=0;
return 1;
}

串口接收中斷服務程序
功能:接收數據
********************************************************************/
void RXD_Int(void) interrupt 4
{
CY=Receive_One(Serial_buf);
if(CY)
Command_status1|=0x04;
}
/********************************************************************

圖1是中斷處理函數中的接收流程,中斷程序如上述。程序在判斷出第一個字節是前導字節以后,需要繼續判斷前導字節,當連續2-4次判斷出是前導字節后才會繼續往下執行。但是在作第二次前導字節的判斷時,Receive_Data()事實上是在當前中斷程序中等待下一個接收到的數據,而當接收到下一個數據時,是否會再次發生中斷呢?這個問題困惑了我一晚上。按照程序邏輯推理,即假設本程序是無誤的基礎上(事后證明應該是正確的),第二次中斷是不應該發生的,否則將程序無限中斷嵌套下去,也得不到幀數據的處理結果。但是在Receive_Data()中的 while(!RI),需要等待的是接收中斷標志位置位,也就是說,第二次接收數據完以后串口接收中斷標志將被置位,但是中斷不嵌套。
以下是我從百度文庫里找到的一片關于51系列單片機中斷嵌套的文章,給出了比較詳細的解釋,現將主要的內容摘錄如下:
“老的51單片機(80C51系列)有5個中斷源,2個優先級,可以實現二級中斷服務嵌套。現在很多擴展的51單片機已經有4個優先級(或更多)和更多的中斷源了。老的51單片機(80C51系列)有5個中斷源,2個優先級,可以實現二級中斷服務嵌套。現在很多擴展的51單片機已經有4個優先級(或更多)和更多的中斷源了。”
“中斷的優先級有兩個:查詢優先級和執行優先級。”
我們通常所說的中斷優先級一般指的是執行優先級,但同一執行優先級的中斷也有比較,那就是查詢優先級。所謂查詢優先級是指在兩個同一優先級的中斷同時發生時(嚴格來說應該是在單片機能分辨的同一微小時段內),處理器會按照默認的次序進行中斷查詢,查詢優先級高的中斷先運行中斷處理程序,而查詢優先級低的則中斷標志置位,如果高查詢優先級的中斷運行過程中沒有對該標志位作恢復處理,那么在運行完該高查詢優先級中斷任務后,仍然會執行低的優先級任務;但是,如果在運行過程中低查詢優先級的中斷標志被恢復,那么對應的中斷程序應該不會被處理。同理,對于同一中斷,比如串口中斷,在運行當前串口接收中斷程序的時候又有數據被接收,則對應的中斷標志會被置位,但是不會產生嵌套中斷,而只有等待當前中斷結束后才繼續執行對應的中斷程序。在上述程序當中,可以看到,在第二次發生中斷后,對應的中斷標志已被清除,所以不會執行第二次中斷程序,第二次中斷的主要作用是滿足函數Receive_Data()中的 while(!RI),即提供了中斷標志位,這樣,就既能接收到第二個字節的數據,又能不產生中斷,也就是該手冊中實現中斷程序一次接收多個字節數據(幀)的方法!
與查詢優先級對應的還有就是執行優先級,這個是需要用戶對單片機做設定的,在這種情況下,中斷才會發生嵌套,細節不敘。當然不同單片機或處理器關于中斷的定義有一定的出入,具體的應用仍然要參照對應的數據手冊。
(轉載請注明出處,謝謝!http://blog.sina.com.cn/s/blog_49d4de8a0100w0f4.html)
參考文獻:
1. ZLG公司.《RS-485_Guide》,2004
2. 《DL/T645-1997通訊規約通信規約》
3. 《關于51系列單片機中斷嵌套》


評論


技術專區

關閉