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

Обсуждаем контроллеры компании Atmel.
Ответить
Открыл глаза
Сообщения: 55
Зарегистрирован: Чт май 30, 2013 15:05:07

Сообщение СергейКир »

Здравствуйте.
Язык Си, 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);
и не работает. Что не так в переводе? Или всё не так?
Заранее спасибо.
Реклама
Открыл глаза
Сообщения: 73
Зарегистрирован: Ср июн 15, 2011 02:22:15

Сообщение vovksextra »

Достаточно сделать так:

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

int i=25;
send_byte(i);
Контактная информация:
Реклама
Открыл глаза
Сообщения: 55
Зарегистрирован: Чт май 30, 2013 15:05:07

Сообщение СергейКир »

Спасибо. Пробую...
Прошиваю...
Не получилось. Отправляю к примеру 28 приходит 156. А если 0x1С то 28, как и надо.
Всё таки, что не так с моим переводом??? (см. выше)
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1518
Зарегистрирован: Пт дек 28, 2012 21:56:46
Откуда: St. Petersburg

Сообщение blackx »

Давайте все-таки весь код целиком.

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

И определитесь, хотите вы число передавать как число или число передавать как строку.
Изображение only pure true norwegian blackx Изображение
Реклама
Эиком - электронные компоненты и радиодетали
Открыл глаза
Сообщения: 55
Зарегистрирован: Чт май 30, 2013 15:05:07

Сообщение СергейКир »

blackx писал(а):Давайте все-таки весь код целиком.
И определитесь, хотите вы число передавать как число или число передавать как строку.
Код смогу уже только завтра.
Число хочу передавать как строку.
Реклама
Встал на лапы
Сообщения: 125
Зарегистрирован: Вс мар 01, 2009 20:41:19

Сообщение xVekx »

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

char buff[10];
memset(buff,0x00,10);
uint32_t A=400;
sprintf(buff,"%x\n",A);
send_byte(s);
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2512
Зарегистрирован: Пн апр 06, 2009 19:33:29
Откуда: Молдова, Кишинев

Сообщение BCluster »

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

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

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

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

Насчет "что не так с моим переводом"... все не так
функция, как я понимаю передает 1 байт
даже если бы правильно был написан этот printf, число в хексе в виде строки это 2 байта
Контактная информация:
Собутыльник Кота
Аватара пользователя
Сообщения: 2512
Зарегистрирован: Пн апр 06, 2009 19:33:29
Откуда: Молдова, Кишинев

Сообщение BCluster »

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

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

если передаем char то и объявляйте i как char. Мож компилятор чет себе придумал на этой почве
Контактная информация:
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1518
Зарегистрирован: Пт дек 28, 2012 21:56:46
Откуда: St. Petersburg

Сообщение 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);
Изображение only pure true norwegian blackx Изображение
Собутыльник Кота
Аватара пользователя
Сообщения: 2512
Зарегистрирован: Пн апр 06, 2009 19:33:29
Откуда: Молдова, Кишинев

Сообщение BCluster »

blackx, судя по постам ТС, что передача типа send_byte(0xFF) его устраивает, то ТС сам не знает что он хочет в итоге получить :))
Контактная информация:
Встал на лапы
Сообщения: 125
Зарегистрирован: Вс мар 01, 2009 20:41:19

Сообщение 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
Открыл глаза
Сообщения: 55
Зарегистрирован: Чт май 30, 2013 15:05:07

Сообщение СергейКир »

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

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

//передача бита
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);

то не получаю правильный результат.
Что не так?
Друг Кота
Аватара пользователя
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение 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 вообще-то должно работать тоже.
Контактная информация:
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

СергейКир писал(а):Так вот, если я делаю так

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

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

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

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

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

Учитывая, что в начале темы:
СергейКир писал(а):Как перевести число из десятичной системы в HEX.
Число хочу передавать как строку.
ТС просто запутался и не понимает что ему нужно. Ещё и остальных путает :)
Контактная информация:
Открыл глаза
Сообщения: 55
Зарегистрирован: Чт май 30, 2013 15:05:07

Сообщение СергейКир »

Понимаю сарказм.
Помогите распутаться.
Не знаю как ещё объяснить.
Нужно с помощью этой функции отправить байт, аргументом должно быть число от 0 до 255 в десятичной системе.
Т.е. например 170 это в десятичной системе. Как мне его вставить в мою функцию правильно?
Вымогатель припоя
Сообщения: 630
Зарегистрирован: Пн июн 14, 2010 13:07:29
Откуда: Жуковский

Сообщение a_skr »

Причем тут HEX? HEX - это текстовое представление числа.

uint8_t i=170;
send_byte(i);

или

send_byte(170);

Так работает?
Открыл глаза
Сообщения: 55
Зарегистрирован: Чт май 30, 2013 15:05:07

Сообщение СергейКир »

a_skr писал(а): uint8_t i=170;
send_byte(i);
или
send_byte(170);
Так работает?
Нет. Работает только так

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

send_byte(0xAA)
Модератор
Аватара пользователя
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Сообщение ploop »

То есть, send_byte(170) не работает, а send_byte(0xAA) работает? :shock:
Хрень какая-то. Это же одно и то же.
Открыл глаза
Сообщения: 55
Зарегистрирован: Чт май 30, 2013 15:05:07

Сообщение СергейКир »

ploop писал(а): Хрень какая-то.
Я знаю.
Собутыльник Кота
Аватара пользователя
Сообщения: 2512
Зарегистрирован: Пн апр 06, 2009 19:33:29
Откуда: Молдова, Кишинев

Сообщение 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 байт, соответственно в старшем бите может быть что угодно. В случае с константой вам везет :)
Контактная информация:
Ответить

Вернуться в «AVR»