Доброго дня всем.
Имеется инклинометр ADIS16209 подключенный к плате с AT91SAM7S64. Последовательно считываю значения регистров POWER_SUPPLY, STATUS, X_INC с интервалом примерно 0,5с. Так вот примерно 50/50 считываются или 0 или правильные значения, причём POWER_SUPPLY может иметь корректное значение(3286mV), а X_INC=0, может наоборот, могут быть оба 0 или оба правильные(никакой системы). STATUS может быть равным 8 т.е. указывает на ошибку SPI или 0. Конфигурирование SPI контроллера проводил совместно с datasheet-ом на ADIS16209, т.е. тайминги, задержки на мой взгляд правильные, болле того, перепроверял их не раз и дёргал тоже. Может кто сталкивался с подобным, подскажите пож.
Код
Инициализация SPI
void InitSPIforADIS16209 (void) {
// Конфигурируем ножки для работы SPI
PinConfig(BIT12 | BIT13 | BIT14 | BIT9,PIN_DISABLE,NONE,PULLUP_DISABLE,NONE); // Отключаем ноги MOSI, MISO, SPCK, NPCS1 от PIO. NPCS1-сигнал выбора ADIS16209
PinSwitchAB (BIT12 | BIT13 | BIT14,PERIFERIA_A); // Для ног указываем на периферию А
PinSwitchAB (BIT9,PERIFERIA_B); // Для NPCS1 указываем на периферию B
//Разрешаем тактирование SPI
AT91C_BASE_PMC->PMC_PCER = 1<<AT91C_ID_SPI;
//Отключение и сброс SPI
p_Spi->SPI_CR |= AT91C_SPI_SPIDIS | AT91C_SPI_SWRST | AT91C_SPI_LASTXFER; //AT91C_SPI_LASTXFER Снятие сигнала NPCS при завершении передачи
//Конфигурируем SPI_MR
//SPI в режиме Master, фиксированная перефирия, линии выбора связаны с чипами, тактирование от MCK, обнаружения ошибок нет, локального "шлейфа" нет
// чип подключен к NPCS1
// у рег. SPI_MR поле DLYBCS, определяет время задержки от момента дизактивации CS до момента активации другого NPCS = DLYBCS/MCK 128/48000000=2,6мкс
p_Spi->SPI_MR |= AT91C_SPI_MSTR | AT91C_SPI_PS_FIXED | 1<<16 | 127<<24 | AT91C_SPI_MODFDIS;
// Настраиваем SPI_CSR1-регистр выбора микросхемы(ADIS16209)
// Полярность синхросигнала CPOL=1, Полярность синхросигнала PHASE=0, 16 битный режим, поле SCBR= т.е. SPCK= MCK/SCBR = 48000000/48 = 1.0Mhz
// расчёт таймингов: Значение по умолчанию регистра SMPL_PRD, ADIS16209, равно 14(Fs = 1/Ts где: Ts=Tb x Ns + 122.07мкс, где: Tb=244.14мкс, Ns=14; Fs= 3540 SPS)
// если SMPL_PRD <= 0x07(Fs>=546 Hz) ADIS16209 работает в быстром режиме, MaxSPCK = 2.5Mhz, не забываем, у нас 1.0Mhz
// tDATARATE(ADIS16209) - мин. время, между двумя последовательными активациями CS = 40мкс - рекомендация AD
// DLYBCT(SPI_CSRx)(время задержки между двумя последовательными передачами), если FDIV(SPI_MR)=0, то Tзад= (32 x DLYBCT)/MCK+SCBR/(2 x MCK)
// Тзад = (32x100)/48000000 + 48/(2 x 48000000) = 3200 / 480000 + 0.5 = 67.1мкс, что вполне ...
// DLYBS(SPI_CSRx)(Время задержки перед SPCK) определяет время задержки от начала значащего(активного) уровня сигнала NPCS до первого значащего перепада SPCK
// tcs(ADIS16209) вышеуказанный параметр ADIS16209 = min 48.8ns(рекомендация AD), вычисление: если FDIV(SPI_MR)=0, то время задержки DLYBS/MCK=
// = 4/48000000= 83.3ns, что вполне ...
//
p_Spi->SPI_CSR[1] = AT91C_SPI_CPOL | AT91C_SPI_BITS_16 | 48<<8 | 4<<16 | 100<<24;
//Разрешаем SPI
p_Spi->SPI_CR |= AT91C_SPI_SPIEN;
// Процедурой запускаем обмен по SPI
unsigned int ADIS16209_trans(unsigned int data)
{
p_Spi->SPI_TDR = data<<8 | 1<<24 | 1<<16;
while(!(p_Spi->SPI_SR & AT91C_SPI_RDRF));
return (p_Spi->SPI_RDR);
}
// Здесь читаем соответствующий регистр
void adis16209_PowerSupply (void) {
unsigned int result,j,i;
const float k = 0.30518;
float PWR_SUPPLY;
j=0;
s1:
result = ADIS16209_trans(0x2);
result = ADIS16209_trans(0x2);
result &= 0xFFFF;
i= result & 0x4000;
if (j==20) {Send32bitVal(mb_Addr,READ_HOLDING_REGISTERS,0); return;}
j++;
if (i==0) goto s1;
result &= 0x3FFF;
PWR_SUPPLY = result*k;
Send32bitFloatVal(mb_Addr,READ_HOLDING_REGISTERS,PWR_SUPPLY);
}
}