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