/* Libreria per il TM1638, utilizzabile con la demoboard LED&KEY e QYF-TM1638. *  * Per utilizzare questa libreria sono necessarie alcune configurazioni: * - Dichiarare _XTAL_FREQ ... nel main prima di includere questa libreria,  *   perchè necessita delle funzioni di ritardo del compilatore  *   (si può usare sia il quarzo interno che quello esterno). * - Bisogna includere sia il file TM1638picD.h che il file TM1638picD.c nel main * - I pin utilizzati (DIO, CLK, STB) POSSONO ESSERE CAMBIATI a proprio *   piacimento, la cosa necessaria è CONFIGURARLI COME OUTPUT E COME DIGITALI  * - Per far funzionare il display occorre settarlo attraverso la funzione *   ImpostaDisplay(...); e resettarlo con Resetta(); *  */
#define DO  LATDbits.LATD5#define DI  PORTDbits.RD5#define CLK LATDbits.LATD6 #define STB LATDbits.LATD7
#define ON 1#define OFF 0
const char FontCarattere[] = {    0b00000000, // (32)  <space>    0b10000110, // (33) !    0b00100010, // (34) "    0b01111110, // (35) #    0b01101101, // (36) $    0b00000000, // (37) %    0b00000000, // (38) &    0b00000010, // (39) '    0b00110000, // (40) (    0b00000110, // (41) )    0b01100011, // (42) *    0b00000000, // (43) +    0b00000100, // (44) ,    0b01000000, // (45) -    0b10000000, // (46) .    0b01010010, // (47) /    0b00111111, // (48) 0    0b00000110, // (49) 1    0b01011011, // (50) 2    0b01001111, // (51) 3    0b01100110, // (52) 4    0b01101101, // (53) 5    0b01111101, // (54) 6    0b00000111, // (55) 7    0b01111111, // (56) 8    0b01101111, // (57) 9    0b00000000, // (58) :    0b00000000, // (59) ;    0b00000000, // (60) <    0b01001000, // (61) =    0b00000000, // (62) >    0b01010011, // (63) ?    0b01011111, // (64) @    0b01110111, // (65) A    0b01111111, // (66) B    0b00111001, // (67) C    0b00111111, // (68) D    0b01111001, // (69) E    0b01110001, // (70) F    0b00111101, // (71) G    0b01110110, // (72) H    0b00000110, // (73) I    0b00011111, // (74) J    0b01101001, // (75) K    0b00111000, // (76) L    0b00010101, // (77) M    0b00110111, // (78) N    0b00111111, // (79) O    0b01110011, // (80) P    0b01100111, // (81) Q    0b00110001, // (82) R    0b01101101, // (83) S    0b01111000, // (84) T    0b00111110, // (85) U    0b00101010, // (86) V    0b00011101, // (87) W    0b01110110, // (88) X    0b01101110, // (89) Y    0b01011011, // (90) Z    0b00111001, // (91) [    0b01100100, // (92) \ (this can't be the last char on a line, even in comment or it'll concat)    0b00001111, // (93) ]    0b00000000, // (94) ^    0b00001000, // (95) _    0b00100000, // (96) `    0b01011111, // (97) a    0b01111100, // (98) b    0b01011000, // (99) c    0b01011110, // (100) d    0b01111011, // (101) e    0b00110001, // (102) f    0b01101111, // (103) g    0b01110100, // (104) h    0b00000100, // (105) i    0b00001110, // (106) j    0b01110101, // (107) k    0b00110000, // (108) l    0b01010101, // (109) m    0b01010100, // (110) n    0b01011100, // (111) o    0b01110011, // (112) p    0b01100111, // (113) q    0b01010000, // (114) r    0b01101101, // (115) s    0b01111000, // (116) t    0b00011100, // (117) u    0b00101010, // (118) v    0b00011101, // (119) w    0b01110110, // (120) x    0b01101110, // (121) y    0b01000111, // (122) z    0b01000110, // (123) {    0b00000110, // (124) |    0b01110000, // (125) }    0b00000001, // (126) ~};
#if (LEDKEY_TEST == 1)const char IndirizzoLed[] = {    0b00000001, //LED1    0b00000011, //LED2    0b00000101, //LED3    0b00000111, //LED4    0b00001001, //LED5    0b00001011, //LED6    0b00001101, //LED7    0b00001111, //LED8};
const char IndirizzoDisplay[] = {    0b00000000, //DISPLAY1    0b00000010, //DISPLAY2    0b00000100, //DISPLAY3    0b00000110, //DISPLAY4    0b00001000, //DISPLAY5    0b00001010, //DISPLAY6    0b00001100, //DISPLAY7    0b00001110, //DISPLAY8};#endif
#if (QYF_TEST == 1)const char IndirizzoDisplay[] = {    0b00000001, //DISPLAY8    0b00000010, //DISPLAY7    0b00000100, //DISPLAY6    0b00001000, //DISPLAY5    0b00010000, //DISPLAY4    0b00100000, //DISPLAY3    0b01000000, //DISPLAY2    0b10000000, //DISPLAY1};
const char Segmenti[] = {    0b11000000, //a    0b11000010, //b    0b11000100, //c    0b11000110, //d    0b11001000, //e    0b11001010, //f    0b11001100, //g    0b11001110, //DP};#endif
#if (LEDKEY_TEST == 1)/* Questa funzione scrive un byte in un determinato indirizzo *  * @param: unsigned char Adress --> l'indirizzo nel quale scrivere il byte *         unsigned char Dato --> byte da scrivere * @return: nessuno */  /* Questa funzione crea ritardi di  microsecondi *  * @param: nessuno * @return: nessuno */void RitardoUS(int Conta) {    while (Conta > 0) {        __delay_us(1);        Conta--;    }}

//MODIFICA APPORTATA NELLA LIBRERIA  //NON SONO PIU' PRESENTI DELLE FUNZIONI COMUNI 
/* Questa funzione scrive un byte sul pun DIO * * @param: unsigned char data --> byte da scrivere * @return: nessuno */void Scrivi1638(unsigned char Dato) {    for (char i = 0; i < 8; i++) {        DO = (Dato & 0X01);        CLK = 0;        Dato = Dato >> 1;        RitardoUS(2);        CLK = 1;    }    RitardoUS(20);}
/* Questa funzione legge un byte dal pin DIO *   * @param: nessuno * @return: unsigned char ... --> byte letto */unsigned char Leggi1638(void) {    unsigned char i;    unsigned char Temporaneo = 0;    DO = 1;    for (i = 0; i < 8; i++) {        Temporaneo >>= 1;        CLK = 0;        if (DI == 1)            Temporaneo |= 0x80;        CLK = 1;    }    return Temporaneo;}
/* Questa funzione manda un comando al TM1638 * * @param: unsigned char Comando --> comando da inviare * @return: nessuno */void ScriviComando(unsigned char Comando) {    STB = 0;    Scrivi1638(Comando);    STB = 1;}

void ScriviDato(unsigned char Indirizzo, unsigned char Dato) {    //Funzione necessaria per inviare un dato (da datasheet)    ScriviComando(0x44);    STB = 0;    Scrivi1638(0xC0 | Indirizzo);    Scrivi1638(Dato);    STB = 1;}
/* Questa funzione resetta i TM1638 *  * @param: nessuno * @return: nessuno */void Resetta(void) {    //Imposta il TM1638 per funzionare in modalità auto-incremento    ScriviComando(0x40);    //Metto il pin STROBE a livello basso per inviare un dato    STB = 0;    //Seleziono il registro 0    Scrivi1638(0xC0);    //Scrivo 0 nel registro 16 volte    for (char i = 0; i < 16; i++) {        Scrivi1638(0x00);    }    //Metto il pin STROBE a livello alto per indicare che la trasmissione del dato è finita    STB = 1;}
/* Questa funzione setta i parametri inziali del TM1638  * * @param: char state --> display abilitato(1, ON) display disabilitato (0, OFF) *         char brightness --> luminosità (0...7) * @return: nessuno */void ImpostaDisplay(unsigned char Stato, unsigned char Luminosita) {    unsigned char Comando = 0x80;    if (Stato == 1)        Comando = Comando | 0x08;    if (Luminosita < 7)        Comando = Comando | Luminosita;    ScriviComando(Comando);}
/* Questa funzione controlla un led collegato al TM1638 * * @param: char led --> il numero del led da controllare (0...7) *         char state --> led acceso(1 o ON) led spento(0 o OFF) * @return: nessuno */void LedSettaggioSingolo(char Led, char Stato) {    char s;    if (Stato == 1)        s = 0x01;    else        s = 0x00;    ScriviDato(IndirizzoLed[Led], s);}/* Questa funzione accende e spegne i led * * @param: char Led --> i led da accendere (1) da spegnere (0) *                      Esempio: LedSettaggio(0b00001001); *                               // accendo i led 1,4 gli altri li spengo * @return: nessuno */void LedSettaggio(char Led) {    for (char i = 0; i < 8; i++) {        char controllo = (Led >> i) & 0x01;        if (controllo == 0x01)            LedSettaggioSingolo(i, ON);        else            LedSettaggioSingolo(i, OFF);    }}
/* Questa funzione spegne tutti i led *  * @param: nessuno * @return: nessuno */void LedPulisci(void) {    for (char i = 0; i < 8; i++) {        //Scrivo nel led[i] niente, quindi spengo il led        ScriviDato(IndirizzoLed[i], 0x00);    }}
/* Questa funzione scrive una cifra o un carattere ad una determinata posizione * * @param: unsigned char c --> cifra o numero da scrivere *         unsigned char pos --> numero del display in cui scrivere * @return: none */void MostraCarattere(unsigned char c, unsigned char pos) {    ScriviComando(0x44);    STB = 0;    Scrivi1638(0xc0 | IndirizzoDisplay[pos]);    Scrivi1638(FontCarattere[c - 32]);    STB = 1;}
/* Questa funzione scrive una stringa *  * @param: const char *string --> stringa da scrivere * @return: nessuno */void MostraStringa(const char *Stringa) {    //Calcolo il numero dei caratteri nella stringa    short int Lunghezza = strlen(Stringa);    for (char i = 0; i < Lunghezza; i++) {        //Scrivo la cifra meno significativa nel display[8] e cosi via        ScriviDato(IndirizzoDisplay[8 - (Lunghezza - i)], FontCarattere[Stringa[i] - 32]);    }    for (char i = Lunghezza; i < 8; i++) {        ScriviDato(IndirizzoDisplay[i - Lunghezza], 0x00);    }}
/* Questa funzione scrive un intero *  * @param: int Numero --> numero da scrivere (con o senza segno) * @return: nessuno */void MostraIntero(const long Numero) {    char buffer[8];    //Converto il numero intero in una stringa    sprintf(buffer, "%ld", Numero);    //Scrivo la stringa, appena convertita, nei display    MostraStringa(buffer);}
/* Questa funzione cancella il display *  * @param: nessuno * @return: nessuno */void DisplayPulisci(void) {    for (char i = 0; i < 8; i++) {        //Scrivo nel display[i] niente, quindi spengo il display        ScriviDato(IndirizzoDisplay[i], 0x00);    }}
void ProvaScheda(void){    MostraStringa("88888888"); //vedere ...            LedSettaggio(255);            __delay_ms(500);            MostraStringa("........");            __delay_ms(500);            Resetta();}
void ProvaScheda1(void){    MostraStringa("88888888"); //vedere ...            LedSettaggio(255);            __delay_ms(500);            MostraStringa("........");            __delay_ms(500);            PulsanteLED();            Resetta();}
void PulsanteLED(){    ImpostaDisplay(ON, 5);//impostiamo lo stato del display attivo e                           // con una determinata luminosita'    Resetta(); //funzione che permette di resettare il display        int a=0;    int b=0;    int c=0;    int d=0;    int e=0;    int f=0;    int g=0;    int h=0;    int i=0;    int j=0;    int k=0;    int l=0;        while(1) //ciclo infinito      {        if(LeggiPulsanti()==(0b00000001) && a==0){            LedSettaggioSingolo(0b00000000, 1); // premendo S1 si accende LED1            a=1;            __delay_ms(250);        }        if(LeggiPulsanti()==(0b00000010) && b==0){            LedSettaggioSingolo(0b00000001, 1); // premendo S2 si accende LED2            b=1;            __delay_ms(250);        }        if(LeggiPulsanti()==(0b00000100) && c==0){            LedSettaggioSingolo(0b00000010, 1); // premendo S3 si accende LED3            c=1;            __delay_ms(250);        }         if(LeggiPulsanti()==(0b00001000) && d==0){            LedSettaggioSingolo(0b00000011, 1); // premendo S4 si accende LED4            d=1;            __delay_ms(250);        }         if(LeggiPulsanti()==(0b00010000) && e==0){            LedSettaggioSingolo(0b00000100, 1); // premendo S5 si accende LED5            e=1;            __delay_ms(250);        }         if(LeggiPulsanti()==(0b00100000) && f==0){            LedSettaggioSingolo(0b00000101, 1); // premendo S6 si accende LED6            f=1;            __delay_ms(250);        }         if(LeggiPulsanti()==(0b01000000) && g==0){            LedSettaggioSingolo(0b00000110, 1); // premendo S7 si accende LED7            g=1;            __delay_ms(250);        }         if(LeggiPulsanti()==(0b10000000) && h==0){            LedSettaggioSingolo(0b00000111, 1); // premendo S8 si accende LED8            h=1;            __delay_ms(250);        }          ////////////////////////////////////////////////////////////////////////                        if(LeggiPulsanti()==(0b00000001) && a==1){            LedSettaggioSingolo(0b00000000, 0); // premendo S1 si spengne LED1            a=0;            __delay_ms(250);        }        if(LeggiPulsanti()==(0b00000010) && b==1){            LedSettaggioSingolo(0b00000001, 0); // premendo S2 si spengne LED2            b=0;            __delay_ms(250);        }        if(LeggiPulsanti()==(0b00000100) && c==1){            LedSettaggioSingolo(0b00000010, 0); // premendo S3 si spengne LED3            c=0;            __delay_ms(250);        }         if(LeggiPulsanti()==(0b00001000) && d==1){            LedSettaggioSingolo(0b00000011, 0); // premendo S4 si spengne LED4            d=0;            __delay_ms(250);        }         if(LeggiPulsanti()==(0b00010000) && e==1){            LedSettaggioSingolo(0b00000100, 0); // premendo S5 si spengne LED5            e=0;            __delay_ms(250);        }         if(LeggiPulsanti()==(0b00100000) && f==1){            LedSettaggioSingolo(0b00000101, 0); // premendo S6 si spengne LED6            f=0;            __delay_ms(250);        }         if(LeggiPulsanti()==(0b01000000) && g==1){            LedSettaggioSingolo(0b00000110, 0); // premendo S7 si spengne LED7            g=0;            __delay_ms(250);        }         if(LeggiPulsanti()==(0b10000000) && h==1){            LedSettaggioSingolo(0b00000111, 0); // premendo S8 si spengne LED8            h=0;            __delay_ms(250);        }        break;    } // Fine ciclo infinito }


/* Questa funzione legge lo stato di tutti e 8 i pulsanti *  * @param: nessuno * @return: unsigned char ... --> il valore dei pulsanti (vedi tabella) * |0 0 0 0 0 0 0 0| --> nessun pulsante premuto * |0 0 0 0 0 0 0 1| --> premuto il pulsante 1 * |0 0 0 0 0 0 1 0| --> premuto il pulsante 2 *        ... * |1 0 0 0 0 0 0 0| --> premuto il pulsante 8 *  * |0 0 0 0 0 0 1 1| --> premuto il pulsante 1 e 2 * |0 0 1 0 0 1 0 1| --> premuto il pulsante 1, 3 e 6 *        ... * |1 1 1 1 1 1 1 1| --> tutti i pulsanti premuti */unsigned char LeggiPulsanti(void) {    unsigned char Pulsanti = 0;    STB = 0;    //Comando necessario per leggere i pulsanti    Scrivi1638(0x42);    for (char i = 0; i < 4; i++) {        Pulsanti |= Leggi1638() << i;    }    STB = 1;    return Pulsanti;}#endif
#if (QYF_TEST == 1) //MODIFICA APPORTATA NELLA LIBRERIA  //NON SONO PIU' PRESENTI DELLE FUNZIONI COMUNI 
/* Questa funzione crea ritardi di  microsecondi *  * @param: nessuno * @return: nessuno */void RitardoUSQYF(int Conta) {    while (Conta > 0) {        __delay_us(1);        Conta--;    }}
/* Questa funzione scrive un byte sul pun DIO * * @param: unsigned char data --> byte da scrivere * @return: nessuno */void Scrivi1638QYF(unsigned char Dato) {    for (char i = 0; i < 8; i++) {        DO = (Dato & 0X01);        CLK = 0;        Dato = Dato >> 1;        RitardoUSQYF(2);        CLK = 1;    }    RitardoUSQYF(20);}
/* Questa funzione legge un byte dal pin DIO *   * @param: nessuno * @return: unsigned char ... --> byte letto */unsigned char Leggi1638QYF(void) {    unsigned char i;    unsigned char Temporaneo = 0;    DO = 1;    for (i = 0; i < 8; i++) {        Temporaneo >>= 1;        CLK = 0;        if (DI == 1)            Temporaneo |= 0x80;        CLK = 1;    }    return Temporaneo;}
/* Questa funzione manda un comando al TM1638 * * @param: unsigned char Comando --> comando da inviare * @return: nessuno */void ScriviComandoQYF(unsigned char Comando) {    STB = 0;    Scrivi1638QYF(Comando);    STB = 1;}
/* Questa funzione scrive un byte in un determinato indirizzo *  * @param: unsigned char Dato --> byte da scrivere  *         unsigned char Indirizzo --> l'indirizzo nel quale scrivere il byte * * @return: nessuno */void ScriviDatoQYF(unsigned char Dato, unsigned char Indirizzo) {    //Funzione necessaria per inviare un dato (da datasheet)    ScriviComandoQYF(0x44);    STB = 0;    Scrivi1638QYF(Dato);    Scrivi1638QYF(Indirizzo);    STB = 1;}
/* Questa funzione resetta i TM1638 *  * @param: nessuno * @return: nessuno */void ResettaQYF(void) {    //Imposta il TM1638 per funzionare in modalità auto-incremento    ScriviComandoQYF(0x40);    //Metto il pin STROBE a livello basso per inviare un dato    STB = 0;    //Seleziono il registro 0    Scrivi1638QYF(0xC0);    //Scrivo 0 nel registro 16 volte    for (char i = 0; i < 16; i++) {        Scrivi1638QYF(0x00);    }    //Metto il pin STROBE a livello alto per indicare che la trasmissione del dato è finita    STB = 1;}
/* Questa funzione setta i parametri inziali del TM1638  * * @param: char state --> display abilitato(1, ON) display disabilitato (0, OFF) *         char brightness --> luminosità (0...7) * @return: nessuno */void ImpostaDisplayQYF(unsigned char Stato, unsigned char Luminosita) {    unsigned char Comando = 0x80;    if (Stato == 1)        Comando = Comando | 0x08;    if (Luminosita < 7)        Comando = Comando | Luminosita;    ScriviComandoQYF(Comando);}
/* Questa funzione scrive una stringa *  * @param: const char *string --> stringa da scrivere * @return: nessuno */void MostraStringaQYF(const char *Stringa) {    //Calcolo il numero dei caratteri nella stringa    short int Lunghezza = strlen(Stringa);    char Display;    for (char i = 0; i < 8; i++) {        Display = 0x00;        for (signed char j = (Lunghezza - 1); j >= 0; j--) {            if(FontCarattere[Stringa[(Lunghezza - 1) - j] - 32] >> i & 0x01)                Display |= IndirizzoDisplay[j];        }        ScriviDatoQYF(Segmenti[i], Display);    }}
/* Questa funzione scrive un intero *  * @param: int Numero --> numero da scrivere (con o senza segno) * @return: nessuno */void MostraInteroQYF(const long Numero){    char buffer[8];    //Converto il numero intero in una stringa    sprintf(buffer, "%ld", Numero);    //Scrivo la stringa, appena convertita, nei display    MostraStringaQYF(buffer);}
/* Questa funzione cancella il display *  * @param: nessuno * @return: nessuno */void DisplayPulisciQYF(void) {    for (char i = 0; i < 8; i++) {        //Scrivo nel display[i] niente, quindi spengo il display    }}
/* Questa funzione legge lo stato di tutti e 8 i pulsanti *  * @param: nessuno * @return: unsigned int ... --> il valore dei pulsanti (vedi tabella) * |0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0| --> nessun pulsante premuto * |0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1| --> premuto il pulsante 1 * |0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0| --> premuto il pulsante 2 *        ... * |0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0| --> premuto il pulsante 8 *  * |0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1| --> premuto il pulsante 1 e 2 * |0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 1| --> premuto il pulsante 1, 3 e 6 *        ... * |1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1| --> tutti i pulsanti premuti */unsigned int LeggiPulsantiQYF(void) {    unsigned int Pulsanti = 0;    STB = 0;    //Comando necessario per leggere i pulsanti    Scrivi1638QYF(0x42);    for (int i = 0; i < 4; i++) {        unsigned char Registrati = Leggi1638QYF();
        Registrati = (((Registrati & 0b1000000) >> 3 | (Registrati & 0b100)) >> 2) | (Registrati & 0b100000) | (Registrati & 0b10) << 3;
        Pulsanti |= ((Registrati & 0x000F) << (i << 1)) | (((Registrati & 0x00F0) << 4) << (i << 1));    }    STB = 1;    return Pulsanti;}#endif