Ako zdebugovat interupt v C ?

Jan Waclawek konfera na efton.sk
Pátek Září 8 10:03:32 CEST 2023


[preposielam]

Ahoj,

tak som ten kod trochu vyextrahoval. (Ja som Vas varoval pred dlzkou....)

Az by ste mali niekto chut to pozriet, budem rad. Ja som neni schopny
momentalne nic vymysliet co s tym.

Velmi pekne dakujem za brainstorming.

A.


>>>
Jak debugovat interupt závisí na okolnostech.

Ale myslím si, že popis těch okolností je podstatně delší, než prostě
zkopírování těch dejme tomu 3-10 řádků kódu na obsluhu multiplexované
sedmisegmentovky a pár sovisejících deklarací.

Nebo, jestli je to tajné, tak ten kousek smazat, chvíli dělat něco úplně
jiného a pak to napsat znova:-)

PH



/*****************************************
 *  Funkcie pre pracu s i/o multiplexom  *
 *****************************************/

// data pre i/o multiplex rutinu
static volatile unsigned char MUX_Sync_Flag;
static volatile unsigned char MUX_Position;
static volatile unsigned char MUX_Data;

static volatile union {
    unsigned long int LongInt;
    unsigned char Byte[4];
} MUX_RawData;

static volatile union {
    unsigned long int LongInt;
    unsigned char Byte[4];
} RawData;


void MUX_7Seg_Display_Init() {

    MUX_RawData.LongInt = 0;
    MUX_Position = 0;
    MUX_Data = 0;
    MUX_Sync_Flag = 0;
    return;
}

void MUX_7Seg_Display_Write_Data() {

    // signal nove data
    GIE = 0;
    MUX_Sync_Flag = 1;
    GIE = 1;

    static volatile unsigned char Tmp = 0;
    unsigned int Time = 0x0040;

    while(1) {
        GIE = 0;
        Tmp = MUX_Sync_Flag;
        GIE = 1;

        if(Tmp == 0)
            break;
    }

    // 21.6.2023
    //
    // rutina potrebuje malu pauzu na synchronizaciu s displejom
    // neviem preco...
    // odladit s osciloskopom
    //
    while(Time--)
        ;

    return;
}


/********************************
 *  Interrupt vektor - 0x0004   *
 ********************************/

void __interrupt() TP11_1kHz_INT(void) {

    if(T0IF == 1 && T0IE == 1) {

        // interrupt TMR0
        // generuje 1kHz na pine TP11

        // clear TMR0 int. flag
        T0IF = 0;

        // TMR0 reload
        // xc8 v2.36
        // int_entry -> 9
        // int_exit  -> 9
        TMR0 = (0x0100 -TMR0_PERIOD +2 +18); // +21 (+1 corr.)

        // decrement pomocneho citaca 1kHz
        if(TMR0_1ms_Counter != 0)
            TMR0_1ms_Counter--;
        else {
            TMR0_1ms_Counter = TMR0_SW_1MS;
            TMR0_1ms_Flag = 1;

            // invertuj TP11
            if(TP11 == 0) {
                //NOP();
                TP11 = 1;
            }
            else {
                TP11 = 0;
            }

            /**************************
             * Multiplex displeja     *
             *  - MUX_7Seg_Display(); *
             **************************/

            // display off
            //
            SEG_CA3 = 1;
            SEG_CA2 = 1;
            SEG_CA1 = 1;
            SEG_CA0 = 1;

            // set new display data
            //
            if(MUX_Data & 0x01)
                SEG_A = 0;      // rozsvieti segment A
            else
                SEG_A = 1;
            if(MUX_Data & 0x02)
                SEG_B = 0;      // rozsvieti segment B
            else
                SEG_B = 1;
            if(MUX_Data & 0x04)
                SEG_C = 0;      // rozsvieti segment C
            else
                SEG_C = 1;
            if(MUX_Data & 0x08)
                SEG_D = 0;      // rozsvieti segment D
            else
                SEG_D = 1;
            if(MUX_Data & 0x10)
                SEG_E = 0;      // rozsvieti segment E
            else
                SEG_E = 1;
            if(MUX_Data & 0x20)
                SEG_F = 0;      // rozsvieti segment F
            else
                SEG_F = 1;
            if(MUX_Data & 0x40)
                SEG_G = 0;      // rozsvieti segment G
            else
                SEG_G = 1;
            if(MUX_Data & 0x80)
                SEG_DP = 0;     // rozsvieti segment DP
            else
                SEG_DP = 1;

            // display on
            //
            if(MUX_Position == 3)
                SEG_CA3 = 0;    // rozsvieti segmentovku Display_Buffer[3]
            else
                SEG_CA3 = 1;
            if(MUX_Position == 2)
                SEG_CA2 = 0;    // rozsvieti segmentovku Display_Buffer[2]
            else
                SEG_CA2 = 1;
            if(MUX_Position == 1)
                SEG_CA1 = 0;    // rozsvieti segmentovku Display_Buffer[1]
            else
                SEG_CA1 = 1;
            if(MUX_Position == 0)
                SEG_CA0 = 0;    // rozsvieti segmentovku Display_Buffer[0]
            else
                SEG_CA0 = 1;

            // shift to next position
            //
            MUX_Position++;

            // check position range
            //
            if(MUX_Position >= 4)
                MUX_Position = 0;

            // if any change write new data to buffer
            // clear sync flag
            //
            if((MUX_Position == 0) && (MUX_Sync_Flag == 1)) {
                MUX_RawData.LongInt = RawData.LongInt;
                MUX_Sync_Flag = 0;
            }

            // get data from new position
            //
            MUX_Data = MUX_RawData.Byte[MUX_Position];

            /*********************
             * Koniec multiplexu *
             *********************/
        }
    }
    else {
        TP11_100kHz_SW();
    }
}



/************************************************************/
// 7Seg_Display_Chars - tabulky a konstanty v EEPROM
//--------------------------------------------------

// Cislice a znaky 0..9, A..F
// * digit 3 ... 0
const unsigned char Digit30[16] = {

//   DpGFEDCBA
    0b00111111, 0b00000110, 0b01011011, 0b01001111, // 0 1 2 3
    0b01100110, 0b01101101, 0b01111101, 0b00000111, // 4 5 6 7
    0b01111111, 0b01101111, 0b01110111, 0b01111100, // 8 9 A b
    0b00111001, 0b01011110, 0b01111001, 0b01110001  // C d E F
};

// generuje kratsi kod
//
#define DigitMinus  0b01000000
#define DigitDP     0b10000000
#define DigitMask   0b00000000

/********************************************************
 * 7Seg_Display_Digits - low-level funkcie              *
 *                              pre pracu s digitmi 3-0 *
 *                                                      *
 * - pracuju s binarnym bufferom RawData[0..31]         *
 * - po nastaveni RawData treba zavolat                 *
 *    MUX_7Seg_Display_Write_Data()   *
 ********************************************************/

// * RawData[0..31] = 0;
//   - call + return  vs.  4 x clrf -> kratsi kod
void ClearRawData() {
    RawData.LongInt = 0x00000000;
    return;
};

// * vymaze digit 3-0
void ClearDigit(unsigned char Digit) {
    RawData.Byte[Digit] = RawData.Byte[Digit] & DigitMask;
    return;
};

// * nastavi znamienko "-" v digite 3-0
void SetMinus(unsigned char Digit) {
    ClearDigit(Digit);
    RawData.Byte[Digit] = RawData.Byte[Digit] | DigitMinus;
    return;
};



// pravdepodobne tuna to zblbne!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

// * nastavi desatinnu bodku v digite 3-0
void SetDecimalPoint(unsigned char Digit) {
    RawData.Byte[Digit] = RawData.Byte[Digit] | DigitDP;
    return;
};

// * nastavi cislicu 0..9, A..F v digite 3-0
void SetDigit3(unsigned char Number) {
    ClearDigit(3);
    RawData.Byte[3] = RawData.Byte[3] | Digit30[Number];
    return;
};

void SetDigit2(unsigned char Number) {
    ClearDigit(2);
    RawData.Byte[2] = RawData.Byte[2] | Digit30[Number];
    return;
};

void SetDigit1(unsigned char Number) {
    ClearDigit(1);
    RawData.Byte[1] = RawData.Byte[1] | Digit30[Number];
    return;
};

void SetDigit0(unsigned char Number) {
    ClearDigit(0);
    RawData.Byte[0] = RawData.Byte[0] | Digit30[Number];
    return;
};



Další informace o konferenci Hw-list