![]() |
Модераторы: PILOT, ManiaK, Mazzi |
![]() ![]() ![]() |
|
EngineerOfHell |
|
|||
Новичок Профиль Группа: Участник Сообщений: 4 Регистрация: 24.6.2008 Репутация: нет Всего: нет |
Я использую USI в трехпроводном режиме для связи Atmel tiny2313 и mega16 (мастер). Все бы хорошо, 24 байта успешно передаются, но потом программа tiny2313 зависает. Исследования с использованием отладочного порта USART показывают, что программа в 25-й раз заходит в прерывание Start Condition Interrupt и пытается получить 25-й байт. Что я делаю не так?
Программа написана на ассемблере. Код, реализующий Start Condition Interrupt на ATtiny2313
|
|||
|
||||
Mazzi |
|
|||
![]() Правильный ![]() ![]() Профиль Группа: Комодератор Сообщений: 825 Регистрация: 3.4.2003 Репутация: 9 Всего: 21 |
Я советую тебе убрать бесконечный цикл в обработчике прерывания, потому, что это "мина замедленного действия" в твоей программе.
Обработчик прерывания должен быть короткий, как выстрел. Лично я делаю так: при попадании в прерывание проверяю флаги для того, чтобы узнать чем вызвано прерывание, затем если нужно копирую данные(на вход или выход) выставляю флажки для основной программы и покидаю обработчик прерывания. Удачи! -------------------- Мне нужны помощники. |
|||
|
||||
EngineerOfHell |
|
|||
Новичок Профиль Группа: Участник Сообщений: 4 Регистрация: 24.6.2008 Репутация: нет Всего: нет |
Спасибо за ответ!
Использование бесконечного цикла - не моя прихоть, так работает SPI в ATtiny2313. Данная функция вызывается по вектору прерывания Start Condition (это начало передачи), а бесконечный цикл будет выполняться ровно до того момента, как переполнится счетчик принятых байт. Кстати, собственно код этого цикла взят из даташита на микроконтроллер. То есть, понятно, что программа виснет именно в этом цикле. Но она не должна просто в него попадать лишний раз! Это знак того, что я где-то допустил ошибку. Если цикл убрать и заменить, скажем, прерыванием Overflow, ошибка не исчезнет :( Может быть, у кого-нибудь есть пример работы с SPI в режиме трех проводов на ассемблере? Самый простой, главное, чтобы рабочий ![]() |
|||
|
||||
Mazzi |
|
|||
![]() Правильный ![]() ![]() Профиль Группа: Комодератор Сообщений: 825 Регистрация: 3.4.2003 Репутация: 9 Всего: 21 |
Я пишу на СИ.
По поводу бесконечного цикла. Добавь в этот цикл например увеличение счётчика, и если он переполнился, то следует покинуть этот злосчастный цикл. Это устранит зависание контроллера в ситуации когда твоё условие никогда не выполнится. По поводу 25-го входа в обработчик прерывания. Учитываешь ли ты то обстоятельство, что прерывание возникает как по приёму, так и по окончании передачи? -------------------- Мне нужны помощники. |
|||
|
||||
Den64 |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 210 Регистрация: 6.4.2006 Где: Курск Репутация: 1 Всего: 2 |
А может мастер чего лишнего посылает?
--------------------
Инагда пишу звуками. |
|||
|
||||
Mazzi |
|
|||
![]() Правильный ![]() ![]() Профиль Группа: Комодератор Сообщений: 825 Регистрация: 3.4.2003 Репутация: 9 Всего: 21 |
Мастер может лишнего послать, только если выбрана неправильная конфигурация, а здесь, похоже, человек без мастеров на чистом АСМе пишет.
-------------------- Мне нужны помощники. |
|||
|
||||
Den64 |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 210 Регистрация: 6.4.2006 Где: Курск Репутация: 1 Всего: 2 |
Я про mega16..
--------------------
Инагда пишу звуками. |
|||
|
||||
Mazzi |
|
|||
![]() Правильный ![]() ![]() Профиль Группа: Комодератор Сообщений: 825 Регистрация: 3.4.2003 Репутация: 9 Всего: 21 |
Я неправильно понял об мастере, извиняюсь.
Вообще для корректного обмена нужно использовать какой-нибудь протокол. Во входной последовательности ищется стартовый байт, затем тело посылки, затем контрольная сумма и стоповый байт. Кроме того использовать тайм-ауты. Тогда все эти проблемы исчезают. -------------------- Мне нужны помощники. |
|||
|
||||
EngineerOfHell |
|
|||
Новичок Профиль Группа: Участник Сообщений: 4 Регистрация: 24.6.2008 Репутация: нет Всего: нет |
Mazzi, На контроллерах этой серии прерывания по началу и по окончанию вызываются разными векторами.
Den64, Я проверил программу на mega16, никаких отклонений не нашел. Вот как раз прямо сейчас сижу и пытаюсь сделать что-то вроде тайм-аутов. Хорошая мысль, спасибо ![]() |
|||
|
||||
Mazzi |
|
|||
![]() Правильный ![]() ![]() Профиль Группа: Комодератор Сообщений: 825 Регистрация: 3.4.2003 Репутация: 9 Всего: 21 |
На самом деле,только не обижайся пожалуйста, мой вариант лучшее решение. Твой вариант больше похож на обход проблемы.
Спросишь, почему? Потому что я предлагаю стандартный подход. Найди какую нибудь книжку где описаны разные протоколы и почитай, я думаю найдёшь много интересного. Желаю удачи! -------------------- Мне нужны помощники. |
|||
|
||||
EngineerOfHell |
|
|||
Новичок Профиль Группа: Участник Сообщений: 4 Регистрация: 24.6.2008 Репутация: нет Всего: нет |
Mazzi, Погоди, не пропадай. Какими свойствами должен обладать протокол? Просто кратко, по пунктам, укажи их. Что-то вроде такого:
1) Тайм-ауты в прерываниях/разные прерывания для начала и конца передачи байта. 2) .....что-то еще... Потому что я сейчас действительно обошел проблему. Зная, что посылка фиксирована по длине, я просто выхожу из прерывания еще до начала цикла, когда вся посылка принята. Таким образом обработка успешно идет своим чередом, и схема работает. Но окончательного понимания источника проблемы все равно нет. |
|||
|
||||
Mazzi |
|
|||
![]() Правильный ![]() ![]() Профиль Группа: Комодератор Сообщений: 825 Регистрация: 3.4.2003 Репутация: 9 Всего: 21 |
Лучше всего взять какой-нибудь готовый протокол. Проще всего сделать свой, простой.
Протокол предусматривает обмен между по крайней мере двумя устройствами. Для простого обмена одно устройство управляет обменом, остальные выполняют запросы. Ведомое устройство всё время "слушает" поток в канале обмена и отвечает только если распознаёт команду направленную непосредственно ему. В просом случае для распознавания начала и конца посылки используются специальные символы которые не могут использоваться для передачи данных. В конце посылки добавляется контрольная сумма помогающая детектировать ошибку во время передачи. Для реализации неподвисающих программ следует поступать примерно так: Получив символ начала посылки "взводить" таймер, по получении каждого очередного байта перевзводить его, получив символ окончания посылки сбросить таймер. Если поток данных прервался, то это определяется по сработке таймера. Это и есть тайм-аут. Получив очередной байт, мы помещаем его в буфер и продолжаем основную работу. Получив завершающий символ, мы начинаем обрабатывать полученную посылку. Удачи! -------------------- Мне нужны помощники. |
|||
|
||||
Masyanya |
|
||||
Новичок Профиль Группа: Участник Сообщений: 5 Регистрация: 30.6.2008 Репутация: нет Всего: нет |
Это в дебагере или на собранном устройстве повисает?
Вот такое простое и забавное:
![]() Если посмотреть на даташит, то видим вот что:
По сему мне искренне интересно зачем вот это: ldi r20,(1<<USIOIF)+(1<<USISIF) Ты "путаешь" контроллер, говоря ему что снова пришло начало пакета? Такое внутри прерывания ATMEL делать не рекомендует. Плюс ок всему если у тебя это происходит на "живом" устройстве, то 100% это что то шумит в линии SCL,SDA (подтянуть надо соответствующие выводы к VCC (+)). Это сообщение отредактировал(а) Masyanya - 1.7.2008, 14:14 |
||||
|
|||||
![]() ![]() ![]() |
Правила форума "Микроконтроллеры (MCU) и микропроцессоры (MPU)" | |
|
На данный раздел помимо Правил форума распространяются текже следующие правила:
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, PILOT, ManiaK, UniBomb, Mazzi. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Микроконтроллеры (MCU) и микропроцессоры (MPU) | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |