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 :
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: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;
Je trouve que ce code n'est pas très efficace. Pensant faire mieuxCode: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 pense utiliser ce nouveau code :
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 ?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) {....
Merci pour votre aide
Jean-Marie
-----