Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: spi mega - мастер, 2 ведомых. есть больной вопрос
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Budek
Здравствуйте!
Столкнулся с проблемой. Есть мега и 2 ведомых (акселерометр и трансивер). Все сидят на одной шине spi.
CS1 - выбор первого, CS2 - выбор второго ведомого.
Функция передачи/приема байта:
unsigned char send_byte_spi (unsigned char byte) { SPDR=byte; while ((SPSR&(1<<7))==0x00) return SPDR; }
Отпрака байта первому: CS1=0; send_byte_spi(0x00); CS1=1; второму: CS2=0; send_byte_spi(0x00); CS2=1;
Все хорошо до того момента, пока не приходится отправлять/принимать байты одному из них (для примера-первому) еще и в прерывании (например прерывании таймера). Что получается: идет "общение" со вторым (CS2=0) и тут возникает прерывание (выбираем CS1=0). В результате - на шине оказываются сразу 2 ведомых - последствия гарантированно плачевные. Можно, конечно, функции отправки привести к виду:
Отпрака байта первому: CS2=1; CS1=0; send_byte_spi(0x00); CS1=1; второму: CS1=1; CS2=0; send_byte_spi(0x00); CS2=1;
но в этом случае прервется "общение" со вторым ведомым (во время передачи ему байта выставляем ему CS2=1;) что тоже не есть хорошо (из опыта общения с флешем помню, что прерывание "диалога" довольно часто приводит к зависанию флеша и необходимостью ее последующего ресета).
Еще думал перед каждым вызовом функции send_byte_spi из "тела программы" запрещать, а потом разрешать прерывания... Но это вообще бред.
Посоветуйте что нибудь... Спасибо.

mempfis_
Введите переменную статуса spi. Пусть она принимает значения 0, 1, 2. 0 - spi не занят, 1 - доступ к устройству 1, 2 - доступ к устройству 2.
В цикле или прерываниях проверяете. Если spi свободен и нужно обратится к одному из устройств - выставляете соотв статус spi и выполняете обращение. По завершению освобождаете spi. Если нужно обратится а spi занят (как у Вас бывает в прерывании) то выставляете флаг что необходимо выполнить обращение к такому-то устройству (если устройства 2 то и флагов будет 2) и далее в основном цикле организовывайте дополнительный опрос этих флагов чтобы выполнить обращение к устройствам в порядке приоритета. Это простейший (наверное) вариант smile.gif

У меня для подобных случаев организовывается задача доступа к определённой переферии (например usart). Остальные задачи которые хотят получить доступ к переферии выставляют запрос на доступ. Задача доступа анализирует флаги запроса и в текущий момент времени все потоки данных переадресуются только этой задаче.
777777
Цитата(mempfis_ @ Oct 11 2010, 11:22) *
Введите переменную статуса spi. Пусть она принимает значения 0, 1, 2. 0 - spi не занят, 1 - доступ к устройству 1, 2 - доступ к устройству 2.
В цикле или прерываниях проверяете.

Правда здесь есть некоторые проблемы:
а) перед проверкой статуса нужно запретить прерывания, а после его установки - разрешить, иначе можно попасть в прерывание между проверкой статуса и его установкой.
б) если это выполняется из какого-то прерывания, то можно в нем зависнуть надолго ожидая освобождения SPI, а в прерываниях надолго зависать не рекомендуется.

Поэтому я предпочитаю для таких случаев кольцевой буфер.
Budek
Спасибо! Буду думать, как лучше поступить....
Новые предложения приветствуются. Надеюсь, это интересно не только мне...
rezident
Цитата(Budek @ Oct 11 2010, 14:39) *
Буду думать, как лучше поступить....
"Как поступить" зависит от того, может ли вызывающая функция "подождать" когда порт освободится или она должна отправить поток данных немедленно, без ожидания? Если функция "согласна" подождать, то можно и без доп. буфера обойтись . Но признак занятости порта нужно реализовать в любом случае.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.