Вопросы по С/С++ (СИ)

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18788
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

просто КОТ писал(а):sprintf (res, "%s %d", "L=", light);
во-первых, так не надо делать. надо делать так: sprintf (res, "L= %d", light);
во-вторых, sprintf сожрет минимум 1,5 килобайта памяти. ну, 1,2 килобайта, если повезет. поэтому обходитесь itoa
в-третьих, можно попытаться уменьшить прожорливсть sprintf-а за счет отказа от некоторых возможностей при помощи опции компилятора -Wl,-u,vfprintf -lprintf_min подробнее читайте здесь: http://www.simple-devices.ru/attachment ... 1-2010.pdf
в-четрвертых, про itoa можно прочесть здесь: http://www.simple-devices.ru/attachment ... 2_2010.pdf
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Держит паяльник хвостом
Аватара пользователя
Сообщения: 908
Зарегистрирован: Вс май 23, 2010 13:55:42
Откуда: Украина, Александрия

Сообщение Apparatchik »

просто КОТ писал(а):Эм... Википедия сказала
Там же в википедии в низу есть реализация попроще
Спойлер

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

/* itoa:  конвертируем n в символы в s */
void itoa(int n, char s[]) {
	int i, sign;
	char c;

	if ((sign = n) < 0) /* записываем знак */
		n = -n; /* делаем n положительным числом */
	i = 0;
	do { /* генерируем цифры в обратном порядке */
		s[i++] = n % 10 + '0'; /* берем следующую цифру */
	} while ((n /= 10) > 0); /* удаляем */
	if (sign < 0)
		s[i++] = '-';
	s[i] = '\0';

	/*переворачиваем строку*/
	for (i = 0, sign = strlen(s) - 1; i < sign; i++, sign--) {
		c = s[i];
		s[i] = s[sign];
		s[sign] = c;
	}
}
«И всё-таки она вертится!»
Реклама
Друг Кота
Аватара пользователя
Сообщения: 12364
Зарегистрирован: Пт дек 17, 2010 15:07:50
Откуда: Крымский Федеральный Округ

Сообщение просто КОТ »

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

if(send) { 
         itoa (light, res, 10);
		 res[4]='L';
		 res[3]='=';
         Out_Str(res); mUart_Putch(0x0D);
         send=0;
}
Так стало слегка лучше. выводит значение light. Но совершенно игнорирует L=
Изображение
И ты врёшь!!! © Vladisman
Изображение
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

Ерунда какая-то написана.
Допустим, ваш ligth = 5;
Тогда после itoa в строке res будет "5". Т.е., res[0] = '5', а res[1] = '\0'. Это и будет выводиться, и по барабану, что вы там пишете в остальные байты массива res (тем более, не в нужном порядке), так как символ конца строки - в позиции [1].
Можно попробовать со смещением писать:

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

res[0]='L';
res[1]='=';
itoa (light, &res[2], 10); // Или itoa (light, res + 2, 10); - должно записать в res, начиная с res[2]
, но надо проверять, не будет ли ошибки.
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
ks0
Прорезались зубы
Аватара пользователя
Сообщения: 238
Зарегистрирован: Чт фев 28, 2013 14:16:10

Сообщение ks0 »

Да отдельно строки вывести, чтоб не скливать их

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

Out_Str("L=");
Out_Str(res);
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18788
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

однахрень не заменяет другую. надо делать так:

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

Out_Str("L=");
Out_Str(res);
Out_Str("\n");
опередил, щустрик :)))
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Друг Кота
Аватара пользователя
Сообщения: 12364
Зарегистрирован: Пт дек 17, 2010 15:07:50
Откуда: Крымский Федеральный Округ

Сообщение просто КОТ »

UART рукописный, причём не мной. Функцию Out_Str не выходит вызывать N раз подряд. Потому вот чего придумал:

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

if(send) { 
itoa (light, res, 10); 
res[2]=res[0];
res[3]=res[1];
res[0]='L';
res[1]='=';
res[4]='\0';
Out_Str(res); mUart_Putch(0x0D);
         send=0;
}
работает.
Изображение
И ты врёшь!!! © Vladisman
Изображение
Контактная информация:
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18788
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

просто КОТ писал(а):UART рукописный, причём не мной. Функцию Out_Str не выходит вызывать N раз подряд.
это как вообще возможно?! что ж такое нужно написать в функции, чтобы ее нельзя было вызвать несколько раз подряд?! :shock:
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 12364
Зарегистрирован: Пт дек 17, 2010 15:07:50
Откуда: Крымский Федеральный Округ

Сообщение просто КОТ »

Ну она вроде как сразу после выполнения уходит в себя на некоторое время.
Изображение
И ты врёшь!!! © Vladisman
Изображение
Контактная информация:
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18788
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

да пусть она хоть в гости уходит - потом-то возвращается? вы же не останавливаете исполнение программы ПОСЛЕ обращения к этой функции? так почему в качестве продолжения работы нельзя СНОВА к ней возвратиться? не понимаю... тем более что наверняка отправка в USART у вас идет в главном ЦИКЛЕ, т.е. эта функция так или иначе вызывается МНОГОКРАТНО...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
ks0
Прорезались зубы
Аватара пользователя
Сообщения: 238
Зарегистрирован: Чт фев 28, 2013 14:16:10

Сообщение ks0 »

просто КОТ писал(а):UART рукописный, причём не мной. Функцию Out_Str не выходит вызывать N раз подряд.
Эта функция выглядит примерно так

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

void Out_Str(char* p)
{
	while(*p)
	{
		while(!(UCSRA & (1<<UDRE)));
		UDR=*p;
		p++;
	}
}
И усе! Никаким ограничений по несколько раз подряд там неоткуда взяться
Нашел транзистор. Понюхал.
Аватара пользователя
Сообщения: 160
Зарегистрирован: Пн сен 05, 2011 10:03:06
Откуда: Тула

Сообщение paskal »

Помогите справиться с особенностями кейла. Надо перевести программу с асма на Си. МК - AT89S52. В исходной программе было детектирование резета следующим образом: В некоторую определенную область ОЗУ пишется определенная сигнатура. При старте этот кусок памяти проверяется на сравнение с сигнатурой. Если совпадение, то считается что процессор стартовал после подачи резета. Если несовпадение то был старт по включению питания.
Так вот, программа на си при старте заполняет ОЗУ нулями, затирая сигнатуру. Как у Кейла отключить эту фичу?

И второй вопрос.
В исходной программе использовалось очень много битовых флагов. Позволяет ли Си пользоваться битовыми флагами. То есть чтоб на 1 флаг тратился бит, а не байт?
Если бы на станции "Мир" стояли Винды, она бы еще висела и висела...
Прорезались зубы
Аватара пользователя
Сообщения: 202
Зарегистрирован: Пн сен 26, 2011 13:48:25
Откуда: Харьков

Сообщение slavokhire5 »

paskal писал(а):В исходной программе использовалось очень много битовых флагов. Позволяет ли Си пользоваться битовыми флагами. То есть чтоб на 1 флаг тратился бит, а не байт?
Вот пример работы с битами:

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


#define F_RED	0x01
#define F_GREEN	0x02
#define F_BLUE	0x04

volatile uint8_t flags;

void main ()	
{
	flags |= F_RED;			// set flag "red". now flags == 0x01

	// do something
	flags |= F_BLUE;		// set flag "blue". now flags == 0x05
	
	// do something
	flags &= ~RED;			// reset flag "red". now flags == 0x04
}
Еще можно работать через битовые поля, но я этим как-то не пользуюсь
Осилит дорогу идущий
--------------------------
Пишу на Си за еду
Нашел транзистор. Понюхал.
Аватара пользователя
Сообщения: 160
Зарегистрирован: Пн сен 05, 2011 10:03:06
Откуда: Тула

Сообщение paskal »

slavokhire5 писал(а):Еще можно работать через битовые поля, но я этим как-то не пользуюсь
Так интересуют как раз битовые поля.
Дело в том что в исходной программе аж несколько десятков битовых переменных. Если реализовывать их арифметикой, то получится такая каша... Тогда получается что на ассемблере удобнее чем на сях.
Если бы на станции "Мир" стояли Винды, она бы еще висела и висела...
ks0
Прорезались зубы
Аватара пользователя
Сообщения: 238
Зарегистрирован: Чт фев 28, 2013 14:16:10

Сообщение ks0 »

paskal писал(а):
slavokhire5 писал(а):Еще можно работать через битовые поля, но я этим как-то не пользуюсь
Так интересуют как раз битовые поля.
Так они гуглятся http://www.c-cpp.ru/books/bitovye-polya
В структурах можно использовать
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18788
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

Разве у этого МК нет специального регистра, биты которого сигнализируют о том, что сброс был по подаче питания? По-моему, есть...и извращения с сигнатурами будут лишними.

Кейл позволяет создавать и использовать битовые переменные.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Нашел транзистор. Понюхал.
Аватара пользователя
Сообщения: 160
Зарегистрирован: Пн сен 05, 2011 10:03:06
Откуда: Тула

Сообщение paskal »

ks0 писал(а):Так они гуглятся http://www.c-cpp.ru/books/bitovye-polya
В структурах можно использовать
Эээ... в 51-х контроллерах битовые поля это такая область памяти с адреса 20h где имеется аппаратный доступ к отдельным битам по адресу бита, без двоичной арифметики.
Но насчет гугля вы правы. Вот я нашел ответ: http://onembedding.bialix.com/tools/keil/faq/#sbit
Так что этот вопрос снят.
ARV писал(а):Разве у этого МК нет специального регистра, биты которого сигнализируют о том, что сброс был по подаче питания? По-моему, есть...и извращения с сигнатурами будут лишними.
Ну если честно то я бы с удовольствием отказался бы от сигнатур. Но я такого регистра у at89s52 не знаю.
Если бы на станции "Мир" стояли Винды, она бы еще висела и висела...
ks0
Прорезались зубы
Аватара пользователя
Сообщения: 238
Зарегистрирован: Чт фев 28, 2013 14:16:10

Сообщение ks0 »

Ну я не знаю какие там еще могут быть особенности, но в Си если переменную определить, но не присвоить ей значение, то никакого обнуления ее не будет. Т.е. это должно работать

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

int n;
if(n==0x8888) 
{ 
   /* был вызыван reset */ 
}
else 
{
   /* было отключение питания */
   n=0x8888;
}
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18788
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

paskal писал(а):
ARV писал(а):Разве у этого МК нет специального регистра, биты которого сигнализируют о том, что сброс был по подаче питания? По-моему, есть...и извращения с сигнатурами будут лишними.
Ну если честно то я бы с удовольствием отказался бы от сигнатур. Но я такого регистра у at89s52 не знаю.
это очень плохо, что вы беретесь программировать МК, не изучив его внутреннее устройство. изучайте регистр PCON и конкретно флаг (бит) этого регистра POF
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18788
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

ks0 писал(а):Ну я не знаю какие там еще могут быть особенности, но в Си если переменную определить, но не присвоить ей значение, то никакого обнуления ее не будет.
верно только для локальных не статических переменных функций. глобальные (статические) переменные по умолчанию обнуляются.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Ответить

Вернуться в «Разные вопросы по МК»