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

 
 
> Работа с обоими USART в ATMega64, подскажите пожалуйста с логикой
UniBomb
сообщение May 21 2009, 07:32
Сообщение #1


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

Группа: Свой
Сообщений: 148
Регистрация: 26-05-05
Пользователь №: 5 416



Добрый день. У меня есть девайс на 64-ой меге, в которой задействованы оба усарта. Реализован протокол ModBus RTU (самолично).

По описанию протокола все посылки данных начинаются и оканчиваются интервалом времени, равное времени приёма 3,5 символов. Не мудрствуя лукаво я реализовал это условие в лоб - при приёме первого символа мк уходит в прерывание и не выходит из него до тех пор, пока не примет всю посылку. До недавнего времени использовался только один усарт и всё было хорошо. Но вот буквально вчера возникла необходимость использования и второго усарта. Естетсвенно вышеописанный подход неверен, т.к. из-за большой частоты посыла запроса и соответсвенно получения ответа два прерывания по приёму данных мешают друг другу. Т.е. если в данный момент уже идёт приём данных по первому усарту и в это время начали приходить данные на второй усарт, то часть посылки со второго усарта просто теряется. Такого быть недолжно.... Сократил об прерывания до самого минимума:

Код
uint8_t data_recv0[128];
uint8_t cur_data_recv0;
/*...*/
ISR(SIG_UART0_RECV)
{
  data_recv1[cur_usart1_recv] = UDR0;
  cur_data_recv++;
}


Но я никак немогу сообразить, как же в этом случае вести отсчёт времени, как отделять посылки друг от друга и вообще как определить конец посылки. Пробовал через таймер, но что то невыходит. Получается либо слишком большой промежуток времени, либо приходится делать период срабаотывания таймера настолько маленьким, что одна посылка разбивается на несколько.


Какие ещё есть решения? Кто как обходил эту ситуацию?

Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
MrYuran
сообщение May 21 2009, 07:48
Сообщение #2


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(UniBomb @ May 21 2009, 11:32) *
По описанию протокола все посылки данных начинаются и оканчиваются интервалом времени, равное времени приёма 3,5 символов. Не мудрствуя лукаво я реализовал это условие в лоб - при приёме первого символа мк уходит в прерывание и не выходит из него до тех пор, пока не примет всю посылку.

Посмотрите реализацию FreeModbus.(berlios.de)
По прерыванию от УАРТа байт просто кидается в буфер и обнуляется таймер таймаута (предварительно настроенный на 3,5 символа)
А вот по прерыванию таймера уже запускается первичная разборка пакета - CRC, адрес и т.д.
И вот если всё нормально (адрес соответствует, CRC в норме и т.д.), тогда выставляется флаг принятого пакета и функция ModPoll() в основном потоке анализирует пакет, запускает колбэк-функции и формирует ответ.

И вообще: ждать чего-то в прерывании - это не просто дурной тон, а ламерство в чистом виде.
В прерывании нужно делать самые неотложные вещи и выскакивать как можно скорее.


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post



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

 


RSS Текстовая версия Сейчас: 21st July 2025 - 17:11
Рейтинг@Mail.ru


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