Как передать int по USART?
- Сообщения: 135
- Зарегистрирован: Чт май 09, 2013 10:50:04
Использую Atmega8a. Из даташита стащил функцию отправки 8бит по USART. Всё работает нормально, в терминале на ПК символы приходят, но не могу сообразить как можно передать на ПК переменные типа integer?
- Реклама
- Сообщения: 1817
- Зарегистрирован: Пн ноя 29, 2010 15:58:43
как вариант -передать в текстовом виде посимвольно : пример "123" три байта
- Сообщения: 844
- Зарегистрирован: Пн апр 11, 2011 10:08:52
Например, так:
приняв, собираем:
По такому же принципу можно передавать/принимать любую разрядность
Код: Выделить всё
unsigned char x;
unsigned int a;
x = a >> 8; // старший байт
x = a & 0xFF; // младший байт
Код: Выделить всё
unsigned char b[2]; // буфер, куда приняли байты
a = b[0]; // старший байт
a = a << 8; // сдивнули
a |= b[1]; // младший байт
- Сообщения: 135
- Зарегистрирован: Чт май 09, 2013 10:50:04
В терминале будет всякая ерунда выводиться если так делать. Мне именно для терминала надо.-=Vovka=- писал(а):Например, так:По такому же принципу можно передавать/принимать любую разрядностьКод: Выделить всё
unsigned char x; unsigned int a; x = a >> 8; // старший байт x = a & 0xFF; // младший байт
Я понимаю что можно разбить число, но если цифры разные то как быть? например "1", "111", "555555555"? Получится какая-то сложная функция для преобразования сразу в unsigned char? Может быть есть готовые?igor-x писал(а): как вариант -передать в текстовом виде посимвольно : пример "123" три байта
- Реклама
- Сообщения: 844
- Зарегистрирован: Пн апр 11, 2011 10:08:52
Кстати, задачу можно решить "в лоб" и без громоздкой функции sprintf():
Начнем с того, что максимальное значение числа равно 65535, т.е. 5 символов.
Понятное дело, что этот код можно упростить, убрать лидирующие нули ....
Это решения для уровня "начинающий", хотя и рабочее
Начнем с того, что максимальное значение числа равно 65535, т.е. 5 символов.
Код: Выделить всё
unsigned char a, buf[5];
unsigned int x; // тут наше число
for( a=0; a<5; a++ ) buf[a] = '0';
while( x>10000 ) { buf[0]++; x = x-10000; }
while( x>1000 ) { buf[1]++; x = x-1000; }
while( x>100 ) { buf[2]++; x = x-100; }
while( x>10 ) { buf[3]++; x = x-10; }
buf[4] = x;
Это решения для уровня "начинающий", хотя и рабочее
Скорее buf[4] += x;-=Vovka=- писал(а):Код: Выделить всё
unsigned char a, buf[5]; unsigned int x; // тут наше число for( a=0; a<5; a++ ) buf[a] = '0'; ...... buf[4] = x;
- Сообщения: 844
- Зарегистрирован: Пн апр 11, 2011 10:08:52
- Сообщения: 135
- Зарегистрирован: Чт май 09, 2013 10:50:04
Если я правильно понял условие, то просто преобразовать x в buf[5] не прокатит. Чтобы в терминале нарисовалось "12345" надо еще коды цифр в ASCII перевести, т.е. к номеру цифры добавить 0x30
Неправильно собранная из неисправных деталей схема нуждается в отладке и сразу не работает... (С)
- Сообщения: 844
- Зарегистрирован: Пн апр 11, 2011 10:08:52
Код: Выделить всё
buf[a] = '0'
Неправильно собранная из неисправных деталей схема нуждается в отладке и сразу не работает... (С)
- Сообщения: 135
- Зарегистрирован: Чт май 09, 2013 10:50:04
Всем спасибо. Сделал так:
Можно преобразовать число любой длины как мне и надо.
Переменную i буду использовать чтоб потом собрать число в правильном порядке.
Код: Выделить всё
int a = 1234, i = 0;
unsigned char ch[10];
while (a > 0)
{
ch[i] = (a % 10) + 0x30;
i++;
a /= 10;
};
Переменную i буду использовать чтоб потом собрать число в правильном порядке.
вообще-то для этого есть функция itoa
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Сообщения: 135
- Зарегистрирован: Чт май 09, 2013 10:50:04
Она принимает тип char, а мне нужен unsigned char. Как мне тогда преобразовать типы?ARV писал(а):вообще-то для этого есть функция itoa
В цикле каждый символ приводить к нужному типу uchr = (unsigned char)chr?
- Сообщения: 135
- Зарегистрирован: Чт май 09, 2013 10:50:04
Получается вот так:
Код: Выделить всё
int chilso = 1234, num = 10;
char chr[17];
unsigned char chr1[17];
int i = 0;
itoa (chislo, chr, num);
while (chr[i] != NULL)
{
chr1[i] = (unsigned char)chr[i];
i++;
}
chr1[i] = NULL;
вообще-то я не понял, что вы там натворили в коде... вам нужно получить строку из числа? itoa делает из числа строковое представление. после этого вам остается только вывести эту строку по USART. что у вас вызывает затруднения?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Ну вот откуда такие берутся, которые свои догадки выдают за реальность ?Ellissar писал(а):Она принимает тип char
Ну неужели трудно набрать слово "itoa" в поисковик ?
Первая же ссылка - https://ru.wikipedia.org/wiki/Itoa_(%D1%E8)
Цитата из неё :
Что тут может быть непонятного ? Русским по белому всё разжёвано.void* itoa(int input, char *buffer, int radix)
itoa принимает передаваемое целое число input и конвертирует его в число в основании корня radix. Полученное число (последовательность цифр основания radix) записывается в буфер вывода buffer.
- Сообщения: 135
- Зарегистрирован: Чт май 09, 2013 10:50:04
Код для вывода по USART которым я пользуюсь:ARV писал(а):что у вас вызывает затруднения?
Код: Выделить всё
void USART_Transmit( unsigned char *data, unsigned char sz)
{
cli();
for (unsigned char i = 0; i<=sz; i++)
{
/* Ожидаем когда буфер станет пустым */
while ( !( UCSRA & (1<<UDRE)) );
/* Поместить данные в буфер, отправка данных */
UDR = data[i];
}
sei();
}
Я только учусь ещё и не знаю, может есть какие-то подводные камни если поменяю тип на char в этой функции.
А Вы, когда писали в аргументе тип unsigned char, задумывались о подводных камнях ? Почему этот вопрос именно при переходе на char у вас возник ?Ellissar писал(а):может есть какие-то подводные камни если поменяю тип на char в этой функции.
Вы вообще в курсе чем они отличаются ?


