<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    Aha tak to je ten případ smazat a napsat úplně znova:-)<br>
    <br>
    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.)<br>
    <br>
    <font color="#800000"><b>uint8_t    dispData[6]={0, 0, 0, 0, 0, 0};
        // 0-3 cisla, 4 Lx, 5 LEDx</b><b><br>
      </b><b>uint8_t    dispMaska=15;                // maska na
        blokovani mist displeje (0 blokovano)</b><b><br>
      </b><b>uint8_t    dispMaskaBlik=15;            // maska na blikani
        mist displeje (0 blikat)</b><b><br>
      </b><b>uint8_t    blikMask=255-L1_mask-L2_mask;    // blikani s
        dvojteckou, stupnem a LEDkama (255 nic)</b><b><br>
      </b><b>const uint8_t        dispZnaky[10]={</b><b><br>
      </b><b>    //cedgabf-</b><b><br>
      </b><b>    0b00010000, // 0</b><b><br>
      </b><b>    0b01111010, // 1</b><b><br>
      </b><b>    0b10000010, // 2</b><b><br>
      </b><b>    0b01000010, // 3</b><b><br>
      </b><b>    0b01101000, // 4</b><b><br>
      </b><b>    0b01000100, // 5</b><b><br>
      </b><b>    0b00000100, // 6</b><b><br>
      </b><b>    0b01110010, // 7</b><b><br>
      </b><b>    0b00000000, // 8</b><b><br>
      </b><b>    0b01000000  // 9</b><b><br>
      </b><b>};</b><b><br>
      </b><b><br>
      </b>// AL_on/AL_off je zapínání a vypínání anod LEDek<br>
      // A_port je port na kterém jsou společné anody<br>
      // SEG_port je na segmenty<br>
      // L1_mask a pod. - dvojtečka a stupeň na displeji<br>
      <b><br>
      </b><b>ISR (ADC0_RESRDY_vect) { // 37,1 kHz =============</b><b><br>
      </b><b>    static uint8_t    dispInd=0;</b><b><br>
      </b><b>    </b><b><br>
      </b><b>    if (++dispInd>=22) dispInd=0;</b><b><br>
      </b><b>    A_port=15; AL_off;</b><b><br>
      </b><b>    if (dispInd<L_ind) {</b><b><br>
      </b><b>        SEG_port=dispData[dispInd];</b><b><br>
      </b><b>        A_port=15-((1<<dispInd) & dispMaska);</b><b><br>
      </b><b>    } else if (dispInd==L_ind) {</b><b><br>
      </b><b>        SEG_port=dispData[L_ind] & dispData[LED_ind];</b><b><br>
      </b><b>        AL_on;</b><b><br>
      </b><b>    } else if (dispInd==20) {        </b><b><br>
      </b><b>        adDataRaw=ADC0_RES; // read ADC</b><b><br>
      </b><b>        adSync=1;</b><b><br>
      </b><b>    }</b><b><br>
      </b><b>    adTest++; // mereni f</b><b><br>
      </b><b>    </b><b><br>
      </b><b>    ADC0_INTFLAGS=1;</b><b><br>
      </b><b>}</b></font><br>
    <br>
    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:<br>
    <br>
    Zobrazení čísel pak dělaj funkce jako:<br>
    <b><font color="#800000">void dispN(uint16_t xx) { // jedno 4mistne
        cislo ========<br>
            int8_t n=0;<br>
            uint16_t x;<br>
            <br>
            x=xx;<br>
            for (n=0; n<4; n++) {<br>
                dispData[3-n]=dispZnaky[x % 10];<br>
                x/=10;<br>
            }<br>
        }</font></b><br>
    <br>
    A někde v čekací funkci je oblast začínající if (sekSync==1) {
    sekSync=0;<br>
    a v ní se nachází i<br>
    <font color="#800000"><b>if (sekundy & 1) {</b><b><br>
      </b><b>    dispData[L_ind]=blikMask; // blikani s dvojteckou,
        stupnem a LEDkama (255 nic)</b><b><br>
      </b><b>} else {</b><b><br>
      </b><b>    dispData[L_ind]=255;</b><b><br>
      </b><b>}</b><b><br>
      </b></font><br>
    pak ještě v podobné, milisekundové sekci:<br>
    <font color="#800000"><b>if (++msCnt>399) msCnt=0;</b><b><br>
      </b><b>if (dispMaskaBlik!=15) { // blikani cisel pri nastaveni</b><b><br>
      </b><b>    if (msCnt<200) dispMaska=dispMaskaBlik; else
        dispMaska=15;</b><b><br>
      </b><b>}</b></font><br>
    <br>
    PH<br>
    <br>
    <div class="moz-cite-prefix">Dne 08.09.2023 v 10:03 Jan Waclawek
      napsal(a):<br>
    </div>
    <blockquote type="cite"
      cite="mid:PC1993202309081003320295eaede947@wekovci">
      <pre class="moz-quote-pre" wrap="">[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.


</pre>
      <blockquote type="cite">
        <blockquote type="cite">
          <blockquote type="cite">
            <pre class="moz-quote-pre" wrap="">
</pre>
          </blockquote>
        </blockquote>
      </blockquote>
      <pre class="moz-quote-pre" wrap="">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 by <a class="moz-txt-link-abbreviated" href="http://www.HW.cz">www.HW.cz</a>
<a class="moz-txt-link-abbreviated" href="mailto:Hw-list@list.hw.cz">Hw-list@list.hw.cz</a>
<a class="moz-txt-link-freetext" href="http://list.hw.cz/mailman/listinfo/hw-list">http://list.hw.cz/mailman/listinfo/hw-list</a>
</pre>
    </blockquote>
    <br>
  </body>
</html>