|
AT91SAM7X: SPI1 не корректно работает |
|
|
|
Nov 12 2011, 08:45
|

Местный
  
Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264

|
Доброго времени суток. Возникла проблема, связанная с организацией интерфейса SPI, ведущим устройством которого является микроконтроллер AT91SAM7X512. Дело в том, что все работает как надо - но, смотря осциллограмму, вижу, что в последний момент независимо от передаваемого функции SPI_Write() значения, линия MOSI устанавливается в уровень логической 1. В данном примере я передаю значение "0", но линия его передает - и сразу же в последний момент устанавливается в 1. Чего быть не должно. В чем еще может быть проблема, если вся инициализация верная, синхронизацию соответствующего периферийного устройства разрешил? Программа main.c: #include "AT91SAM7X256.h" #include <spi/spi.h> int main(void) { unsigned short data; AT91C_BASE_PMC->PMC_PCER = (1<<2); AT91C_BASE_PIOA->PIO_PPUDR = (1<<21) | (1<<22) | (1<<23) | (1<<24); AT91C_BASE_PIOA->PIO_PDR = (1<<21) | (1<<22) | (1<<23) | (1<<24); AT91C_BASE_PIOA->PIO_BSR = (1<<21) | (1<<22) | (1<<23) | (1<<24);
SPI_Configure(AT91C_BASE_SPI1, 5, 0xFF000011); SPI_ConfigureNPCS(AT91C_BASE_SPI1, 0, 0xFFFFFF02); SPI_Enable(AT91C_BASE_SPI1);
SPI_Write(AT91C_BASE_SPI1, 0, 0x00); data=SPI_Read(AT91C_BASE_SPI1);
while(1); } А содержимое spi.c (вырезал кусок): void SPI_Enable(AT91S_SPI *spi) { spi->SPI_CR = AT91C_SPI_SPIEN; }
//------------------------------------------------------------------------------ /// Disables a SPI peripheral. /// \param spi Pointer to an AT91S_SPI instance. //------------------------------------------------------------------------------ void SPI_Disable(AT91S_SPI *spi) { spi->SPI_CR = AT91C_SPI_SPIDIS; }
//------------------------------------------------------------------------------ /// Configures a SPI peripheral as specified. The configuration can be computed /// using several macros (see "SPI configuration macros") and the constants /// defined in LibV3 (AT91C_SPI_*). /// \param spi Pointer to an AT91S_SPI instance. /// \param id Peripheral ID of the SPI. /// \param configuration Value of the SPI configuration register. //------------------------------------------------------------------------------ void SPI_Configure(AT91S_SPI *spi, unsigned int id, unsigned int configuration) { AT91C_BASE_PMC->PMC_PCER = (1<<2) | (1<<id); spi->SPI_CR = AT91C_SPI_SPIDIS; // Execute a software reset of the SPI twice spi->SPI_CR = AT91C_SPI_SWRST; spi->SPI_CR = AT91C_SPI_SWRST; spi->SPI_MR = configuration; }
//------------------------------------------------------------------------------ /// Configures a chip select of a SPI peripheral. The chip select configuration /// is computed using the definition provided by the LibV3 (AT91C_SPI_*). /// \param spi Pointer to an AT91S_SPI instance. /// \param npcs Chip select to configure (1, 2, 3 or 4). /// \param configuration Desired chip select configuration. //------------------------------------------------------------------------------ void SPI_ConfigureNPCS(AT91S_SPI *spi, unsigned int npcs, unsigned int configuration) { spi->SPI_CSR[npcs] = configuration; }
//------------------------------------------------------------------------------ /// Sends data through a SPI peripheral. If the SPI is configured to use a fixed /// peripheral select, the npcs value is meaningless. Otherwise, it identifies /// the component which shall be addressed. /// \param spi Pointer to an AT91S_SPI instance. /// \param npcs Chip select of the component to address (1, 2, 3 or 4). /// \param data Word of data to send. //------------------------------------------------------------------------------ void SPI_Write(AT91S_SPI *spi, unsigned int npcs, unsigned short data) { // Discard contents of RDR register //volatile unsigned int discard = spi->SPI_RDR;
// Send data while ((spi->SPI_SR & AT91C_SPI_TXEMPTY) == 0); spi->SPI_TDR = data | SPI_PCS(npcs); while ((spi->SPI_SR & AT91C_SPI_TDRE) == 0); }
|
|
|
|
|
 |
Ответов
(1 - 8)
|
Nov 12 2011, 11:02
|

Местный
  
Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264

|
В общем, получить должен то, что указано в программе. Пишу сейчас инициализацию для SD карты памяти, но решил проверить верную работоспособность SPI. Как видно из программы, настроил линии ввода/вывода на управление встроенным периферийным устройством SPI1. Далее - настроил это периферийное устройство (скорость работы, режим работы и т.д.). Далее посредством вызова функции SPI_Write передаю данные, и, как видно - 0х00. Запрограммировал микроконтроллер, смотрю результат осциллографом и подключенными светодиодами (отладочная плата у меня это). Итак - отправка идет - пачка импульсов на линии SPCK прослеживается - 8 импульсов - как и предполагалось в регистре CSR0. Линия CS сбрасывается в уровень логического "0" при передаче. В это время на линии MOSI микроконтроллера происходит следующее: отправляется пачка импульсов, отправились 7 старших в передаваемом слове данных бит, сброшенных в уровень логического "0", но последний 8-й бит установился в 1 и таковым передался. Хотя в программе этого не предполагалось. Такое чувство, что микроконтроллер всегда отправляет 0х01.
К сожалению, не обратил внимания, 8-й ли бит передаваемого слова данных устанавливается в 1, или следующий, 9-й, просто ответил по памяти (не особо обратил внимание на последовательность, просто помню, что последним действием микроконтроллера стало установка линии MOSI в уровень логической "1"). Ближе к вечеру сообщу точно, что да как. Но надеюсь, что проблема будет понятна и в таком виде, в каком я преподнес ее Вам. Спасибо.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|