Ako zdebugovat interupt v C ?

Pavel Hudeček edizon na seznam.cz
Pátek Září 8 10:48:24 CEST 2023


Aha tak to je ten případ smazat a napsat úplně znova:-)

Pro inspiraci: Tohle je kus programu, kde je 4místný LED displej spol. 
anoda, s dalšíma LEDkama jako 5. místo (v programu jako Lx) + LEDky na 
DPS jako 6. místo, umí to i blikat a ještě se to kombinuje s měřením ADC 
v době kdy má displej tmu v rámci rozumného jasu. (Schéma obsahuje 6 NPN 
a 8 malých R.)

*uint8_t    dispData[6]={0, 0, 0, 0, 0, 0}; // 0-3 cisla, 4 Lx, 5 LEDx**
**uint8_t    dispMaska=15;                // maska na blokovani mist 
displeje (0 blokovano)**
**uint8_t    dispMaskaBlik=15;            // maska na blikani mist 
displeje (0 blikat)**
**uint8_t    blikMask=255-L1_mask-L2_mask;    // blikani s dvojteckou, 
stupnem a LEDkama (255 nic)**
**const uint8_t        dispZnaky[10]={**
**    //cedgabf-**
**    0b00010000, // 0**
**    0b01111010, // 1**
**    0b10000010, // 2**
**    0b01000010, // 3**
**    0b01101000, // 4**
**    0b01000100, // 5**
**    0b00000100, // 6**
**    0b01110010, // 7**
**    0b00000000, // 8**
**    0b01000000  // 9**
**};**
**
*// AL_on/AL_off je zapínání a vypínání anod LEDek
// A_port je port na kterém jsou společné anody
// SEG_port je na segmenty
// L1_mask a pod. - dvojtečka a stupeň na displeji
*
**ISR (ADC0_RESRDY_vect) { // 37,1 kHz =============**
**    static uint8_t    dispInd=0;**
****
**    if (++dispInd>=22) dispInd=0;**
**    A_port=15; AL_off;**
**    if (dispInd<L_ind) {**
**        SEG_port=dispData[dispInd];**
**        A_port=15-((1<<dispInd) & dispMaska);**
**    } else if (dispInd==L_ind) {**
**        SEG_port=dispData[L_ind] & dispData[LED_ind];**
**        AL_on;**
**    } else if (dispInd==20) { **
**        adDataRaw=ADC0_RES; // read ADC**
**        adSync=1;**
**    }**
**    adTest++; // mereni f**
****
**    ADC0_INTFLAGS=1;**
**}*

No a to je vlastně všechno, co by mělo sloužit k inspiraci jak 
zobrazovat displejem, když už máme obsah pole dispData. Ale lze se 
podívat i dál:

Zobrazení čísel pak dělaj funkce jako:
*void dispN(uint16_t xx) { // jedno 4mistne cislo ========
     int8_t n=0;
     uint16_t x;

     x=xx;
     for (n=0; n<4; n++) {
         dispData[3-n]=dispZnaky[x % 10];
         x/=10;
     }
}*

A někde v čekací funkci je oblast začínající if (sekSync==1) { sekSync=0;
a v ní se nachází i
*if (sekundy & 1) {**
**    dispData[L_ind]=blikMask; // blikani s dvojteckou, stupnem a 
LEDkama (255 nic)**
**} else {**
**    dispData[L_ind]=255;**
**}**
*
pak ještě v podobné, milisekundové sekci:
*if (++msCnt>399) msCnt=0;**
**if (dispMaskaBlik!=15) { // blikani cisel pri nastaveni**
**    if (msCnt<200) dispMaska=dispMaskaBlik; else dispMaska=15;**
**}*

PH

Dne 08.09.2023 v 10:03 Jan Waclawek napsal(a):
> [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;
> };
>
> _______________________________________________
> HW-list mailing list  -  sponsored bywww.HW.cz
> Hw-list na list.hw.cz
> http://list.hw.cz/mailman/listinfo/hw-list
------------- další část ---------------
HTML příloha byla odstraněna...
URL: <http://list.hw.cz/pipermail/hw-list/attachments/20230908/2e868e26/attachment-0001.htm>


Další informace o konferenci Hw-list