新聞中心

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

        51內(nèi)核單片機(jī)中斷優(yōu)先級的理解

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

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

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


        評論


        技術(shù)專區(qū)

        關(guān)閉
        主站蜘蛛池模板: 肥西县| 花垣县| 达拉特旗| 曲麻莱县| 龙泉市| 塘沽区| 河北区| 溆浦县| 永吉县| 石屏县| 阿鲁科尔沁旗| 长阳| 邳州市| 武平县| 茂名市| 平江县| 乡城县| 什邡市| 鲁山县| 兴业县| 江孜县| 益阳市| 吉首市| 临湘市| 图们市| 宝丰县| 达拉特旗| 新疆| 九寨沟县| 德州市| 库伦旗| 平利县| 天长市| 观塘区| 泰和县| 黔江区| 墨江| 绩溪县| 常宁市| 德令哈市| 万全县|