Athlon128 0 24 октября, 2007 Опубликовано 24 октября, 2007 · Жалоба По RS485 объединены мастер и несколько слейвов (все на mega128) мастер с интервалом в 100мс шлёт команду вида: префикс ":", байт - номер команды, байт - id слейва, 2 байта - аргументы для команды, постфикс ";". 1 из слейвов должен ответить что он подключен. Вот фрагмент кода слейва (codevisionAVR): while (1) { delay_ms(50); command=0; number=0; while (getchar() != ':'); command=getchar(); number=getchar(); if ((command==1)&&(number==id)) { PORTE.7=1; printf(":%d online;",id); PORTE.7=0; } // delay_ms(50); }; } на деле отвечает только 1 раз первый запрошенный слейв. что я делаю неправильно подскажите плз поигрался интервалом отправки команд с мастера, начали отвечать несколько слейвов :) proteus_prj.rar Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DASM 0 24 октября, 2007 Опубликовано 24 октября, 2007 · Жалоба Не понял - это симулятор ? А где код вкл-выключения 485 драйвера на передачу ? И что-то не нравится мне идея готовность выдавать в виде : :%d online . В данном случае девайсы услышат этот отклик, но команда будет равна 32 (код пробела) но зачем их напрягать то... Какая скорость 485 ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Athlon128 0 24 октября, 2007 Опубликовано 24 октября, 2007 · Жалоба код вкл-выключения 485 драйвера на передачу PORTE.7=1; ....//передача PORTE.7=0; Теперь у меня вопрос: как правильнее синхронизировать передачу команды и ссчитывание из буфера слейвом. Если ставлю интервал отправки мастером меньше чем интервал ссчитывания из буфера слейвом, то всё работает до переполнения буфера слейва. Сейчас попробую синхронизировать их таймером. А как выходили из положения вы? Сорри за сумбур :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DASM 0 24 октября, 2007 Опубликовано 24 октября, 2007 · Жалоба Ничего не понял. Какого буфера переполнение ? Зачем кстати 50 мс задержка в цикле ? PS после включения драйвера на передачу задржку надо бы на устаканивание переходных процессов в линии Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Палыч 9 24 октября, 2007 Опубликовано 24 октября, 2007 · Жалоба ИМХО, слэйв отвечает на команду мастера не дождавшись окончания передачи мастера: передача слэйва начинается. когда получен id слэйва, но мастер еще передаёт 3 байта (аргументы и постфикс) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DASM 0 24 октября, 2007 Опубликовано 24 октября, 2007 · Жалоба Точно :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alexander55 0 24 октября, 2007 Опубликовано 24 октября, 2007 · Жалоба ИМХО, слэйв отвечает на команду мастера не дождавшись окончания передачи мастера: передача слэйва начинается. когда получен id слэйва, но мастер еще передаёт 3 байта (аргументы и постфикс) Это самая главная проблема при работе с RS485 для мастера. ЕЕ надо решать корректно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Athlon128 0 24 октября, 2007 Опубликовано 24 октября, 2007 (изменено) · Жалоба ИМХО, слэйв отвечает на команду мастера не дождавшись окончания передачи мастера: передача слэйва начинается. когда получен id слэйва, но мастер еще передаёт 3 байта (аргументы и постфикс) Вы правы. Поставил задержку перед ответом, все слейвы отвечают нормально Дальше экспериментирую.. Буду благодарен за фрагмент исходника для слейвов с RS485 или хотябы словесное объяснение алгоритма. Вечером отпишу что получилось у меня Изменено 24 октября, 2007 пользователем Athlon128 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
prm 0 24 октября, 2007 Опубликовано 24 октября, 2007 · Жалоба Работу слейва,как вариант, можно описать следующим образом. Будем считать пакет принятым, если после приема последнего байта пакета истекла пауза равная времени передачи трех байтов, в течение которой не было принято ни одного байта. Если же во время паузы принимаем байт, то считаем его последним и вновь отслеживаем истечение паузы. И так далее пока пауза не истечет и пакет не будет принят. Отслеживанием паузы занимается таймер, в прерывании которого просто устанавливаем какой-либо флаг. К примеру: //------------------------------------------------------------------------------------------- unsigned char Read_USART(unsigned char kol) // kol - число байт, которое хотим принять { unsigned char i; for(i=0;i<kol;i++) { TimerFlag0=0; //очищаем флаг срабатывания таймера TCNT0=0xC8; //значение, соответсвующее паузе ~1.75мс TCCR0=0x04; //запускаем таймер //ожидаем приема байта while (!(UCSRA & (1<<RXC))) { if(TimerFlag0) //проверка, время ожидания истекло { //возвращаем число реально принятых байт return i; } //сбрасываем сторожевой таймер WDR(); } //считываем байт buf=UDR; TCCR0=0x00; } return i; } //--------------------------------------------------------------------------------------- //Прерывание от таймера 0, свидетельствует о превышении интервала ожидания для приема байта interrupt [TIM0_OVF] void timer0_ovf_isr(void) { TCCR0=0x00; //останавливаем таймер TimerFlag0=1; //устанавливаем флаг срабатывания } В основной программе: //принимаем пакет k=Read_USART(IN_BUF_LEN); //анализируем его error = AnalizeBuf(k); :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Палыч 9 24 октября, 2007 Опубликовано 24 октября, 2007 · Жалоба Буду благодарен за фрагмент исходника для слейвов с RS485 или хотябы словесное объяснение алгоритма. В глаза бросаются недостатки примененного в Вашей работе протокола. Например, префикс и постфикс могут совпадать с другими полями команды (кодом, адресом, аргументами); если они применяются для целей нахождения начала и конца команды, то в этом случае - это будет сделать затруднительно. Да, и проверка "правильности" приема пакета (например, с помощью контрольной суммы) - дело не последнее. Рекомендую ознакомится с тем, как это делают другие. Например, тут http://www.caxapa.ru/lib/wake/ И исходники для AVR приведены... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DASM 0 24 октября, 2007 Опубликовано 24 октября, 2007 · Жалоба В данном случае думаю проще Modbus ASCII использовать, тем более похоже им и навеяно Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
prm 0 24 октября, 2007 Опубликовано 24 октября, 2007 · Жалоба Либо ModBus RTU, тоже вещь очень хорошая. Я бы даже сказал просто не заменимая в работе Master-Slave систем. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alexander55 0 24 октября, 2007 Опубликовано 24 октября, 2007 · Жалоба В глаза бросаются недостатки примененного в Вашей работе протокола. Я рекомендую протокол ModBus. Дешево и сердито. PS. Какой у нас народ шустрый. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DASM 0 24 октября, 2007 Опубликовано 24 октября, 2007 · Жалоба Modbus RTU не люблю по причине определенных сложностей обработки потока на компе (винда не real time, и 3.5 символа паузы определить 100 % проблематично). Лучше действительно wake- подобное, ну или если траффика не жалко ASCII Modbus Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
prm 0 24 октября, 2007 Опубликовано 24 октября, 2007 · Жалоба Пользую ModBus RTU (вернее ModBus RTU-подобный протокол ). Обычно поступаю следующим образом. В качестве мастера выступает комп, он формирует запросы, анализирует ответы, осуществляет мониторинг, пишет БД и т.д. Обмен информацией организую так: 1. Очищаю приемный и передаваемый буферы драйвера COM - порта; 2. Отправляю запрос слейв устройствам; 3. Делаю маленькую паузу; 4. Жду поступления в приемный буфер данных (проверяю число байт в буфере) 5. Как только в буфере появились байты осуществляю считывание, если данные не идут в течении определенного времени - вываливаюсь по TIMEOUT-у 6. Анализирую принятую инфу Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться