新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > 51內核單片機中斷優(yōu)先級的理解

51內核單片機中斷優(yōu)先級的理解

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

圖1接收程序流程圖(ZLG RS-485_Guide)
接收一個字節(jié)通訊函數(shù)
原型:uchar Receive_Data();
功能:接收一個字節(jié)通訊
入口參數(shù):無
出口參數(shù):返回接收值
********************************************************************/
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;
}

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

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


評論


技術專區(qū)

關閉