DEHiCKA 0 16 августа, 2011 Опубликовано 16 августа, 2011 (изменено) · Жалоба Имеем поток 16-ти битных слова от мастера: 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мс в основном цикле до или после вышеприведённого кода, то ошибки чтения пропадают полностью. Оставлял на час, ни одной ошибки. Если менять задержку как в большую, так и в меньшую сторону, ошибки снова возникают с разной частотой в зависимости от задержки. Изменено 16 августа, 2011 пользователем DEHiCKA Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ILYAUL 0 17 августа, 2011 Опубликовано 17 августа, 2011 · Жалоба Но, если вставить задержку порядка 1мс в основном цикле до или после вышеприведённого кода Так может приведёте код полный и инит SPI Во, вспомнил - у Вас timeout после установки SS в (0) выдерживается? А то в коде этого нет, может просто посадить в zero и проверить Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alex_hyp 0 2 марта, 2012 Опубликовано 2 марта, 2012 (изменено) · Жалоба Добрый день, не создаю новую тему, так как проблема похожа. Ловлю 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; } Изменено 2 марта, 2012 пользователем IgorKossak [codebox] Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GDI 0 2 марта, 2012 Опубликовано 2 марта, 2012 · Жалоба Вы бы подробнее описали что Вы хотите получить, а то из кода ничего не понятно. К самой программе хоть она и короткая есть много претензий: 1. зачем 2 раза объявлена IOReg? И зачем она volatile? 2. А вот count как раз должна быть volatile, раз она меняется в прерывании. 3. Зачем ind[4], если у Вас 3 байта на прием? Наверное, потому что Вы в прерывании инкрементируете count перед тем как сделать запись в массив? 4. Зачем обнуляете ind[2]? Смысла в этом не вижу, надо либо весь массив обнулять, либо вообще ничего не обнулять. 5. Почему count никогда не обнуляете, или ждете только одного прохода программы? 6. Почему читаете SPDR и в основном цикле, и в прерывании? Не слишком ли много вопросов для программы из 20 строк? В этом разделе есть прикрепленная тема "Исходники программ и бибилиотек" Там есть несколько реализаций работы с SPI, да и на сайте Атмела есть апноуты про это. Почитайте. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alex_hyp 0 2 марта, 2012 Опубликовано 2 марта, 2012 · Жалоба 1. IOReg был как раз из одного из примеров, там было volatile. 2. ___ 3. массив 3 или 4 - не имеет смысла. просто индексы не с нуля начинаются. 4. обнулял принудительно второй элемент массива ind[2], потому что именно с ним проблемы - первый и третий приходят корректно. 5. Да, пока один проход программы, чтобы понять куда теряется второй байт 6. в основном цикле, я думаю, эта строка никому не мешает да, вы правы, претензий от вас много :) и ни одного предположения в чем ошибка Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GDI 0 2 марта, 2012 Опубликовано 2 марта, 2012 · Жалоба Информацию клещами из Вас вытягивать приходится. Значит первый и третий приходят правильно, а второй пропадает? А из Вашего описания проблемы это не следует. Я первым предложением попросил подробно описать что Вы хотите сделать и как Вы это делаете. Уверен на 90%, что когда Вы это опишете, то проблема будет решена Вами самостоятельно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alex_hyp 0 2 марта, 2012 Опубликовано 2 марта, 2012 · Жалоба не надо клещами :) написал коротко - думал будет понятно. пробую развернуть! от некого Мастера передаю на свой слэйв 3 байта подряд, зная чётко их значения, видя их на осциллографе. в приведенной выше программе слэйва отлавливаю эти 3 байта, заношу в массив ind[]. и на моё удивление, значение второго реального байта нигде не отслеживается. то есть в массиве ind 2 и 3 ячейки содержат одинаковое значение 3-го реально переданного байта. мне кажется, достаточно подробно Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться