Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Вопрос по USART
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Alex@ndr
Здравствуйте, есть маленький вопрос по 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.
zltigo
Цитата(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", а );
Alex@ndr
Цитата(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", а );


Спасибо, то что нужно. Тема закрыта.
Сергей Борщ
Цитата(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]);
prottoss
Цитата(Alex@ndr @ Feb 9 2007, 17:59) *
Здравствуйте, есть маленький вопрос по USART.
Мне нужно передавать по USART некую переменную int a (изменяется от 0 до 20000) в формате hex, причём так, чтобы длинна пакета передачи в любом случае оставалась неизменной.
А почему нельзя просто в UDR записать старший и, по завершении отправки, младший байты???
defunct
Цитата(prottoss @ Feb 9 2007, 14:26) *
А почему нельзя просто в UDR записать старший и, по завершении отправки, младший байты???

И как это потом смотреть в терминале?
раз автор использует printf видимо на то есть причины.
SasaVitebsk
Цитата(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.
ahulap
Цитата(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'};
defunct
Цитата(SasaVitebsk @ Feb 9 2007, 17:11) *
Ну а чтобы смотреть в терминале прибавить "0" к цифре. Примерно так:
...
Компилятор будет напрямую к байтам обращаться. Можно вместо переменных dig напрямую в UART.

Вы часто так поступаете? Подозреваю что нет.

Я предпочитаю использовать printf. Если возникают проблемы с памятью то пишу свой сокращенный printf, который поддерживает только те опции форматирования которые нужны мне - чаще всего это только %x, иногда еще и %d.
SasaVitebsk
Цитата(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'};


smile.gif Да, чё то переклинило
dig0 = (i >> 24) + '0';
if(dig0>'9') dig0 +=7;

ну и так далее

2 defunct.
Цитата
Вы часто так поступаете? Подозреваю что нет.


smile.gif Если честно, то совсем так не поступаю. Так поступаю в ASM, при отладочном выводе. У меня и задачи такой не было не разу. Я, обычно передаю бинарные данные, естественно в рамках какого-нибудь протокола, а на другом конце обрабатываю и представляю данные так, как мне нужно. Безусловно, я легко оперирую HEX данными (сказывается моя долгая практика работы). Нет - нет и проскакивает мысль, что человечеству давно пора на неё перейти. biggrin.gif Но, даже общаясь с сыном, и наблюдая за его затруднениями, понимаю, что отнюдь не все люди меня безоговорочно поддержат.
Поскольку проги пишу не для внутреннего пользования, то редко приходится использовать такой формат данных. Из внешних протоколов он узаконен только в MODBUS, на сколько помню.
Alex@ndr
Цитата(Сергей Борщ @ 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 ?
defunct
Цитата(Alex@ndr @ Feb 10 2007, 00:44) *
А переменная HEXtable обязательно должна быть static const ?

не обязательно, если вы не хотите чтобы эта константа хранилась не только во флеш, но и в ОЗУ, то можете ничего перед ней не писать..

если IAR исп-ете, то для размещения во флеш пишите __flash const или просто __flash
prottoss
Цитата(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 строки. Дешево и сердито smile.gif
Kirill Frolov
Цитата(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
Сергей Борщ
Цитата(Alex@ndr @ Feb 10 2007, 00:44) *
А переменная HEXtable обязательно должна быть static const ?
Нет, насчет static это я погорячился. А const очень желательно по двум причинам: во-первых для процессоров с единым адресным пространством это заставит разместить таблицу во флеш, а во-вторых компилятор будет отлавливать ошибочные попытки записать что-либо в нее. Для AVR конечно, как заметил defunct, надо добавить еще __flash.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.