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

 
 
 
Reply to this topicStart new topic
> 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
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
Budek
сообщение Oct 11 2010, 08:39
Сообщение #4


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

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



Спасибо! Буду думать, как лучше поступить....
Новые предложения приветствуются. Надеюсь, это интересно не только мне...
Go to the top of the page
 
+Quote Post
rezident
сообщение Oct 11 2010, 16:20
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(Budek @ Oct 11 2010, 14:39) *
Буду думать, как лучше поступить....
"Как поступить" зависит от того, может ли вызывающая функция "подождать" когда порт освободится или она должна отправить поток данных немедленно, без ожидания? Если функция "согласна" подождать, то можно и без доп. буфера обойтись . Но признак занятости порта нужно реализовать в любом случае.
Go to the top of the page
 
+Quote Post

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

 


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


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