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

 
 
> Не работает SPI
yshur
сообщение Jan 20 2007, 13:29
Сообщение #1





Группа: Новичок
Сообщений: 2
Регистрация: 20-01-07
Пользователь №: 24 624



Используем ARM AT91M42800 и АЦП с SPI интерфейсом.
Драйвер для чтение АЦП отказывается работать, если поместить чтение АЦП в прерывание от таймера (на ножках SPI ничего нет).
Вне прерывания драйвер работает нормально.

В чем может быть проблема?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
AlexBoy
сообщение Jan 21 2007, 16:07
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 205
Регистрация: 19-12-05
Из: Kiev
Пользователь №: 12 394



Цитата(yshur @ Jan 20 2007, 12:29) *
Используем ARM AT91M42800 и АЦП с SPI интерфейсом.
Драйвер для чтение АЦП отказывается работать, если поместить чтение АЦП в прерывание от таймера (на ножках SPI ничего нет).
Вне прерывания драйвер работает нормально.

В чем может быть проблема?


Проверьте вызывается ли вообще это прерывание (помигать светодиодом), и если вызывается то может слишком часто, не успевает пройти предыдущий байт, смотрю сейчас стоит делитель скорости 10. И еще у меня проверки немного в другом порядке, попробуйте так:

//----------------------------------------------------------------------------
BYTE AT91F_ByteSPI(int channel, BYTE data)
{
AT91PS_SPI pSPI = SpiChannels[channel].spi_base;
while(!(pSPI->SPI_SR & AT91C_SPI_TDRE)); // ожидание пока буфер передачи не пустой
pSPI->SPI_TDR = data; // запись в регистр передачи
while(!(pSPI->SPI_SR & AT91C_SPI_RDRF)); // ожидание пока буфер приема пустой
data = pSPI->SPI_RDR; // чтение из регистра приема
return data;
}
Go to the top of the page
 
+Quote Post
andrvisht
сообщение Apr 17 2007, 15:24
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 298
Регистрация: 29-08-05
Пользователь №: 8 064



Поскольку АРМ только начал изучать решил попробовать Keil 3.51
Задача состоит в работе SPI на LPC2294. За основу был взят пример из книги Тревора Мартина слегка переделанный под задачу.
делаем инициализацию:
Код
  PINSEL1 = 0x000002A8;        //Enable SPI1 pins
  IODIR1     =    0x00000000;        //Enable Chipselect pin as output
  VICVectCntl0 = 0x0000002B;          //Select a priority slot for a given interrupt (A - interrupt SPI0)
  VICVectAddr0 = (unsigned)SPI_ISR;    //Pass the address of the IRQ into the VIC slot
  VICIntEnable = 0x00000800;            //Enable interrupt SPI1

Функция записи данных контроллером
Код
void TxSPI(unsigned char *pData, unsigned char SPICount)
{
  unsigned char i;
  CountTxSPI = SPICount; // загрузка счетчика переданных байт
  for(i = SPICount; i > 0;) // перегрузка данных в буфер SPI
  {
    BufSPI[--i] = *pData++;
  }
  pSPI = &BufSPI[SPICount-1]; // указатель на начало передачи
  S1SPCCR = 0xFF;
  S1SPCR = (1<<SPIE)|(1<<MSTR)|(0<<CPOL)|(0<<CPHA);
  S1SPDR = *pSPI;
}

и собственно обработка прерывания
Код
void SPI_ISR(void) __irq
{
  *pSPI = S1SPDR; // чтение данных в буфер
  if (CountTxSPI > 1)
  {
    S1SPDR = *(--pSPI);
    CountTxSPI--;
  }
  else
  {
    CountTxSPI = 0;
    PCONP &= ~(1<<PCSPI1); // выключение SPI
  }
  S1SPINT =    0x01;
  VICVectAddr = 0x00000000;
  return;
}

И вот получается что в симуляции все нормально, а в реальном железе прерывание срабатывает только 1 раз.
Пример из которого переделывалось ведет себя аналогично. PLL не использую, кварц 14.7456MHz
Видимо симулятор что то не договаривает, но вот что ?
Go to the top of the page
 
+Quote Post



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

 


RSS Текстовая версия Сейчас: 11th August 2025 - 16:26
Рейтинг@Mail.ru


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