|
|
  |
Вопрос по USART |
|
|
|
Feb 9 2007, 13:59
|
Участник

Группа: Новичок
Сообщений: 20
Регистрация: 22-12-06
Пользователь №: 23 802

|
Здравствуйте, есть маленький вопрос по USART. Мне нужно передавать по USART некую переменную int a (изменяется от 0 до 20000) в формате hex, причём так, чтобы длинна пакета передачи в любом случае оставалась неизменной. Тоесть при передаче числа a=18654 должна быть посылка 48DE, при а=3578 ->0DFA, при a=12 ->000C, при a=0 -> 0000. Первое что пришло в голову это вывод вот таким образом, дописывая недостающие ноли: Код if (а/256<16)printf("0"); printf("%X",а/256); if (а%256<16)printf("0"); printf("%X",а%256); Работает, но мне самому это жутко ненравится, наверняка для решения такой задачи есть способы поизящнее. Подскажите пожалуста как мне правильно выводить hex- значения. Компилятор CodeVision.
|
|
|
|
|
Feb 9 2007, 14:05
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(Alex@ndr @ Feb 9 2007, 12:59)  Здравствуйте, есть маленький вопрос по USART. А бедный USART причем? Цитата Код if (а/256<16)printf("0"); printf("%X",а/256); if (а%256<16)printf("0"); printf("%X",а%256); Работает, но мне самому это жутко ненравится, наверняка для решения такой задачи есть способы поизящнее. Подскажите пожалуста как мне правильно выводить hex- значения. Ну хоть ЧУТЬ-ЧУТЬ-ЧУТЬ о формате ....printf() ну НАДО ПОЧИТАТЬ!!!!!! Код printf( "%04X", а );
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Feb 9 2007, 14:28
|
Участник

Группа: Новичок
Сообщений: 20
Регистрация: 22-12-06
Пользователь №: 23 802

|
Цитата(zltigo @ Feb 9 2007, 13:05)  Цитата(Alex@ndr @ Feb 9 2007, 12:59)  Здравствуйте, есть маленький вопрос по USART.
А бедный USART причем? Цитата Код if (а/256<16)printf("0"); printf("%X",а/256); if (а%256<16)printf("0"); printf("%X",а%256); Работает, но мне самому это жутко ненравится, наверняка для решения такой задачи есть способы поизящнее. Подскажите пожалуста как мне правильно выводить hex- значения. Ну хоть ЧУТЬ-ЧУТЬ-ЧУТЬ о формате ....printf() ну НАДО ПОЧИТАТЬ!!!!!! Код printf( "%04X", а ); Спасибо, то что нужно. Тема закрыта.
|
|
|
|
|
Feb 9 2007, 14:34
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(Alex@ndr @ Feb 9 2007, 13:28)  Спасибо, то что нужно. Тема закрыта. А еще где-то printf используется? Если нет, то можно сэкономить память не говоря уж о времени выполнения printf: Код static const char HEXtable[] = "0123456789ABCDEF"; putchar(HEXtable[(a >> 12) & 0x0F]); putchar(HEXtable[(a >> 8) & 0x0F]); putchar(HEXtable[(a >> 4) & 0x0F]); putchar(HEXtable[(a >> 0) & 0x0F]);
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Feb 9 2007, 18:11
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Цитата(defunct @ Feb 9 2007, 16:53)  Цитата(prottoss @ Feb 9 2007, 14:26)  А почему нельзя просто в UDR записать старший и, по завершении отправки, младший байты???
И как это потом смотреть в терминале? раз автор использует printf видимо на то есть причины. Ну а чтобы смотреть в терминале прибавить "0" к цифре. Примерно так: uint16_t i; dig0 = (i >> 12) + '0'; dig1 = ((i >> 8) & 0xf) + '0'; dig2 = ((i >> 4) & 0xf) + '0'; dig3 = (i & 0xf) + '0'; Компилятор будет напрямую к байтам обращаться. Можно вместо переменных dig напрямую в UART.
|
|
|
|
|
Feb 9 2007, 18:52
|
Участник

Группа: Участник
Сообщений: 44
Регистрация: 22-06-06
Из: Kharkiv, UA
Пользователь №: 18 284

|
Цитата(SasaVitebsk @ Feb 9 2007, 17:11)  dig0 = (i >> 24) + '0'; dig1 = ((i >> 16) & 0xf) + '0'; dig2 = ((i >> 8) & 0xf) + '0'; dig3 = (i & 0xf) + '0'; Для хексов так не получится - в таблице символов между '9' и 'A' идут ':', ';'... Так что, наверное, проще всего перекодировать черем массив char HEX[16]={'0'... 'E','F'};
|
|
|
|
|
Feb 10 2007, 00:33
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Цитата(ahulap @ Feb 9 2007, 19:52)  Цитата(SasaVitebsk @ Feb 9 2007, 17:11)  dig0 = (i >> 24) + '0'; dig1 = ((i >> 16) & 0xf) + '0'; dig2 = ((i >> 8) & 0xf) + '0'; dig3 = (i & 0xf) + '0';
Для хексов так не получится - в таблице символов между '9' и 'A' идут ':', ';'... Так что, наверное, проще всего перекодировать черем массив char HEX[16]={'0'... 'E','F'};  Да, чё то переклинило dig0 = (i >> 24) + '0'; if(dig0>'9') dig0 +=7; ну и так далее 2 defunct. Цитата Вы часто так поступаете? Подозреваю что нет.  Если честно, то совсем так не поступаю. Так поступаю в ASM, при отладочном выводе. У меня и задачи такой не было не разу. Я, обычно передаю бинарные данные, естественно в рамках какого-нибудь протокола, а на другом конце обрабатываю и представляю данные так, как мне нужно. Безусловно, я легко оперирую HEX данными (сказывается моя долгая практика работы). Нет - нет и проскакивает мысль, что человечеству давно пора на неё перейти.  Но, даже общаясь с сыном, и наблюдая за его затруднениями, понимаю, что отнюдь не все люди меня безоговорочно поддержат. Поскольку проги пишу не для внутреннего пользования, то редко приходится использовать такой формат данных. Из внешних протоколов он узаконен только в MODBUS, на сколько помню.
|
|
|
|
|
Feb 10 2007, 01:44
|
Участник

Группа: Новичок
Сообщений: 20
Регистрация: 22-12-06
Пользователь №: 23 802

|
Цитата(Сергей Борщ @ Feb 9 2007, 13:34)  А еще где-то printf используется? Если нет, то можно сэкономить память не говоря уж о времени выполнения printf: Код static const char HEXtable[] = "0123456789ABCDEF"; putchar(HEXtable[(a >> 12) & 0x0F]); putchar(HEXtable[(a >> 8) & 0x0F]); putchar(HEXtable[(a >> 4) & 0x0F]); putchar(HEXtable[(a >> 0) & 0x0F]); Во, вот этот вариант ещё лутше - позволил повыкидывать printf и сэкономить почти 1кб памяти! А переменная HEXtable обязательно должна быть static const ?
|
|
|
|
|
Feb 10 2007, 15:05
|

Гуру
     
Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659

|
Цитата(defunct @ Feb 9 2007, 19:53)  Цитата(prottoss @ Feb 9 2007, 14:26)  А почему нельзя просто в UDR записать старший и, по завершении отправки, младший байты???
И как это потом смотреть в терминале? раз автор использует printf видимо на то есть причины. Возможно, есть. Но я лишь высказал мнение по цитате из поста автора. Цитата(defunct @ Feb 9 2007, 23:08)  Цитата(SasaVitebsk @ Feb 9 2007, 17:11)  Ну а чтобы смотреть в терминале прибавить "0" к цифре. Примерно так: ... Компилятор будет напрямую к байтам обращаться. Можно вместо переменных dig напрямую в UART.
Вы часто так поступаете? Подозреваю что нет. Я предпочитаю использовать printf. Если возникают проблемы с памятью то пишу свой сокращенный printf, который поддерживает только те опции форматирования которые нужны мне - чаще всего это только %x, иногда еще и %d. У меня два своих "принт". Первый пишет в усарт из флэш, второй из SRAM, строки, заканчивающиеся нулем. Все числа преобразую в десятичные, а далее в ascii строки. Дешево и сердито
--------------------
|
|
|
|
|
Feb 11 2007, 00:21
|

Частый гость
 
Группа: Новичок
Сообщений: 111
Регистрация: 10-02-07
Из: St.Petersburg, Russia
Пользователь №: 25 241

|
Цитата(Alex@ndr @ Feb 9 2007, 13:59)  Тоесть при передаче числа a=18654 должна быть посылка 48DE, при а=3578 ->0DFA, при a=12 ->000C, при a=0 -> 0000. Первое что пришло в голову это вывод вот таким образом, дописывая недостающие ноли: Код if (а/256<16)printf("0"); printf("%X",а/256); if (а%256<16)printf("0"); printf("%X",а%256); Ужоснафиг. А это, почитать мануал на стандартную библиотеку языка C не помогает? Вот конкретно семействи функций printf. На счёт ширины поля: %4x... (это подсказка) http://www.hmug.org/man/3/printf.php
--------------------
[ZX]
|
|
|
|
|
Feb 11 2007, 01:09
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(Alex@ndr @ Feb 10 2007, 00:44)  А переменная HEXtable обязательно должна быть static const ? Нет, насчет static это я погорячился. А const очень желательно по двум причинам: во-первых для процессоров с единым адресным пространством это заставит разместить таблицу во флеш, а во-вторых компилятор будет отлавливать ошибочные попытки записать что-либо в нее. Для AVR конечно, как заметил defunct, надо добавить еще __flash.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|