реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Вопрос по USART
Alex@ndr
сообщение Feb 9 2007, 13:59
Сообщение #1


Участник
*

Группа: Новичок
Сообщений: 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.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Feb 9 2007, 14:05
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 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
Go to the top of the page
 
+Quote Post
Alex@ndr
сообщение Feb 9 2007, 14:28
Сообщение #3


Участник
*

Группа: Новичок
Сообщений: 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", а );


Спасибо, то что нужно. Тема закрыта.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Feb 9 2007, 14:34
Сообщение #4


Гуру
******

Группа: Модераторы
Сообщений: 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)
Go to the top of the page
 
+Quote Post
prottoss
сообщение Feb 9 2007, 15:26
Сообщение #5


Гуру
******

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



Цитата(Alex@ndr @ Feb 9 2007, 17:59) *
Здравствуйте, есть маленький вопрос по USART.
Мне нужно передавать по USART некую переменную int a (изменяется от 0 до 20000) в формате hex, причём так, чтобы длинна пакета передачи в любом случае оставалась неизменной.
А почему нельзя просто в UDR записать старший и, по завершении отправки, младший байты???


--------------------
Go to the top of the page
 
+Quote Post
defunct
сообщение Feb 9 2007, 15:53
Сообщение #6


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(prottoss @ Feb 9 2007, 14:26) *
А почему нельзя просто в UDR записать старший и, по завершении отправки, младший байты???

И как это потом смотреть в терминале?
раз автор использует printf видимо на то есть причины.
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Feb 9 2007, 18:11
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 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.
Go to the top of the page
 
+Quote Post
ahulap
сообщение Feb 9 2007, 18:52
Сообщение #8


Участник
*

Группа: Участник
Сообщений: 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'};
Go to the top of the page
 
+Quote Post
defunct
сообщение Feb 9 2007, 19:08
Сообщение #9


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(SasaVitebsk @ Feb 9 2007, 17:11) *
Ну а чтобы смотреть в терминале прибавить "0" к цифре. Примерно так:
...
Компилятор будет напрямую к байтам обращаться. Можно вместо переменных dig напрямую в UART.

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

Я предпочитаю использовать printf. Если возникают проблемы с памятью то пишу свой сокращенный printf, который поддерживает только те опции форматирования которые нужны мне - чаще всего это только %x, иногда еще и %d.
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Feb 10 2007, 00:33
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 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'};


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

ну и так далее

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


smile.gif Если честно, то совсем так не поступаю. Так поступаю в ASM, при отладочном выводе. У меня и задачи такой не было не разу. Я, обычно передаю бинарные данные, естественно в рамках какого-нибудь протокола, а на другом конце обрабатываю и представляю данные так, как мне нужно. Безусловно, я легко оперирую HEX данными (сказывается моя долгая практика работы). Нет - нет и проскакивает мысль, что человечеству давно пора на неё перейти. biggrin.gif Но, даже общаясь с сыном, и наблюдая за его затруднениями, понимаю, что отнюдь не все люди меня безоговорочно поддержат.
Поскольку проги пишу не для внутреннего пользования, то редко приходится использовать такой формат данных. Из внешних протоколов он узаконен только в MODBUS, на сколько помню.
Go to the top of the page
 
+Quote Post
Alex@ndr
сообщение Feb 10 2007, 01:44
Сообщение #11


Участник
*

Группа: Новичок
Сообщений: 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 ?
Go to the top of the page
 
+Quote Post
defunct
сообщение Feb 10 2007, 06:38
Сообщение #12


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(Alex@ndr @ Feb 10 2007, 00:44) *
А переменная HEXtable обязательно должна быть static const ?

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

если IAR исп-ете, то для размещения во флеш пишите __flash const или просто __flash
Go to the top of the page
 
+Quote Post
prottoss
сообщение Feb 10 2007, 15:05
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 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 строки. Дешево и сердито smile.gif


--------------------
Go to the top of the page
 
+Quote Post
Kirill Frolov
сообщение Feb 11 2007, 00:21
Сообщение #14


Частый гость
**

Группа: Новичок
Сообщений: 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]
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Feb 11 2007, 01:09
Сообщение #15


Гуру
******

Группа: Модераторы
Сообщений: 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)
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 16:44
Рейтинг@Mail.ru


Страница сгенерированна за 0.01509 секунд с 7
ELECTRONIX ©2004-2016