Как оптимизировать этот код с помощью 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. Если вам действительно нужен этот самый быстрый подход, вам может понадобиться написать несколько строк сборки.