Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: SPI у AT91SAM7X256
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Timofey
Вобщем столкнулся с такой проблемой.

Инициализирую SPI

Код
void CnfSpi(void)
{
AT91F_PIO_CfgPeriph( AT91C_BASE_PIOA,        
        ((unsigned int)AT91C_PA12_SPI0_NPCS0   ) |
        ((unsigned int)AT91C_PA16_SPI0_MISO    ) |
        ((unsigned int)AT91C_PA17_SPI0_MOSI    ) |
        ((unsigned int)AT91C_PA18_SPI0_SPCK    ) |
        ((unsigned int)AT91C_PA13_SPI0_NPCS1   ) |
        ((unsigned int)AT91C_PA14_SPI0_NPCS2   ) |
        ((unsigned int)AT91C_PA15_SPI0_NPCS3   ) ,
        0);
AT91F_PMC_EnablePeriphClock ( AT91C_BASE_PMC, 1 << AT91C_ID_SPI0 );
AT91F_SPI_Reset(AT91C_BASE_SPI0);
//определяет регистр SPI_MR
AT91F_SPI_CfgMode(AT91C_BASE_SPI0,
AT91C_SPI_MSTR |
AT91C_SPI_PS_FIXED |
AT91C_SPI_FDIV |
((unsigned int) 0x0 <<  2) |
AT91C_SPI_MODFDIS |
((unsigned int) 0x0 <<  7) |
AT91C_SPI_PCS |
((0x01 << 24) & AT91C_SPI_DLYBCS)
);
AT91C_BASE_SPI0->SPI_CR = AT91C_SPI_LASTXFER | AT91C_SPI_SPIEN;
AT91C_BASE_SPI0->SPI_TDR = AT91C_SPI_LASTXFER;
//Flash
AT91F_SPI_CfgCs(AT91C_BASE_SPI0,
0,
((unsigned int) 0x1 <<  0)   |
((unsigned int) 0x0 <<  1)   |
((unsigned int) 0x0 <<  3)   |
((unsigned int) 0x0 <<  4)   |
((unsigned int) 0x03 << 8)   |
((unsigned int) 0xC << 16)   |
((unsigned int) 0x2 << 24)
);
//ADC
AT91F_SPI_CfgCs(AT91C_BASE_SPI0,
1,//номер регистра
((unsigned int) 0x0 <<  0)   |
((unsigned int) 0x1 <<  1)   |
((unsigned int) 0x0 <<  3)   |
((unsigned int) 0x0 <<  4)   |
((unsigned int) 0x30< 8)   |
((unsigned int) 0x0 << 16)   |
((unsigned int) 0x0 << 24)
);
AT91F_PDC_EnableRx(AT91C_BASE_PDC_SPI0);
AT91F_PDC_EnableTx(AT91C_BASE_PDC_SPI0);
AT91F_PDC_Open(AT91C_BASE_PDC_SPI0);
}


Работаю например с АЦП, принимаю данные от него следующим образом

Код
AT91F_SPI_CfgPCS(AT91C_BASE_SPI0,0x0D);
AT91F_PDC_DisableRx(AT91C_BASE_PDC_SPI0);
AT91F_PDC_SetRx(AT91C_BASE_PDC_SPI0, 0 1);
AT91F_PDC_SetNextRx(AT91C_BASE_PDC_SPI0, adc_in, 3);

AT91F_PDC_DisableTx(AT91C_BASE_PDC_SPI0);
AT91F_PDC_SetTx(AT91C_BASE_PDC_SPI0,adc_send, 1);
AT91F_PDC_SetNextTx(AT91C_BASE_PDC_SPI0, 0, 2);

AT91F_PDC_EnableRx(AT91C_BASE_PDC_SPI0);
AT91F_PDC_EnableTx(AT91C_BASE_PDC_SPI0);
while(!(AT91C_BASE_SPI0->SPI_SR & AT91C_SPI_TXEMPTY));


Вобщем проблема такая: сначала работал с одним буфером приема и отправки. То есть отправлял три байта на ацп, где первый был командой на считывание данных, другие два незначащие, во время которых ацп возвращало мне данные. Но там интересная вещь была, данные лежали в буфере так - в третьем элементе буфера первый принятый, в нулевом второй принятый. Через день работы вобще стали возвращаться одни нули. Хотя осцилом смотрел - красивые и ПРАВИЛЬНЫЕ данные возвращаются, в строгом порядке. на самой ноге контроллера. Тогда сделал так. как показано выше.

Теперь у меня в нулевом элемнте буфера adc_in лежит постоянно всякая лабуда, зато далее мои нормальные данные ....

думал что изза этой строки так AT91F_PDC_SetNextTx(AT91C_BASE_PDC_SPI0, 0, 2);

вместо нулевого указателя поставил ненужную переменную. Также сделал и в AT91F_PDC_SetRx(AT91C_BASE_PDC_SPI0, 0 1);

ситуация не изменилась. Самое интересное, что при включении контроллера, я записываю регистры АЦП и их читаю, для проверки правильности записи, дак там нету такой фишки. Зато когда я нахожусь в обработке прерывания PIT и опрос веду там - есть ... Я так понимаю это изза того что нахожусь в прерывании у меня происходит сдвиг на один байт вправо?

Попробывал читать данные из флэш - таже лабуда: первый байт какая-то лабуда, а дальше идет нужная информация.

Что это может быть? и как с эим бороться? или не нужно и можно отсавить как есть? в надежде что так будет работать всегда и не глюканет потом где-нибудь ...

З.Ы. строка ожидания - потому что смотрел что принимается у меня ... smile.gif
AlexBoy
Попробуйте запускать прием и передачу в одной команде:
Код
pPDC->PDC_PTCR = AT91C_PDC_TXTEN | AT91C_PDC_RXTEN;


и ожидание по другому:
Код
mask = AT91C_SPI_ENDTX | AT91C_SPI_ENDRX;
do
   {
      status = pSPI->SPI_SR & mask;
      mask &= (~status);
    } while(mask);
Timofey
Увы .... не помогло .... 01.gif
Dron_Gus
Разбирайтесь с железом. Может АЦП нужен пустой цикл или пауза...
Timofey
В том то и дело что нет. АЦП ADS7871. Там шлется один байт команды на оцифровку с с указанием номера канала и коэфициентом усиления. после отправки этого байта команды. начиная со следующего такта АЦП возвращает предыдущее оцифрованное значение.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.