簡體   English   中英

中斷本身可以中斷嗎?

[英]Can an interrupt interrupt itself?

我正在將pic16F690與mplabv8.70,pickit 2和高科技PICC PRO c編譯器一起使用。

我的問題是,該中斷是否將能夠使用其中的getch函數,因為getch函數使用RCIF標志,該標志也是用於觸發EUSART中斷的標志。

她是我的代碼,很抱歉,但是很長一段時間,但是這里的人似乎不喜歡放置摘要/部分而不是整個內容。 它多路復用一個4位數的7段LED顯示屏,並獲得RUS值的EUSART信號,但是我希望它即使在沒有收到EUSART的情況下也能繼續顯示,然后在中斷並有效地“更新”時有效。全局變量。 如果有明顯更好的方法,那么我很高興被告知我的方法是錯誤的。

//#include _LEGACY_HEADERS              //Added for compiler versions 9.81+
#include <stdio.h>                      //For the printf function
#include <htc.h>                        //Compiler header file
//#include "usart.h"                        //USART header file
//#include "pause.h"
//#include "SerialIn.h"
//#include "Display.h"

__CONFIG(INTIO & WDTDIS & PWRTEN & MCLRDIS & UNPROTECT & UNPROTECT & BORDIS & IESODIS & FCMDIS);        //Configure the PIC with generic set up

#define BAUD 2400      
#define FOSC 4000000L
#define baudsetting ((int)(FOSC/(64UL * BAUD) -1))

#define RX_PIN TRISB5
#define TX_PIN TRISB7

#define dig0 0b01111110
#define dig1 0b00110000
#define dig2 0b01101101
#define dig3 0b01111001
#define dig4 0b00110011
#define dig5 0b01011011
#define dig6 0b01011111
#define dig7 0b01110000
#define dig8 0b01111111
#define dig9 0b01111011

unsigned char byte1;
unsigned char byte2;
unsigned char byte3;
unsigned char byte4;
unsigned char byte5;
unsigned char byte6;
unsigned char byte7;
unsigned char byte8;
unsigned char byte9;

unsigned RPMleft;
unsigned RPMright;

#define units 0b000001
#define tens 0b000010
#define hundreds 0b000100
#define thousands 0b001000

unsigned char RPM_unit;
unsigned char RPM_ten;
unsigned char RPM_hund;
unsigned char RPM_thou;

void interrupt isr(void);
void display_digit(unsigned char digit);
void multiplex(unsigned RPM);
void pause(unsigned usvalue);
unsigned char getch(void);
void init_comms(void);

void interrupt isr(void)
{   
    if (RCIF == 1)
    {
        byte2 = getch();                //Receive 8 bytes from the PICAXE
        byte3 = getch();
        byte4 = getch();
        byte5 = getch();
        byte6 = getch();
        byte7 = getch();
        byte8 = getch();
        byte9 = getch();

        byte2 = byte2 - 30;             //Convert the ASCII to equivilent integer
        byte3 = byte3 - 30;
        byte4 = byte4 - 30;
        byte5 = byte5 - 30;
        byte6 = byte6 - 30;
        byte7 = byte7 - 30;
        byte8 = byte8 - 30;
        byte9 = byte9 - 30;

////////Depending on which PIC is being used comment one of the following lines///////////////////////////////

        RPMleft = byte2*1000 + byte3*100 + byte4*10 + byte5;    //Save the RPM of the left prop shaft

//      RPMright = byte6*1000 + byte7*100 + byte8*10 + byte9;   //Save the RPM of the right prop shaft
    }
}

void main(void)
{
    /* General Setup */
    PORTA = 0;                          //Clear PortA
    PORTB = 0;                          //Clear PortB
    PORTC = 0;                          //Clear PortC
    TRISA = 0;                          //All PortA outputs
    TRISB = 0xFF;                       //All PortB inputs
    TRISC = 0;                          //All PortC outputs
    CM1CON0 = 0;                        //Comparators off
    CM2CON0 = 0;
    ANSEL = 0;                          //A/D module off

    INTCON = 0b11000000;                //Enable interrupts GIE = 1 (global interrupts), PEIE = 1 (periphaeral interrupts)
    PIE1 = 0b00100000;                  //Enable bit 5 RCIE = 1 (EUSART receive interrupt enable bit)

    init_comms();                       //Set up the USARTh

    while(1==1)                         //Loop Forever
    {
////////Depending on which PIC is being used comment one of the following lines////////////////////////////////////
        multiplex(RPMleft);
//      multiplex(RPMright);
    }//End while    
}//End main

unsigned char getch(void) {
    /* retrieve one byte */
    while(!RCIF)    /* set when register is not empty */
        continue;
    return RCREG;   
}

void init_comms(void)
{   
    RX_PIN = 1; 
    TX_PIN = 0;       
    SPBRG = baudsetting;        
    //Continuous 8 bit asynchronous non inverted low speed communication
    RCSTA = 0x90; // SPEN and CREN bit = 1, RX9EN = 0
    TXSTA = 0x20;//TXEN = 1, BRGH, SYNC = 0
    BAUDCTL = 0; //BRG16 = 0 
}

void multiplex(unsigned RPM)
{
    RPM_unit = RPM / 1000;                                  //Split the Left RPM value into 4 digits
    RPM_ten = (RPM / 100) % 10;
    RPM_hund = (RPM / 10) % 10;
    RPM_thou = RPM % 10;

    //Start Multiplexing

    PORTA = thousands;
    display_digit(RPM_thou);

    PORTA = hundreds;
    display_digit(RPM_hund);

    PORTA = tens;
    display_digit(RPM_ten);

    PORTA = units;
    display_digit(RPM_unit);
}

void display_digit(unsigned char digit)
{
    switch (digit)
    {
        case 0:
        PORTC = dig0;       //zero
        break;

        case 1:
        PORTC = dig1;       //one
        break;

        case 2:
        PORTC = dig2;       //two
        break;

        case 3:
        PORTC = dig3;       //three
        break;

        case 4:
        PORTC = dig4;       //four
        break;

        case 5:
        PORTC = dig5;       //five
        break;

        case 6:
        PORTC = dig6;       //six
        break;

        case 7:
        PORTC = dig7;       //seven
        break;

        case 8:
        PORTC = dig8;       //eight
        break;

        case 9:
        PORTC = dig9;       //nine
        break;
    }
}

在PIC16架構中,中斷不能自行中斷。 即使您提前清除該標志,ISR也將繼續運行,直到返回為止。

如果需要嵌套中斷,請切換到PIC18。

我喜歡使中斷服務程序盡可能的短,並避免延遲或代碼花費太長時間來處理它們。 這樣,程序就可以盡快處理新的中斷了。

如果在服務另一個中斷時發生中斷,則由於設置了中斷標志,微處理器將在退出ISR后立即再次重新輸入ISR。

在您的代碼中,我認為您可以在讀取第一個字符后退出ISR,然后繼續執行直到下一次設置RCIF標志為止。 由於您可以執行大量代碼,直到通過USART發送另一個字節為止。 如果您創建了一個字節[9]之類的緩沖區和一個靜態指針來記住您在ISR調用之間接收到的字符,這應該可以工作。

這是一個例子:

void interrupt isr(void)
{   
    static char pointer = 0;
    if (RCIF == 1)
    {
         byte[pointer]=getch();        // stores the incoming data in byte[0]-byte[8]
         pointer++;                  
         if(pointer==9)
         {
              pointer=0;               // Reset pointer
              // Other operations or flags that signal the expected data was received
         }
    }
}

編輯:我還認為您需要在軟件中清除RCIF標志,檢查數據表以查看是否需要手動執行此操作,或者如果緩沖區為空,則是否自動清除了該標志。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM