Как оптимизировать этот код с помощью c и pic16f84a?

Я использую mikroC для программирования pic16f84a, и у меня есть следующая функция

volatile unsigned short d;  // global variable

void put_data(){
    RA3_bit = d & 1;
    d >>= 1;
    RA4_bit = d & 1;
    d >>= 1;
    PORTB.B0 = d & 1;
    d >>= 1;
    PORTB.B1 = d & 1;
    d >>= 1;
    PORTB.B2 = d & 1;
    d >>= 1;
    PORTB.B3 = d & 1;
    d >>= 1;
    PORTB.B4 = d & 1;
    d >>= 1;
    PORTB.B5 = d & 1;
}

Эта функция берет каждый бит из d (8 бит) и выводит его на вывод порта RA3, RA4, RB0, ..., RB5.

как я мог оптимизировать этот код, и память - моя первая проблема.

Обновить::

из pic16f84a.h:

volatile unsigned char           PORTA               @ 0x005;
// bit and bitfield definitions
volatile bit RA0                 @ ((unsigned)&PORTA*8)+0;
volatile bit RA1                 @ ((unsigned)&PORTA*8)+1;
volatile bit RA2                 @ ((unsigned)&PORTA*8)+2;
volatile bit RA3                 @ ((unsigned)&PORTA*8)+3;
volatile bit RA4                 @ ((unsigned)&PORTA*8)+4;

volatile unsigned char           PORTB               @ 0x006;
// bit and bitfield definitions
volatile bit RB0                 @ ((unsigned)&PORTB*8)+0;
volatile bit RB1                 @ ((unsigned)&PORTB*8)+1;
volatile bit RB2                 @ ((unsigned)&PORTB*8)+2;
volatile bit RB3                 @ ((unsigned)&PORTB*8)+3;
volatile bit RB4                 @ ((unsigned)&PORTB*8)+4;
volatile bit RB5                 @ ((unsigned)&PORTB*8)+5;
volatile bit RB6                 @ ((unsigned)&PORTB*8)+6;
volatile bit RB7                 @ ((unsigned)&PORTB*8)+7;

Могу ли я использовать эти значения из заголовочного файла, чтобы сделать функцию несколько строк кода внутри цикла?

2 ответа

Решение

Предполагая, что PORTB.B0 - PORTB.B5 являются битами выходного порта, это может быть быстрее:


volatile unsigned short d;  // global variable

void put_data(){
    RA3_bit = d & 1;
    d >>= 1;
    RA4_bit = d & 1;
    d >>= 1;

    PORTB &= 0x3F; // Mask out the low 6 bits
    PORTB |= d & 0x3f;  // Or in the low 6 bits of d

    // Clean out the bits if needed in d
    d >>= 6;
}

Я бы ожидал, что ассемблер выйдет примерно вдвое быстрее, чем то, что вы делаете сейчас, может быть, больше. Использование 3-го и 4-го бита в первых двух инструкциях, вероятно, не стоит делать с расположением битов в порту. Однако, чтобы быть уверенным, всегда дважды проверяйте вывод ассемблера. Коды операций для вашего ассемблера достаточно просты, чтобы подтвердить их довольно быстро.

Прочитайте текущее значение регистра PORT или LAT для A & B. Если у этого PIC есть и PORT, и LAT, важно знать разницу, поэтому я предлагаю вам провести небольшое исследование, если вы не уверены, какой из них использовать.

Затем выполните сдвиг и маскировку, необходимые для того, чтобы убедиться, что вы меняете только соответствующие контакты, и выполняете только две операции записи, одну для порта A и одну для порта B.

В качестве альтернативы, если все остальные контакты порта A и B настроены на ввод через регистр TRIS, связанный с каждым портом, пропустите шаг чтения.

Так, например:

tmp = PORTA;
tmp = (tmp & 0xFC) | (d & 0x3);
PORTA = tmp;

tmp = PORTB;
tmp = (tmp & 0xE0) | ((d >> 2) & 0x1F);
PORTB = tmp;

Я думаю, что на самом деле это даст вам противоположный битовый порядок по сравнению с тем, что делает ваш код, поэтому вам может потребоваться "обратить" битовую манипуляцию или, в качестве альтернативы, изменить битовый порядок d перед использованием этого кода.

Кроме того, я не буду гарантировать, что это на самом деле производит более быстрый код PIC. Если вам действительно нужен этот самый быстрый подход, вам может понадобиться написать несколько строк сборки.

Другие вопросы по тегам