Страница 1 из 2

Перевод числа в СИ

Добавлено: Ср ноя 13, 2013 15:57:24
СергейКир
Здравствуйте.
Язык Си, AVRStudio6, Mega8.
Вопрос.
Как правильно/грамотно перевести число (от 0 до 255) из десятичной системы в HEX.
Есть у меня функция send_byte(), тело функции не привожу(не имеет смысла);
Вот так

Код: Выделить всё

send_byte(0b10101010)
// или так  
send_byte(0xAA)
она работает как надо.
Хочу чтобы аргументом была переменная.
Делаю так:

Код: Выделить всё

int i=25;
char s;
sprintf(s,"%x",i);
send_byte(s);
и не работает. Что не так в переводе? Или всё не так?
Заранее спасибо.

Re: Перевод числа в СИ

Добавлено: Ср ноя 13, 2013 16:13:59
vovksextra
Достаточно сделать так:

Код: Выделить всё

int i=25;
send_byte(i);

Re: Перевод числа в СИ

Добавлено: Ср ноя 13, 2013 16:16:06
СергейКир
Спасибо. Пробую...
Прошиваю...
Не получилось. Отправляю к примеру 28 приходит 156. А если 0x1С то 28, как и надо.
Всё таки, что не так с моим переводом??? (см. выше)

Re: Перевод числа в СИ

Добавлено: Ср ноя 13, 2013 17:05:27
blackx
Давайте все-таки весь код целиком.

В вашем примере неправильно хотя бы то, что функции sprintf() необходимо передавать указатель на массив типа char, а не значение переменной типа char.

И определитесь, хотите вы число передавать как число или число передавать как строку.

Re: Перевод числа в СИ

Добавлено: Ср ноя 13, 2013 17:45:05
СергейКир
blackx писал(а):Давайте все-таки весь код целиком.
И определитесь, хотите вы число передавать как число или число передавать как строку.
Код смогу уже только завтра.
Число хочу передавать как строку.

Re: Перевод числа в СИ

Добавлено: Ср ноя 13, 2013 18:11:56
xVekx

Код: Выделить всё

char buff[10];
memset(buff,0x00,10);
uint32_t A=400;
sprintf(buff,"%x\n",A);
send_byte(s);

Re: Перевод числа в СИ

Добавлено: Ср ноя 13, 2013 18:36:02
BCluster

Код: Выделить всё

char i = 0x3C;
send_byte(i);
и

Код: Выделить всё

char i = 60;
send_byte(i);
даст разные результаты исполнения?) не верю

Насчет "что не так с моим переводом"... все не так
функция, как я понимаю передает 1 байт
даже если бы правильно был написан этот printf, число в хексе в виде строки это 2 байта

Re: Перевод числа в СИ

Добавлено: Ср ноя 13, 2013 18:47:07
BCluster
СергейКир писал(а):Отправляю к примеру 28 приходит 156
Кстати, 156 от 28 отличается только наличием "1" в старшем бите. Странное совпадение ))

и почему
int i = 25;
send_byte(i);

если передаем char то и объявляйте i как char. Мож компилятор чет себе придумал на этой почве

Re: Перевод числа в СИ

Добавлено: Ср ноя 13, 2013 18:47:56
blackx
СергейКир писал(а):Число хочу передавать как строку.
Хорошо, попробуйте так

Код: Выделить всё

int input = 100500;
int i = 0;
char buf[10];
char s;
itoa(input, buf, 16); // stdlib.h, non-ANSI
while((s = buf[i++]) != 0) send_byte(s);

Re: Перевод числа в СИ

Добавлено: Ср ноя 13, 2013 18:59:40
BCluster
blackx, судя по постам ТС, что передача типа send_byte(0xFF) его устраивает, то ТС сам не знает что он хочет в итоге получить :))

Re: Перевод числа в СИ

Добавлено: Ср ноя 13, 2013 20:18:38
xVekx

Код: Выделить всё

#define F_CPU			16000000		//частота микропроцессора
#define BAUD_DEV		38400			//Скорость передачи COM порта он же RS-232 (USART)
#define MYUBRR			F_CPU/16/BAUD_DEV-1

#include <avr/io.h>
#include <util/delay.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void USART_Init(uint32_t ubrr)
{
	/* Set baud rate */
	UBRR0H = (uint8_t)(ubrr>>8);
	UBRR0L = (uint8_t)ubrr;
	/* Enable receiver and transmitter */
	UCSR0B = (1<<RXEN0)|(1<<TXEN0);
	/* Set frame format: 8data, 2stop bit */
	//rUCSRC = (1<<bURSEL)|(1<<bUSBS)|(3<<bUCSZ0);
	UCSR0C = (1<<USBS0)|(3<<UCSZ00);
}

void USART_Transmit(uint8_t data)
{
	/* Wait for empty transmit buffer */
	while ( !( UCSR0A & (1<<UDRE0)) );
	/* Put data into buffer, sends the data */
	UDR0 = data;
}

void UsartBuffTransmit(uint8_t *data,uint8_t size)
{
	for(uint8_t i=0;i<size;i++)
	{
		USART_Transmit(data[i]);
	}
}

void USART_Setup()
{
	USART_Init(MYUBRR);
}

typedef union{uint32_t	u32;uint8_t	u8[4];}u32u8_4;
	
void u32u8_4b(uint32_t data,uint8_t *buff)
{
	u32u8_4 temp;
	temp.u32=data;
	memcpy(buff,temp.u8,4);
}	


bool loop;				//При true выход из главного цикл
void Setup();				//Начальные установки контроллера
void Loop(bool *loop);		//Главный цикл программы

int main(void)
{
	Setup();
	loop=true;
	while(loop)
	{
		Loop(&loop);
		//TODO:: Please write your application code
	}
}

void Setup()
{
	USART_Setup();			//Инициализация USART
}

void Loop(bool *loop)
{
	char buff[11];
	memset(buff,0x00,10);
	int32_t A=0xF12F3F4F;
	sprintf(buff,"0x%lx\n",A);
	UsartBuffTransmit((uint8_t*)buff,11);
	
	uint8_t buffint[8];
	u32u8_4b(A,buffint);
	UsartBuffTransmit(buffint,8);
	
	_delay_ms(1000);
}
sprintf(buff,"0x%lx\n",A);
http://www.avrfreaks.net/index.php?name ... c&p=293495

Re: Перевод числа в СИ

Добавлено: Чт ноя 14, 2013 08:52:32
СергейКир
Спасибо всем за советы, но всё равно не могу сделать/понять как надо.
Привожу тело самой функции:

Код: Выделить всё

//передача бита
uint8_t send_bit(uint8_t bit){
	while(//что-то A);
	if(!bit){
	// что-то B
		
	}
	return wait_end();
}


// Передача байта.
uint8_t send_byte(uint8_t byte){
	for(uint8_t i = 0; i<7; i++){
		if(!send_bit(byte & 1)) return 0;
		byte >>= 1;
	}
	return 1;
}
(что-то A и что-то B не важно)

Так вот, если я делаю так

Код: Выделить всё

send_byte(0b10101010);
// или так
send_byte(0xAA);
то там где я это жду приходит как надо 170.
Но если делаю так

Код: Выделить всё

char i=170;
// или uint8_t i=170;
send_byte(i);

то не получаю правильный результат.
Что не так?

Re: Перевод числа в СИ

Добавлено: Чт ноя 14, 2013 09:08:42
WiseLord
СергейКир писал(а): Но если делаю так

Код: Выделить всё

char i=170;
// или uint8_t i=170;
send_byte(i);

то не получаю правильный результат.
Что не так?
char - знаковый тип, от -128 до 127. А функция send_byte(uint8_t byte) - для беззнакового.
Нужно unsigned char i = 170. Хотя uint8_t i = 170 вообще-то должно работать тоже.

Re: Перевод числа в СИ

Добавлено: Чт ноя 14, 2013 09:29:16
Аlex
СергейКир писал(а):Так вот, если я делаю так

Код: Выделить всё

send_byte(0b10101010);
// или так
send_byte(0xAA);
то там где я это жду приходит как надо 170.
Но если делаю так

Код: Выделить всё

char i=170;
// или uint8_t i=170;
send_byte(i);

то не получаю правильный результат.
Что не так?
Весело тут у вас :))

Учитывая, что в начале темы:
СергейКир писал(а):Как перевести число из десятичной системы в HEX.
Число хочу передавать как строку.
ТС просто запутался и не понимает что ему нужно. Ещё и остальных путает :)

Re: Перевод числа в СИ

Добавлено: Чт ноя 14, 2013 09:38:39
СергейКир
Понимаю сарказм.
Помогите распутаться.
Не знаю как ещё объяснить.
Нужно с помощью этой функции отправить байт, аргументом должно быть число от 0 до 255 в десятичной системе.
Т.е. например 170 это в десятичной системе. Как мне его вставить в мою функцию правильно?

Re: Перевод числа в СИ

Добавлено: Чт ноя 14, 2013 09:46:27
a_skr
Причем тут HEX? HEX - это текстовое представление числа.

uint8_t i=170;
send_byte(i);

или

send_byte(170);

Так работает?

Re: Перевод числа в СИ

Добавлено: Чт ноя 14, 2013 09:49:47
СергейКир
a_skr писал(а): uint8_t i=170;
send_byte(i);
или
send_byte(170);
Так работает?
Нет. Работает только так

Код: Выделить всё

send_byte(0xAA)

Re: Перевод числа в СИ

Добавлено: Чт ноя 14, 2013 09:55:49
ploop
То есть, send_byte(170) не работает, а send_byte(0xAA) работает? :shock:
Хрень какая-то. Это же одно и то же.

Re: Перевод числа в СИ

Добавлено: Чт ноя 14, 2013 09:56:54
СергейКир
ploop писал(а): Хрень какая-то.
Я знаю.

Re: Перевод числа в СИ

Добавлено: Чт ноя 14, 2013 09:59:08
BCluster
Если бы вы обратили внимание на то, что я писал про 28 и 156, и немного подумали, возможно решение уже было бы :)
Проблема тут:

Код: Выделить всё

uint8_t send_byte(uint8_t byte)
{
   for(uint8_t i = 0; i<7; i++) ///// тут надо написать for(uint8_t i = 0; i<=7; i++)
{
      if(!send_bit(byte & 1)) return 0;
      byte >>= 1;
   }
   return 1;
}
Вы передаете 7 байт, соответственно в старшем бите может быть что угодно. В случае с константой вам везет :)