Inversion de bit / PIC32 / LCD ili9341
Répondre à la discussion
Affichage des résultats 1 à 4 sur 4

Inversion de bit / PIC32 / LCD ili9341



  1. #1
    schneiderj

    Inversion de bit / PIC32 / LCD ili9341


    ------

    Bonsoir,

    je poste sur ce forum car il correspond à de la programmation pour un système embarqué.

    je suis en phase de finalisation de l'optimisation du code qu'Hector m'a fourni. Il s'agit d'un driver qui permet d'écrire sur ce LCD. Toutes les commandes passent par une interface SPI et pour les écritures qui ne correspondent pas à une commande j'utilise un canal DMA.

    Il reste un point qui est assez lent : il s'agit de l'écriture du texte.
    Le codage de chaque lettre est réalisé à l'aide de plusieurs bytes. Chaque byte est lu tour à tour par le programme, et en fonction la valeur de chaque bit (du byte en cour de lecture) la valeur à attribuer au pixel et calculer.

    Actuellement mon code est le suivant. Définition d'un champ de bits :

    Code:
    union {
        unsigned char DAT;
     
        struct {
            unsigned char b0 : 1;
            unsigned char b1 : 1;
            unsigned char b2 : 1;
            unsigned char b3 : 1;
            unsigned char b4 : 1;
            unsigned char b5 : 1;
            unsigned char b6 : 1;
            unsigned char b7 : 1;
        } BITS;
    } DATA;
    La valeur de Data est chargé, puis DATA est parcouru bit par bit selon (DataDMA est un buffer dans lequel je stock les valeurs que je vais envoyer à l'afficheur) :


    Code:
     DATA.DAT = *font;
        i = height; // Hauteur du caractére en pixels
        while (i) {
            j = width;  // Largeur du caractére en pixels.
     
                if (j >= 1) {
                    if (DATA.BITS.b0 > 0) {
                        DataDMA[iDataDMA] = (color >> 8);
                        iDataDMA++;
                        DataDMA[iDataDMA] = (color & 0xFF);
                        iDataDMA++;
                    } else {
                        DataDMA[iDataDMA] = 0xFF;
                        iDataDMA++;
                        DataDMA[iDataDMA] = 0xFF;
                        iDataDMA++;
                    }
                    x++;
                    j--;
                } else {
                    font++;
                    break;
                }
                if (j >= 1) {
                    if (DATA.BITS.b1 > 0) {
                        DataDMA[iDataDMA] = (color >> 8);
                        iDataDMA++;
                        DataDMA[iDataDMA] = (color & 0xFF);
                        iDataDMA++;
    ... }
    Je trouve que ce code n'est pas très efficace. Pensant faire mieux

    Je pense utiliser ce nouveau code :
    Code:
       while (j) {
            DATA.DAT = *font;
            if (iDataDMA > NBRE_DONNEE_DMA_MAX) {
                LATDbits.LATD4 = 0;
                LATDbits.LATD5 = 0;
                DmaChnSetTxfer(dmaTxChn, DataDMA, (void*) &SPI2BUF, iDataDMA, 1, 1);
    
                DmaChnSetEvEnableFlags(dmaTxChn, DMA_EV_BLOCK_DONE); // enable the transfer done interrupt, when all buffer transferred
    
                INTEnable(INT_SOURCE_DMA(dmaTxChn), INT_ENABLED); // enable the chn interrupt in the INT controller
    
                DmaTxIntFlag = 0; // clear the interrupt flag we're  waiting on
    
                DmaChnStartTxfer(dmaTxChn, DMA_WAIT_NOT, 0); // force the DMA transfer: the SPI TBE flag it's already been active
    
                // wait for the transfer to complete
                // In a real application you can do some other stuff while the DMA transfer is taking place
                LATDbits.LATD5 = 1;
                while (!DmaTxIntFlag);
                LATDbits.LATD4 = 1;
    
                iDataDMA = 0;
            }
    
            if (j >= 1) {
                Temp1 = (~DATA.BITS.b0) & 1;
                Temps2 = DATA.BITS.b0;
                DataDMA[iDataDMA] = Temp1 * 0xFF + Temp2 * ColorByteFort;
                iDataDMA++;
                DataDMA[iDataDMA] = Temp1 * 0xFF + Temp2 * ColorByteFaible;
                iDataDMA++;
                j--;
            } else {
                font++;
                break;
            }
            if (j >= 1) {....
    Mais il ne s'avère pas plus efficace que le précédant. Comment pourrais-je modifier ce code pour qu'il soit plus rapide ?

    Merci pour votre aide
    Jean-Marie

    -----

  2. #2
    terriblement

    Re : Inversion de bit / PIC32 / LCD ili9341

    Salut,

    Temp1 = (~DATA.BITS.b0) & 1;
    et
    Temp1 = (~DATA.BITS.b0);

    Sont exactement la même chose.

    PAsser par les variables temp est plus rapide que d'intégrer le calcul directement ? (certes on y accède deux fois mais sait on jamais...)

    Dans ton premier code, regarde si il y a un gain de temps entre le calcul ">" et "==".

    Ce qui me chagrine aussi c'est ca :
    while (!DmaTxIntFlag);

    Ca reste du temps perdu, une fois que ton tableau est envoyé à ta fonction, libre à toi de modifier son contenu, ie, ne pas attendre que le transfert soit fini.

  3. #3
    schneiderj

    Re : Inversion de bit / PIC32 / LCD ili9341

    Je te remercie pour ta réponse.

    Citation Envoyé par terriblement Voir le message
    Salut,

    Temp1 = (~DATA.BITS.b0) & 1;
    et
    Temp1 = (~DATA.BITS.b0);

    Sont exactement la même chose.
    C'est ce que je croyais. Sauf que le compilateur traite le bit comme un byte et me retourne 254... ce qui n'est pas ce que j'attends. Et je n'ai pas trouvé comment faire cela uniquement au niveau d'un seul bit... d'où le & 1 !


    PAsser par les variables temp est plus rapide que d'intégrer le calcul directement ?
    J'ai vérifié, et finalement non. J'ai donc abandonné ce point.

    [QUOTE]Ce qui me chagrine aussi c'est ca :
    while (!DmaTxIntFlag);[/QUOT
    Ne soit pas chagriné : ce while est là uniquement pour la mise au point du code. A terme le code ne se serra plus bloquant.

    J'ai réduit d'environs 30% le temps d'excussion de ce code en vérifiant la valeur du caratére est égale à 0 : dans ce cas je met la couleur du fond d'écran sans me poser de question.
    Et plutôt que de vérifier si j est égale à 1, je vérifie s'il est supérieur à 7. Dans ce cas j'affecte les 8 bits sans autre controle. Maintenant l'émission d'un caractére prend un peu mois d'une milli seconde, dont environs 50% que je vais récupérer (activité du DMA).

    Je vais également passer en mode 16 bits, ce qui évitera de faire le calcul pour les deux bytes de la couleur, après ... ??? A voir/discuter

    Jean-Marie

  4. #4
    terriblement

    Re : Inversion de bit / PIC32 / LCD ili9341

    Tu peux tenter ce genre de chose :

    DATA.BITS^= 1<<n;

    avec n le bit à inverser.

    Tu peux tester l'état d'un bit d'une manière similaire

  5. A voir en vidéo sur Futura

Discussions similaires

  1. Mémoire PIC32
    Par Fireball34110 dans le forum Électronique
    Réponses: 3
    Dernier message: 16/06/2015, 07h56
  2. [PIC / C] - Gestion d'un TFT avec contrôleur ILI9341
    Par jorg1n dans le forum Électronique
    Réponses: 5
    Dernier message: 25/07/2013, 08h08
  3. mosfet faible inversion, forte inversion
    Par frenchy dans le forum Électronique
    Réponses: 11
    Dernier message: 30/12/2010, 16h35
  4. Bootloader en C sur pic32
    Par invite23ada26d dans le forum Électronique
    Réponses: 17
    Dernier message: 15/03/2009, 16h12
  5. PIC32 et EXPLORER 16
    Par invitea2c70312 dans le forum Électronique
    Réponses: 4
    Dernier message: 24/12/2008, 20h42
Découvrez nos comparatifs produits sur l'informatique et les technologies.