Перейти к содержанию
    

SPI Slave ошибки чтения, помогите разобраться

Имеем поток 16-ти битных слова от мастера:

post-65341-1313496423_thumb.png

3.3v TTL. Клок 1.25Мгц. Слова идут непрерывно, паузы между пакетами в 1Tc.

Непрерывно весь поток читать не нужно, только переодически отслеживать изменение значения слова.

 

Пытаюсь отладить чтение в SPI-slave режиме на Atmega328p (платка arduino nano v3), 5В питалово. Т.к slave ничего не пердаёт, подключен напрямую без шифтера 3.3-5в.

 

В итоге, всё читается, но где-то один из 200-300 пакетов в среднем, читается неправильно.

Все тайминги по даташиту проходят с запасом.

 

В основном путается порядок байт в слове, но иногда неверно читаются и сами байты.

Прогнал на логанализаторе с длинной памятью c порогами для 5v TTL - никаких ошибок в передаче нет.

Пробовал читать с прерываним по SS и просто в цикле с предварительным опросом ноги SS, без разницы.

В итоге упростил код до:

  
  while (!(PINB & 0x4) ); // wait until SlaveSelect goes High
  while(!(SPSR & (1<<SPIF))); // SPIF bit set when 8 bits received
  w.c[0] = SPDR;               
  while(!(SPSR & (1<<SPIF))); // SPIF bit set when 8 bits received
  w.c[1] = SPDR;

никаких прерываний, только чтение и вывод на serial. Всё по прежнему.

 

Но, если вставить задержку порядка 1мс в основном цикле до или после вышеприведённого кода, то ошибки чтения пропадают полностью. Оставлял на час, ни одной ошибки. Если менять задержку как в большую, так и в меньшую сторону, ошибки снова возникают с разной частотой в зависимости от задержки.

Изменено пользователем DEHiCKA

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Но, если вставить задержку порядка 1мс в основном цикле до или после вышеприведённого кода

 

Так может приведёте код полный и инит SPI

Во, вспомнил - у Вас timeout после установки SS в (0) выдерживается? А то в коде этого нет, может просто посадить в zero и проверить

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Добрый день, не создаю новую тему, так как проблема похожа.

Ловлю SPI-Slave-устройством 3 байта.

каждый по прерыванию сохраняю.

и, каким-то образом, 2 и 3 байт оказываются одинаковыми, хотя при передаче их на осциллографе вижу, что

данные поступают разные.

подскажите в чем может быть проблема? куда думать

 

#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
volatile char IOReg;

unsigned char command, f_m, f_l; // три байта комманды

char count = 0;  // счётчик байтов комманды
unsigned char ind[4]; // массив под входящие данные

long f;

int main(void)
{
	ind[2] = 0;	
	volatile char IOReg;
	DDRB	= (1 << PB6)|(1 << PB3 ); // MISO & LED
	PORTB = 255; // тут у меня светодиод висит
	// Enable SPI Interrupt and SPI in Slave Mode with SCK = CK/4
	SPCR  = (1<<SPIE)|(1<<SPE);
	IOReg   = SPSR;						 // Clear SPIF bit in SPSR
	IOReg   = SPDR;
	SPDR = 0b01010101; // произвольный байт для отправки
	sei();	   

while(1)
{
	if (count == 3) // после того, как прошли 3 байта
	{

		 if (ind[2] == ind[3]){PORTB = 0;} // выключаю светодиод, когда регистры равны
	};	

	IOReg = SPDR;

}

return 0;
}

ISR(SPISTC_vect)
{
count++;

ind[count] = SPDR;

return;
}

Изменено пользователем IgorKossak
[codebox]

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вы бы подробнее описали что Вы хотите получить, а то из кода ничего не понятно.

К самой программе хоть она и короткая есть много претензий:

1. зачем 2 раза объявлена IOReg? И зачем она volatile?

2. А вот count как раз должна быть volatile, раз она меняется в прерывании.

3. Зачем ind[4], если у Вас 3 байта на прием? Наверное, потому что Вы в прерывании инкрементируете count перед тем как сделать запись в массив?

4. Зачем обнуляете ind[2]? Смысла в этом не вижу, надо либо весь массив обнулять, либо вообще ничего не обнулять.

5. Почему count никогда не обнуляете, или ждете только одного прохода программы?

6. Почему читаете SPDR и в основном цикле, и в прерывании?

 

Не слишком ли много вопросов для программы из 20 строк? В этом разделе есть прикрепленная тема "Исходники программ и бибилиотек" Там есть несколько реализаций работы с SPI, да и на сайте Атмела есть апноуты про это. Почитайте.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1. IOReg был как раз из одного из примеров, там было volatile.

2. ___

3. массив 3 или 4 - не имеет смысла. просто индексы не с нуля начинаются.

4. обнулял принудительно второй элемент массива ind[2], потому что именно с ним проблемы - первый и третий приходят корректно.

5. Да, пока один проход программы, чтобы понять куда теряется второй байт

6. в основном цикле, я думаю, эта строка никому не мешает

 

да, вы правы, претензий от вас много :) и ни одного предположения в чем ошибка

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Информацию клещами из Вас вытягивать приходится. Значит первый и третий приходят правильно, а второй пропадает? А из Вашего описания проблемы это не следует. Я первым предложением попросил подробно описать что Вы хотите сделать и как Вы это делаете. Уверен на 90%, что когда Вы это опишете, то проблема будет решена Вами самостоятельно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

не надо клещами :) написал коротко - думал будет понятно. пробую развернуть!

от некого Мастера передаю на свой слэйв 3 байта подряд, зная чётко их значения, видя их на осциллографе.

в приведенной выше программе слэйва отлавливаю эти 3 байта, заношу в массив ind[].

и на моё удивление, значение второго реального байта нигде не отслеживается.

то есть в массиве ind 2 и 3 ячейки содержат одинаковое значение 3-го реально переданного байта.

мне кажется, достаточно подробно

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...