реклама на сайте
подробности

 
 
> AT91SAM7X: SPI1 не корректно работает
Arlleex
сообщение Nov 12 2011, 08:45
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 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);
}


Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Arlleex
сообщение Nov 12 2011, 11:02
Сообщение #2


Местный
***

Группа: Участник
Сообщений: 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"). Ближе к вечеру сообщу точно, что да как. Но надеюсь, что проблема будет понятна и в таком виде, в каком я преподнес ее Вам.
Спасибо.
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th July 2025 - 14:37
Рейтинг@Mail.ru


Страница сгенерированна за 0.01377 секунд с 7
ELECTRONIX ©2004-2016