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

 
 
> Не работает 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
Сергей Борщ
сообщение Apr 17 2007, 15:54
Сообщение #4


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(&-rey @ Apr 17 2007, 14:24) *
делаем инициализацию:
У вас ведь дальше очень красиво написано:
Код
S1SPCR = (1<<SPIE)|(1<<MSTR)|(0<<CPOL)|(0<<CPHA);
Почему же вы тут пишете страшные шестнадцатиричные числа? Ведь можно голову сломать переводя их в биты
Код
  PINSEL1 = (2UL<<8) | (2UL<<6)|(2UL<<4)|(2UL<<2);        //Enable SPI1 pins
  VICVectCntl0 = (1<<VIC_SPI1) | (1<<5);          //Select a priority slot for a given interrupt (A - interrupt SPI1)
  VICVectAddr0 = (unsigned)SPI_ISR;    //Pass the address of the IRQ into the VIC slot
  VICIntEnable = (1UL<<VIC_SPI1);            //Enable interrupt SPI1

Цитата(&-rey @ Apr 17 2007, 14:24) *
и собственно обработка прерывания

1) Вы выключаете питание SPI после передачи (PCONP &= ~(1<<PCSPI1); ) а включения его обратно перед началом передачи я не вижу.
2) У вас нога SSEL настроена на ввод и подтянута снаружи к единице?


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
andrvisht
сообщение Apr 17 2007, 16:26
Сообщение #5


Местный
***

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



Цитата(Сергей Борщ @ Apr 17 2007, 15:54) *
Почему же вы тут пишете страшные шестнадцатиричные числа? Ведь можно голову сломать переводя их в биты

Потому что Keil. Разработчики поленились и описали только регистры, на описание битов сил у них не хватило sad.gif Другое дело IAR, там все по человечески сделано, но решил опробовать Keil ввиду возможности симулить переферию. До нормального описания битов через #define пока не дошли руки.
Цитата
1) Вы выключаете питание SPI после передачи (PCONP &= ~(1<<PCSPI1); ) а включения его обратно перед началом передачи я не вижу.
2) У вас нога SSEL настроена на ввод и подтянута снаружи к единице?


да, это недосмотр. Просто в TXSPI были строки выключения SPI вначале и включение в конце, а потом я их устранил чтобы не захломлять код, удалил и эту строку из прерывания, а также настроил SSEL на вывод IODIR0 |= 1<<20;
Результат тот же, прерывание срабатывает только 1 раз. По косвенным признакам нога SCK1 (P0.17) в Z. Если посмотреть в отладке на PINSEL0 то там все в порядке, т.е. видно что к ногам прицеплен SPI1.
Go to the top of the page
 
+Quote Post



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

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 18:07
Рейтинг@Mail.ru


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