Оптимизация функции

Patriot
Offline
Зарегистрирован: 25.06.2015

Люди добрые, подскажите как монжо данную функцию оптимизировать еще больше? Вместо стольки обращений к регистрам портов использовать поменьше. Я смог только так реализовать работу с портами. 

#define B_MASK  0b000010000000000000000000000000;
    #define C_MASK  0b010111111000000000000000000000;
   
    #define write_8(x)   {  PIOC->PIO_CODR = C_MASK; PIOB->PIO_CODR = B_MASK; \
                            if((0x01 & ((x >> 2)))) PIOB->PIO_SODR = 1<<25; \
                            if((0x01 & ((x >> 3)))) PIOC->PIO_SODR = 1<<28; \
                            if((0x01 & ((x >> 4)))) PIOC->PIO_SODR = 1<<26; \
                            if((0x01 & ((x >> 5)))) PIOC->PIO_SODR = 1<<25; \
                            if((0x01 & ((x >> 6)))) PIOC->PIO_SODR = 1<<24; \
                            if((0x01 & ((x >> 7)))) PIOC->PIO_SODR = 1<<23; \
                            if((0x01 & ((x >> 0)))) PIOC->PIO_SODR = 1<<22; \
                            if((0x01 & ((x >> 1)))) PIOC->PIO_SODR = 1<<21; \
    }

Пробовал оптимизировать хотя бы 4-пина до одного обращения через маску, но что-то не завелось:

#define B_MASK  0b000010000000000000000000000000;
    #define C_MASK  0b010111111000000000000000000000;
  
    #define write_8(x)   {  PIOC->PIO_CODR = C_MASK; PIOB->PIO_CODR = B_MASK; \
                            if((0x01 & ((x >> 2)))) PIOB->PIO_SODR = 1<<25; \
                            if((0x01 & ((x >> 3)))) PIOC->PIO_SODR = 1<<28; \
                            PIOC->PIO = (x>>4<<23) ^ C_MASK; \
                            if((0x01 & ((x >> 0)))) PIOC->PIO_SODR = 1<<22; \
                            if((0x01 & ((x >> 1)))) PIOC->PIO_SODR = 1<<21; \
    }

Подскажите, что не так? Вроде обрезаю справа на 4-е символа, добавляю 23 нуля и инвертирую пины.

 

MagicianT
Offline
Зарегистрирован: 03.10.2015
Что, TFT LCD   ?
Я бы не использовал "if"    , просто раскадрировал сначала, а потом одна запись в порт - (пример не мои, из библиотеки   Adafruit TFTLCD    ):
  #define write8inline(d) { \
   PIO_Set(PIOD, (((d) & 0x08)<<(7-3))); \
   PIO_Clear(PIOD, (((~d) & 0x08)<<(7-3))); \
   PIO_Set(PIOC, (((d) & 0x01)<<(22-0)) | (((d) & 0x02)<<(21-1))| (((d) & 0x04)<<(29-2))| (((d) & 0x10)<<(26-4))| (((d) & 0x40)<<(24-6))| (((d) & 0x80)<<(23-7))); \
   PIO_Clear(PIOC, (((~d) & 0x01)<<(22-0)) | (((~d) & 0x02)<<(21-1))| (((~d) & 0x04)<<(29-2))| (((~d) & 0x10)<<(26-4))| (((~d) & 0x40)<<(24-6))| (((~d) & 0x80)<<(23-7))); \
   PIO_Set(PIOB, (((d) & 0x20)<<(27-5))); \
   PIO_Clear(PIOB, (((~d) & 0x20)<<(27-5))); \
   WR_STROBE; }