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

 
 
> spi mega - мастер, 2 ведомых. есть больной вопрос
Budek
сообщение Oct 11 2010, 06:59
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 132
Регистрация: 17-02-08
Из: Уфа
Пользователь №: 35 116



Здравствуйте!
Столкнулся с проблемой. Есть мега и 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 из "тела программы" запрещать, а потом разрешать прерывания... Но это вообще бред.
Посоветуйте что нибудь... Спасибо.

Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
mempfis_
сообщение Oct 11 2010, 07:22
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409



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

У меня для подобных случаев организовывается задача доступа к определённой переферии (например usart). Остальные задачи которые хотят получить доступ к переферии выставляют запрос на доступ. Задача доступа анализирует флаги запроса и в текущий момент времени все потоки данных переадресуются только этой задаче.
Go to the top of the page
 
+Quote Post
777777
сообщение Oct 11 2010, 07:47
Сообщение #3


Профессионал
*****

Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357



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

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

Поэтому я предпочитаю для таких случаев кольцевой буфер.
Go to the top of the page
 
+Quote Post



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

 


RSS Текстовая версия Сейчас: 24th June 2025 - 17:32
Рейтинг@Mail.ru


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