Страница 2 из 3
Re: Пакетный протокол обмена данными между МК и ПК
Добавлено: Чт ноя 04, 2010 12:02:56
YKolomiets
Спасибо большое за ответ и за предложенную помощь.
Пошел вникать в CAN.
Re: Пакетный протокол обмена данными между МК и ПК
Добавлено: Сб ноя 06, 2010 01:00:19
foxit
Liv писал(а):Для каких задач и платформ Вас интересуют примеры? Опишите свою задачу, возможно, что-то подобное найдется.
Программирую AVR.
Задача такая.
На объекте 20 датчиков(нормально замкнутых кнопок). МК опрашивает датчики и по УАРТ пересылает на центральный пульт.
Пока объект один то все вроде понятно. А если объектов несколько. Вот тогда уместней использовать пакетный протокол. расстояние порядка 1 км.
Re: Пакетный протокол обмена данными между МК и ПК
Добавлено: Сб ноя 06, 2010 11:11:24
Liv
1 км - довольно много. RS-485 потянет на низких скоростях, ну или использовать проводные модемы. Что касается протокола, то Ваш случай не очень сложный, должно хватить той информации, которая есть по ссылке, которую я здесь приводил. В скором времени планирую добавить туда примеров.
Re: Пакетный протокол обмена данными между МК и ПК
Добавлено: Сб ноя 06, 2010 11:34:28
avreal
Liv писал(а):А для CRC-8 это тоже выгоднее?
Прошу прощения за задержку с ответом, закрутило.
Увы, нет. По крайней мере, для 1-Wire

CRC8 содержит в полиноме столько же единичек, сколько и 16-битная CRC от xmodem, но ведь сама CRC вдвое короче и при прокручивании для такого быстрого способа набор сдвигов и xor-ов становится ну слишком большим. Так навскидку, развёрнутый канонический цикл займёт меньше места и будет выполняться быстрее.
Но есть ещё один способ, занимающий промежуточное положение между каноническим циклом и табличным вычислением и по скорости, и по месту. Используется две таблицы по шестнадцать вхождений и CRC вычисляется таблично для каждого полубайта отдельно.
Если обычную таблицу для байтового алгоритма таблицу из 256 вхождений записать "квадратно", 16*16, то можно заметить, что все значения в таблице есть xor соответствующего значения по вертикали из первой строки и по горизонтали из первого столбца.
Соответсвтенно, для того же далласа, берём две таблицы, в одной из которых сдублирована первая строка, в другой — первый столбец (если я нигде не ошибся в перебивании чисел из таблички в далласовской апноте).
Код: Выделить всё
uint8_t crctable_1w_lo[] = {
0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65
};
uint8_t crctable_1w_hi[] = {
0, 157, 35, 190, 70, 219, 101, 248, 140, 17, 175, 50, 202, 233, 116
};
И обновление CRC для одного байта будет выглядеть так
Код: Выделить всё
uint8_t crc_1w_table_4(uint8_t crc, uint8_t data)
{
uint8_t index = crc ^ data;
return crctable_1w_lo[ index & 0x0F] ^ crctable_1w_hi[ index >> 4];
}
Будет оно ближе по скорости к циклу или к привычной табличке для целых байтов — зависит от архитектуры контроллера, разрядности его самого и CRC. Так навскидку для AVR при аккуратнов выписывании на асме (с выровненными на границу 16 байт полутаблицами) это будет раза в полтора быстрее, чем развёрнутый в линеечку цикл. А места займёт ощутимо меньше, чем полноразмерная таблица.
Может, когда-то разрожусь на статеечку на эту тему, а может и нет — в сети, вообще говоря, довольно много информации, а писатель статей из меня не такой хороший, как Вы.
Re: Пакетный протокол обмена данными между МК и ПК
Добавлено: Сб ноя 06, 2010 11:40:57
Jack_A
foxit писал(а):
На объекте 20 датчиков(нормально замкнутых кнопок). МК опрашивает датчики и по УАРТ пересылает на центральный пульт.
От каждого датчика - своя линия или на шине?
Если своя - никаких протоколов не надо, принимаются логические сигналы напрямую ( если пинов хватает ) или через мультиплексор.
Если шина и в точке размещения датчика не ставить МК -- ес-сно, никакой протокол не поможет, один замкнутый блокирует всех.
Если ставить МК на каждую точку, и решена проблема его питания ( по отдельному проводу или с разделением питание-сигнал ) опять же никакой протокол не нужен :
хост посылает слейву адрес, и дивайс на этом адресе отвечает одним битом Вкл/Откл.
Или еще проще: хост посылает стартовый маркер, у каждого дивайса есть его временной интервал, во время которого он отвечает опять же одним битом.
В общем, IMHO, по воробьям лучше из рогатки ( если позволит ОЗЖ ). а из установки "Град" - это не комильфо. Я так думаю.
Перечитал вопрос и уточняю: датчики сводятся к одному МК и уж от него - в комп?
Тогда о каком пакетном режиме может идти речь - ПК обменивается с МК по схеме "точка-точка", длина фиксированная - 3 байта. Я бы повторил эти 3 байта 3 раза и потом мажоритарно выбрал корректное значение, не усложняя. Проверено, надежно работает, причем не в информационной системе, а в АСУТП.
Re: Пакетный протокол обмена данными между МК и ПК
Добавлено: Сб ноя 06, 2010 11:50:43
avreal
avreal писал(а):если я нигде не ошибся в перебивании чисел из таблички в далласовской апноте
Стоп, что-то я так с чистого листа нахомутал при переносе кода от какого-то из 16-битных алгоритмов. Из таблички в апноте переписал вроде бы правильно, но при прогоне в тестовой программе не всегда сходится. Может, конечно, не сходится в самой тестовой программке, но это уже посмотрю позже, сейчас опять бегу дальше.
Re: Пакетный протокол обмена данными между МК и ПК
Добавлено: Сб ноя 06, 2010 11:57:27
Jack_A
foxit писал(а):
На объекте 20 датчиков(нормально замкнутых кнопок). МК опрашивает датчики и по УАРТ пересылает на центральный пульт.
От каждого датчика - своя линия или на шине?
Если своя - никаких протоколов не надо, принимаются логические сигналы напрямую ( если пинов хватает ) или через мультиплексор.
Если шина и в точке размещения датчика не ставить МК -- ес-сно, никакой протокол не поможет, один замкнутый блокирует всех.
Если ставить МК на каждую точку, и решена проблема его питания ( по отдельному проводу или с разделением питание-сигнал ) опять же никакой протокол не нужен :
хост посылает слейву адрес, и дивайс на этом адресе отвечает одним битом Вкл/Откл.
Или еще проще: хост посылает стартовый маркер, у каждого дивайса есть его временной интервал, во время которого он отвечает опять же одним битом.
В общем, IMHO, по воробьям лучше из рогатки ( если позволит ОЗЖ ). а из установки "Град" - это не комильфо. Я так думаю.
Перечитал вопрос и уточняю: датчики сводятся к одному МК и уж от него - в комп?
Тогда о каком пакетном режиме может идти речь - ПК обменивается с МК по схеме "точка-точка", длина фиксированная - 3 байта. Я бы повторил эти 3 байта 3 раза и потом мажоритарно выбрал корректное значение, не усложняя. Проверено, надежно работает, причем не в информационной системе, а в АСУТП.
PS Саша, давно хотел спросить : а кто такой метелик?

Re: Пакетный протокол обмена данными между МК и ПК
Добавлено: Сб ноя 06, 2010 12:26:55
Liv
avreal писал(а):Но есть ещё один способ, занимающий промежуточное положение между каноническим циклом и табличным вычислением и по скорости, и по месту.
Да, с полутаблицами вычислять тоже можно, где-то встречал такую реализацию. Но я все же думаю сделать в исходнике 2 варианта, один из которых можно будет выбирать на этапе компиляции: обычное вычисление с циклом (нужно меньше всего памяти, используется в случаях, когда скорость не важна) и табличный (максимальная скорость, а 256 байт памяти программ сейчас действительно не такая уж проблема). Что касается CRC-16, то используется она только на плохих каналах связи, а там скорость не нужна.
Re: Пакетный протокол обмена данными между МК и ПК
Добавлено: Сб ноя 06, 2010 13:37:36
avreal
avreal писал(а):Из таблички в апноте переписал вроде бы правильно
Ага, щас ™
Тупо пропустил один байт, правильно так:
Код: Выделить всё
const uint8_t crctable_1w_hi[] = {
0, 157, 35, 190, 70, 219, 101, 248, 140, 17, 175, 50, 202, 87, 233, 116
};
Liv писал(а):обычное вычисление с циклом и табличный
Ну для CRC8, пожалуй, да. А 16-битная CRC на 8-битнике указанным выше методом из комбинаций сдвигов места занимает практически как цикл, а по времени почти как табличный. Специфика побайтового беганья к памяти за 16-битными значениями.
Jack_A писал(а):PS Саша, давно хотел спросить : а кто такой метелик? 
Привет, Евгений!
Бабочка.
Эта фраза мне несколько лет назад приснилась. Именно фраза, а не картина, мне иногда снятся тексты.
Причём снилась нахально несколько дней подряд.
Дочка потом говорила, что ночью в меня вселился дух Мацуо Басьо 
Re: Пакетный протокол обмена данными между МК и ПК
Добавлено: Сб ноя 06, 2010 23:54:35
foxit
Jack_A писал(а):foxit писал(а):
На объекте 20 датчиков(нормально замкнутых кнопок). МК опрашивает датчики и по УАРТ пересылает на центральный пульт.
От каждого датчика - своя линия или на шине?
Если своя - никаких протоколов не надо, принимаются логические сигналы напрямую ( если пинов хватает ) или через мультиплексор.
Если шина и в точке размещения датчика не ставить МК -- ес-сно, никакой протокол не поможет, один замкнутый блокирует всех.
Если ставить МК на каждую точку, и решена проблема его питания ( по отдельному проводу или с разделением питание-сигнал ) опять же никакой протокол не нужен :
хост посылает слейву адрес, и дивайс на этом адресе отвечает одним битом Вкл/Откл.
Или еще проще: хост посылает стартовый маркер, у каждого дивайса есть его временной интервал, во время которого он отвечает опять же одним битом.
В общем, IMHO, по воробьям лучше из рогатки ( если позволит ОЗЖ ). а из установки "Град" - это не комильфо. Я так думаю.
Перечитал вопрос и уточняю: датчики сводятся к одному МК и уж от него - в комп?
Тогда о каком пакетном режиме может идти речь - ПК обменивается с МК по схеме "точка-точка", длина фиксированная - 3 байта. Я бы повторил эти 3 байта 3 раза и потом мажоритарно выбрал корректное значение, не усложняя. Проверено, надежно работает, причем не в информационной системе, а в АСУТП.
от каждого датчика своя линия.
на простых задачах легче изучить в данном случае протокол, а потоп уже внедрять.
Re: Пакетный протокол обмена данными между МК и ПК
Добавлено: Вс ноя 07, 2010 21:38:59
Jack_A
foxit писал(а):
от каждого датчика своя линия.
на простых задачах легче изучить в данном случае протокол, а потоп уже внедрять.
Не надо меня так обильно цитировать, загордюсь
Если так, то для приема с датчиков никакого протокола не надо - достаточно соманды
in
А передать от МК в порт... Как вариант - то, что я выше описал, преимущество - относительно большая помехоустойчивость. Маловероятно, что побьются 2 или все 3 копии одного байта.
Если передавать со станартным подходом - заголовок пакета - данные - контрольная сумма - ответ; если побился хотя бы один бит, то перезапрос, потери времени.
Но стандартные протоколы, согласен, изучать и пробовать надо, может пригодиться при подключении промышленного прибора, ему уже не прикажешь, он передает, как обучен.
Re: Пакетный протокол обмена данными между МК и ПК
Добавлено: Ср дек 08, 2010 16:00:03
grisha109
Доброго времени суток!
Недавно столкнулся с задачей обмена информацией в системе из трех МК AVR ATmega644, в которой два МК должны передавать данные в третий по UART. Для этих целей решил взять за основу протокол WAKE с сайта
http://digit-el.com/files/open/wake/wake.html . поскольку пишу в среде CodeVisionAVR, то пришлось переделывать исходный код для IAR под CV.
Поскольку я новичок

возникло несколько глупых вопросов

:
Все имеющиеся библиотеки (файлы с .h) я подключил к своему проекту в CV, из С файлов все функции и объявления переменных скопировал в свой проект и подправил под CV. Далее пытаюсь осуществить обмен данными между двумя МК в среде Proteus но ничего не выходит.
В основном цикле обоих микроконтроллеров программы делаю следующее (полный код программы в прикрепленном файле):
Port_Init();
while (1)
{
Tx_Dat[0]=1;
Tx_Dat[1]=2;
Tx_Dat[2]=3;
t1=Rx_Dat[0];
t2=Rx_Dat[1];
t3=Rx_Dat[2];
sprintf(lcd_buffer,"RECEVING");
lcd_clear();
lcd_puts(lcd_buffer);
FloatToLCD(t1,0);
delay_ms(300);
FloatToLCD(t2,1);
delay_ms(300);
FloatToLCD(t3,2);
}
Большая просьба по возможности объяснить каким образом использовать данный протокол применительно к обмену данными между МК
Re: Пакетный протокол обмена данными между МК и ПК
Добавлено: Ср дек 08, 2010 23:40:05
Liv
Готовые примеры есть только для обмена между МК и компьютером. В случае обмена между двумя МК для мастера придется писать функции обмена самостоятельно. Они, конечно, будут не сильно отличаться, но все-таки будут другими. То, что Вы написали в основном цикле, неработоспособно. Нужно заполнить все поля пакета, передать его, затем дождаться приема пакета, анализируя Command, и только затем читать буфер приема.
Re: Пакетный протокол обмена данными между МК и ПК
Добавлено: Пт дек 10, 2010 21:56:11
Pavel V.
А я подсмотрел вот такое интересное решение для формирования исходящего пакета (на С++).
Использовать примерно следующим образом:
Код: Выделить всё
void SendInputsState(void) {
Message message(&uart0);
message.Send(Commands::CMD_DI_ALL);
message.Send(0x02);
uint16_t inputsState = inputs.GetState();
message.Send(inputsState >> 8);
message.Send(inputsState);
}
Прием пакета:
Код: Выделить всё
/*!
* @brief Обработчик прерывания по приему
*/
virtual void RxHandler(void) {
uint8_t ch = GetChar();
if(ch == UartBase<RX, TX>::m_StartOfMessage) {
UartBase<RX, TX>::m_RxBuffer.flush();
return;
} else if(ch == UartBase<RX, TX>::m_EndOfMessage) {
g_Uart0MessageReceive.Signal();
return;
} else if(ch == UartBase<RX, TX>::m_Escape) {
UartBase<RX, TX>::m_IsEscape = true;
return;
}
if(UartBase<RX, TX>::m_RxBuffer.get_free_size() > 0) {
if(UartBase<RX, TX>::m_IsEscape) {
UartBase<RX, TX>::m_RxBuffer.push(ch ^ 0x20);
UartBase<RX, TX>::m_IsEscape = false;
} else {
UartBase<RX, TX>::m_RxBuffer.push(ch);
}
}
}
Обработка пакета вынесена из прерывания и происходит по событию g_Uart0MessageReceive:
Код: Выделить всё
void Process(uint8_t command, uint8_t length) {
uint8_t message[128];
message[0] = command;
message[1] = length;
uint16_t crc = 0;
uint16_t crcRcv = 0;
bool result = true;
if(length > 0) {
result = uart0.Read(&message[2], length);
}
if(!result) {
return;
}
crc = Crc::Crc16Block(message, length + 2);
if(uart0.ReadCrc(crcRcv)) {
if(crc == crcRcv) {
Invoke(message);
}
}
}
Удачи!
Re: Пакетный протокол обмена данными между МК и ПК
Добавлено: Сб дек 11, 2010 01:39:13
Liv
Я тоже переделал функции работы с WAKE:
Возможно, что-то там сыро, еще мало тестировал.
Re: Пакетный протокол обмена данными между МК и ПК
Добавлено: Сб дек 11, 2010 09:40:33
foxit
Liv писал(а):Я тоже переделал функции работы с WAKE:
Возможно, что-то там сыро, еще мало тестировал.
а можно примерчик простенький?
Re: Пакетный протокол обмена данными между МК и ПК
Добавлено: Сб дек 11, 2010 11:23:17
Liv
Так там же всё есть. Wake.c - это реализация протокола, а Port.c - пример его использования.
Re: Пакетный протокол обмена данными между МК и ПК
Добавлено: Вт июн 07, 2011 11:12:51
OKF
Леонид Иванович, а отчего Вы именно такой CRC8 используете? Отчего не взять какой-нибудь из "стандартных", типа Dallass 1-wire?
Re: Пакетный протокол обмена данными между МК и ПК
Добавлено: Вс июн 12, 2011 18:23:21
Леонид Иванович
А у меня и есть Dallas.
Re: Пакетный протокол обмена данными между МК и ПК
Добавлено: Пн июн 13, 2011 04:24:39
OKF
А отчего CRC_INIT = 0xde? У Далласа, как я понимаю, 0.