Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ATmega AVR
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.57/44: Рейтинг темы: голосов - 44, средняя оценка - 4.57
0 / 0 / 0
Регистрация: 21.01.2012
Сообщений: 30
1

AVR пакеты по UART,помогите разобраться в системе команд

13.10.2012, 13:15. Показов 8278. Ответов 12
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте! Не знал куда отправить этот вопрос. Прошу помощи!
вкратце:
моя задача разработать прошивку для мк AVR ATmega16, входящего в состав платы сопряжения с компьютером зарядного устройства(ЗУ), плата сопряжения мереет выходное напряжение ЗУ(стоит АЦП), задаёт заданное для ЗУ(с помощью ЦАП), выводит и то и другое на ЖКИ и позволяет осуществлять с компьютера управление ЗУ по интерфейсу RS-232(запуск, остановку, передачу заданного значения для ЦАП) и считывание информации(о состояниии, измеренном АЦП напряжении и заданном для ЦАП значении).
Собственно сами вопросы:
Есть система команд [205.4 Кб]

и куча вопросов по ней.
Я воспринял её так:
1) Команда чтения состояния. Запрос занимает 4байта. Ответ 7байт: под (ацп) я отвёл 2 байта(думаю надо передавать в коде, а не в В, максим-е зн-е 0xFFFF - соответствует 16-битному АЦП); под (блок)(сост) я отвёл 1 байт(для примера код 0х12 - это готов и разомкнута цепь вн.блокировки); (ошибка) думаю тоже 1 байт, ещё начальный конечный символ и адрес - итого 7байт. почему в примере у них такой ответ я не догнал чуство что (ацп) передаётся не в хексах а в символах или ещё как то да и не в кодах а в В зачем это..
2) Команда чтения задан. напр. и напр. отс. Запрос занимает 4байта. Ответ 7байт: под (ЦАП) и (U_отсечки) я отвёл по 2 байта на каждое(так же в кодах и там и там максим-е зн-е 0xFFFF). Зачем (U_отсечки) делённое на 100 вообще не догнал..
3) команда управления. Запрос по моей логике занял 8байт: под (0) я отвёл 1 байт, под (мощность)(заряд) - 1 байт, (ЦАП) - 2 байта, итого 8байт. Ответ-3байта.
4)Команда задания напряжения отсечки. Под каждый (0) отвёл по 1байту, под (U_отсечки) снова 2 байта, итого получил вместе со всем прочим 11 байт.

Не совсем понятно так же как эти все эти байты в прерывании по приёму RXD собрать в команду если (ЦАП) в хексах передавать ведь в составе команды могут быть символы начала и конца строки..

В общем я окончательно запутался правильно ли я это всё понял.. да и к кому обратиться .. Ктсати наверно важно - подобных устройств там уже куча и они все уже управляются поэтому думаю систему команд мне менять по моему усмотрению никто не позволит.. Если кто дочитал до конца - уже отдельное спасибо)
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
13.10.2012, 13:15
Ответы с готовыми решениями:

Вопрос по системе команд устройства подключенного по UART
Здравствуйте! Опишу кратко суть вопроса. Есть некое устройство, подключенное к ПК по UART....

[решено] Помогите разобраться с UART
Здравствуйте. Нужна помощь с UART-ом у кого есть опыт, подскажите. Ниже мой несложный протокол,...

ATMega 162 помогите разобраться с UART
Добрый вечер! Помогите разобраться с UART0 на ATMiko162. Нашел пример работы на прерываниях, и...

Помогите разобраться с lcd в bascom avr
Помогите разобраться! Подключил рабочий МЭЛТ mt-16s2d к atmego32 по 4 битам, а он не реагирует на...

помогите разобраться с USART для AVR crumb2560
Доброго времени суток! Мне необходимо связать плату Avr crumb2560 c ПК по rs-232, для написания...

12
0 / 0 / 0
Регистрация: 03.11.2012
Сообщений: 9
13.10.2012, 13:32 2
Цитата Сообщение от oski12345
1) Ответ 7байт: ...
Нет. Ответ 10 байт + символ начала передачи и символ окончания. Под АЦП отводится 5 байт. Если не соблюсти формат посылки, оконечное устройство вас не поймет.
Не совсем понятно так же как эти все эти байты в прерывании по приёму RXD собрать в команду если (ЦАП) в хексах передавать ведь в составе команды могут быть символы начала и конца строки..
Вы передаете десятичное число в ASCII формате. Оно не принимает значения символов начала и конца строки.
0
Th0r
13.10.2012, 13:44 3
Цитата Сообщение от oski12345
1) Команда чтения состояния. Запрос занимает 4байта.
запрос занимает 6 байт
1 - $
2 и 3 - 16ричные цифры в ASCII формате
4 - символ "3"
5 - символ "0"
6 - символ 0x0D (перевод строки)
0 / 0 / 0
Регистрация: 21.08.2011
Сообщений: 1,057
13.10.2012, 16:33 4
Я понимаю, что для готового устройства никто не будет менять систему команд, но на будущее старайтесь использовать или стандартные протоколы (Modbus), или нормальный человеческий ASCII. Окупится сторицей при наладке и эксплуатации.
Как-то писал модуль связи с кетайской системой контроля доступа: таким продвинутым домофоном с временными зонами, логами, группами пользователей и сканером отпечатков пальцев. Протокол там включал от 10 до 16 полей данных, среди которых были перемешаны big-endian integers, BCD, ASCII integers, нигические константы и контрольные суммы. Плюс машина состояний, по которой порядок выполнения комманд тоже имел свои особенности. Плюс документация на китайском диалекте английского. В общем проклинал я разработчика долго и со страстью и с тех пор не экономлю на байтах протокола.
0
0 / 0 / 0
Регистрация: 03.11.2012
Сообщений: 9
13.10.2012, 17:16 5
Так ведь в приведенном протоколе обмен как раз символами ASCII и происходит.
0
0 / 0 / 0
Регистрация: 21.01.2012
Сообщений: 30
14.10.2012, 10:44 6
Всем большое спасибо, теперь вроде уложилось. Если я так понял, то получается следующее:
1) Команда чтения состояния. Запрос занимает 6 байт. Ответ 12 байт;
2) Команда чтения задан. напр. и напр. отс. Запрос занимает 6 байт. Ответ 12 байт;
3) команда управления. Запрос занимает 14 байт. Ответ 4 байта;
4) Команда задания напряжения отсечки. Запрос занимает 14 байт. Ответ 4 байта.
0
0 / 0 / 0
Регистрация: 03.11.2012
Сообщений: 9
14.10.2012, 13:06 7
"Плюс" этого протокола в том, что его можно начать отлаживать в стандартном виндовском гипертерминале без готовой целевой платы. По пунктам. Просто соединяешь ПК с "компьютером зарядного устройства" и отлаживаешь обмен вообще без контроллера. После того, как научишь их общаться, реализовать протокол будет несложно.
И да, обычно между включением и готовностью к обмену, а также запросом и ответом существуют определенные временные задержки, которые должны быть указаны в описании протокола. Т.е. первый запрос должен быть отправлен не раньше, чем через Х секунд после включения, а ответ устройство выдаст не ранее, чем через У мсек после обработки запроса. При отладке, когда ручками шлешь байты, эти условия выполняются автоматически, а вот сами железки общаются между собой очень быстро. Тут уже интервалы нужно учитывать, иначе пакет просто потеряется или будет принят с ошибкой.
0
0 / 0 / 0
Регистрация: 21.01.2012
Сообщений: 30
15.10.2012, 10:56 8
спасибо, у меня по той же теме ещё вопрос: допустим пришла в контроллер команда управления устройством, я её как то собрал и запихнул в символьный массив: som[14]=$(27)(30)(0)(0)(0)(0C544)(0x0D). Как мне теперь вычленить из него подстроку (0C544) и преобразовать в шестнадцатеричное число 0х0C544.
Если бы стояла задача вычленить подстроку из десятичных символов и преобразовать в десятичное число(допустим 50500 в десятичное). Я бы наверно создал второй символьный массив размерностью 5 символов mas[5] и посимвольно присвоив его элементам соответствующие элементы принятой команды mas[0]=som[9]; mas[1]=som[10];..mas[4]=som[13]; функцией c= atoi(mas); преобразовал его в целое десятичное число, правильно ли это.. и как быть с шестнадцатеричным..
0
0 / 0 / 0
Регистрация: 03.11.2012
Сообщений: 9
15.10.2012, 12:33 9
Да в общем, просто:
1. Убеждаешься, что первый байт является байтом начала посылки.
2. Убеждаешься, что посылка адресована именно этому модулю.
3. Включаешь счетчик принятых символов. Его переполнение укажет на ошибку кадра.
4. Декодируешь код команды, в зависимости от него обрабатываешь посылку.
Цитата Сообщение от oski12345
Как мне теперь вычленить из него подстроку (0C544) и преобразовать в шестнадцатеричное число 0х0C544.
Выполняешь начальные пункты. Сравниваешь принятый байт с $0D. Если не равен- вычитаешь (в данном случае) из принятого кода $37. Если получилось отрицательное число, то принятый символ < чем $A, -> нужно вычитать $30. В итоге получаешь двоичное представление принятого числового символа. Т.е., если после вычитания $30 осталась двойка, то и символ был "2". Короче, после того, как МК принял решение, что принятая последовательность адресована ему, расшифровал код команды и т.п., сравниваешь принятый байт с $0D и, если не равен, вычитаешь сначала $37. Если получилось отрицательное число, вычитаешь из принятого $30. Если остаток отличен от нуля- сохраняешь где нибудь значение, берешь следующее и т.д., пока не встретишь $0D или не переполнится счетчик принимаемых байтов декодированной команды. Получил признак конца посылки- делаешь преобразование DEC2BIN (процедуры есть и на ассме, а уж на Си- и подавно) и работаешь уже с двоичным представлением. Как-то так.
0
0 / 0 / 0
Регистрация: 21.01.2012
Сообщений: 30
17.10.2012, 12:06 10
Цитата Сообщение от STT
Если не равен- вычитаешь (в данном случае) из принятого кода $37. Если получилось отрицательное число, то принятый символ < чем $A, ->
я наверно что то не так понял.., мне кажется надо из принятого кода вычитать первоначально не $37 а $39, чтобы убедиться что принятый символ < чем $A, и далее если результат <=0 то вычитать из принятого $30, а если >0 вычитать $37..
И ещё один вопрос.. Насколько я понимаю ответ на команду передаётся в несколько байтов без пауз друг за другом, это куча времени, а у меня там куча прерываний за это время может успеть придти..как быть в этом случае.. или там(между байтами одного ответа) всё таки можно вводить временные паузы..
0
0 / 0 / 0
Регистрация: 03.11.2012
Сообщений: 9
17.10.2012, 13:09 11
Цитата Сообщение от oski12345
мне кажется надо из принятого кода вычитать первоначально не $37 а $39, чтобы убедиться что принятый символ < чем $A, и далее если результат <=0 то вычитать из принятого $30, а если >0 вычитать $37..
Да, ошибся. Ну, тогда уж сначала вычитать даже не $37, а $3А, п.ч. $39("9")- $37>0.
Цитата Сообщение от oski12345
Насколько я понимаю ответ на команду передаётся в несколько байтов без пауз друг за другом, это куча времени, а у меня там куча прерываний за это время может успеть придти..как быть в этом случае.. или там(между байтами одного ответа) всё таки можно вводить временные паузы..
Если используешь прерывания, то само событие происходит не по приему каждого бита, а когда собрался весь байт (Rx Complete). Считать его и пихнуть в буфер дело нескольких тактов. А чтоб не терять остальные прерывания, обработчики пишутся максимально короткими.
Вообще, вот статья: http://iosyitistromyss.ru/avr-uchebnyj- ... -uart.html
0
0 / 0 / 0
Регистрация: 21.01.2012
Сообщений: 30
18.10.2012, 15:29 12
Цитата Сообщение от STT
Если используешь прерывания, то само событие происходит не по приему каждого бита, а когда собрался весь байт
да, извините за глупый вопрос, я ступил..

А как быть с следующей ситуацией: допустим микроконтроллер принял пакет с командой, обработал и запустил таймер на отсчёт временного интервала задержки перед ответом, а в течении этой задержки пришёл пакет со следующей командой или десяток таких пакетов, может имеет смысл запрещать тогда на это время принятие данных по UART(хотя наверно это не правильно) или как то в управляющей программе с компьютера надо предусматривать какие то минимальные времена между командами либо так алгоритм строить, или же такой ситуации в принципе не может быть..
0
0 / 0 / 0
Регистрация: 26.04.2010
Сообщений: 1,445
18.10.2012, 16:28 13
Очередь команд спасет отца русской демократии. То есть мы очень быстро разбираем пакет, определяем, что за команда, кладем команду в очередь и ждем другого пакета. В это время неторопливо обработчик команд вытаскивает команды по одной и обрабатывает.

Можно предусмотреть приоритеты команд - некоторые критичные команды сразу обрабатывать, не кладя в очередь. Например "ааа, блин, погасить все нафиг!!!".

А вообще, зачем задержка перед ответом? Есть ответ - пулим его в usart, там пусть комп разгребает.

В принципе, можно преобразовать протокол так, что до получения ответа комп не присылает никаких других команд (типа AT-общение с модемом).
0
18.10.2012, 16:28
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
18.10.2012, 16:28
Помогаю со студенческими работами здесь

Скорость эмуляции в AVR studio, помогите разобраться
Доброго времени суток! Я совсем новичок, прошу помощи. Использую AVR Studyo 4.19. В коде написана...

ик-avr-uart
В общем попалась мне статейка про ик и avr http://habrahabr.ru/post/82383/ Загорелся я собрать...

AVR. UART. 9 бит.
Сложилась тут задача: два МК, соеденены по интерфейсу RS-485. Периодически первый МК шлет второму 6...

AVR на C, траблы с UART
Доброго времени суток. Я новичок в программировании, и в МК. Пытаюсь написать прогу, но не совсем...

AVR - 1-wire & UART
Привет! Мучаю 1-wire на основе UART на Тиньке 2313. Сверяюсь с даташитом, с Аппноутом и т.д....


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru