Привет. Посмотрел я код и вот что скажу - решение по размножению кода с заменой инструкций дергающих один бит на шаблонные копии, дергающие разные биты, выгодно, на мой взгляд, лишь если нужно задействовать два-три пина, а при б
ольшем количестве пинов накладные расходы, связанные с парой - сравнение номера канала с очередным номером + переход к следующему сравнению, если текущее сравнение ложно - оказываются тяжелее, чем накладные расходы связанные с вычислением полного байта, нужного для работы с пином.
Давай сравним, сейчас у тебя так:
Код: Выделить всё
void w1_init(unsigned char chan) // параметр - номер канала (и пина, заодно)
{
if (chan == 0){
w1_init0();
} else if(chan == 1){
...
} else
w1_init7();
}
то есть, если канал - восьмой, то
все операции с ним будут сопровождаться семью сравнениями и семью переходами! Вычисляемых переходов в AVR нету, поэтому такой метод фактически привел к алгоритму прямого перебора. Я думаю, что нужно попробовать применить в процедурах не инструкции установки/сброса бита, а инструкции вывода в порт сразу всего набора бит - байта. Разумеется, семь бит, которые мы не хотим трогать, нужно предварительно прочитать, каждая операция с битом получается такой:
1. прочитать байт из порта
2. изменить в нем нужный бит
3. вывести байт в порт
Операций там две - установить нужный бит, либо сбросить нужный бит. Делается побитным ИЛИ предыдущих бит с единичкой в нужном разряде (установка бита), либо побитным И предыдущих бит с единичками во всех разрядах кроме нужного. Что-то вроде такого:
Код: Выделить всё
static unsigned char OrMask[8] = {0x1, 0x2, 0x4, ...,0x80},
AndMask[8] = {0xFE,0xFD,0xFB,...,0x7F},
SetBit, ClrBit;
void w1_init(unsigned char chan) // параметр - такой же
{
SetBit = OrMask[chan];
ClrBit = AndMask[chan];
...
// set bit
Port = Port | SetBit;
// reset bit
Port = Port & ClrBit;
...
}
Переменные SetBit и ClrBit можно сделать локальными, разумеется.
Накладные расходы здесь тоже есть, но если нужно использовать более трех пинов, то они оказываются меньше тех, что в твоем варианте. Попробуй так, по-моему, это должно сработать лучше.
P.S. Если памяти будет так мало, что даже 16 байт будет жалко под статические битовые маски (OrMask и AndMask), то их можно, конечно, не хранить, а генерить на лету сдвигами - не так быстро, но и в этом случае расходы будут меньше, чем при прямом переборе. Да и объем кода будет почти в восемь раз меньше.
