Не понял вопроса, да и в вопросе отсутствуют примеры кода и тех. данные SPI, но объясню, как работает блок SPI в AVR серии ATMega.
В режиме MASTER блок SPI никак не управляет пином SS (Slave Select). Соответственно, им надо управлять программно. А раз так, то для этой цели можно выбрать, помимо SS, любой другой пин, предварительно сконфигурировав его на выход (например в случае, когда SLAVE устройств на шине несколько).
В режиме SLAVE (в режиме SLAVE блок SPI тактируется внешним устройством) блоком SPI можно управлять двумя путями:
1. Перевести программно с помощью флага в регистре управления
2. Перевести аппаратно с помощью пина SS.
И вот последний способ имеет одну особенность: при подаче на пин SS низкого уровня, блок SPI сразу же переходит в режим SLAVE. Поэтому, если блок SPI работает в режиме MASTER, то пин SS лучше сразу же переводить как выход.
Что такое счетчик массива - я не знаю (в блоке SPI нет такого счетчика).
Смещение начала массива может происходить по весьма простой причине - программный код в обработчике прерывания не успевает обработать получаемые данные.
ДОПОЛНЕНО:
Прерывание по пину SS возникает сразу же, как только внешнее устройство переводит пин SS в ноль. Поэтому индекс массива можно обнулить в самом начале прерывания от SPI.
Но я делаю по другому. Зачем индекс, если можно "скользить" по ячейкам массива указателем?
//... Отправить и получить несколько байт по SPI. Принятые данные лежат в data
void SPI_ReadArray(uint8_t num, uint8_t *data)
{
while(num--)
{
*data++ = SPI_WriteByte(*data);
}
}
где:
//... Передать и принять байт данных
inline uint8_t SPI_WriteByte(uint8_t data)
{
uint8_t temp;
SPDR = data;
while(!(SPSR & (1<<SPIF)));
temp = SPDR;
return temp;
}