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

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить
Опытный кот
Аватара пользователя
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

Сообщение shads »

WiseLord писал(а):А во второй строчке *(pointer+1) - восьмибитное число, сдвинув которое 8 раз влево, Вы получаете 0. Вот и итоговое число не меняется. Результат и должен быть 0x0011.
На сам деле, как я понял не совсем так...
Дело в том, что если слева от "=" стоит 16-ти разрядная переменная, то справа, выражения автоматически приводятся к 16-ти разрядам...
Так что в данном случае приведение справа к 16-ти разрядам - необязательно...
WiseLord писал(а):Вот если эта строчка записывалась как-то так:

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

Data |= ((uint16_t)(*(pointer+1)) << 8);
, было бы другое дело.
Пробовал так, тут: http://radiokot.ru/forum/viewtopic.php? ... 1#p2252521
Результат тот же...


В общем, как я понял, не стоит сдвигать результат чтения по указателю... т.к. компилятор это иногда решает не верно...
Лучше сначала прочитать в переменную старшее значение, потом переменную сдвинуть, а потом добавить младшее значение...
В итоге я так и сделал...
Реклама
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 353
Зарегистрирован: Вс янв 19, 2014 22:41:55

Сообщение Siarzhuk »

shads писал(а):На сам деле, как я понял не совсем так...
Дело в том, что если слева от "=" стоит 16-ти разрядная переменная, то справа, выражения автоматически приводятся к 16-ти разрядам...
Так что в данном случае приведение справа к 16-ти разрядам - необязательно...
Неявное преобразование в данном случае возможно либо при присваивании - когда уже поздно, либо promote to int в арифметической операции справа - которой там вроде как и не наблюдается (а есть побитовая).
В любом случае наблюдаемая катастрофическая разница на выходе оптимизированного и неоптимизированного вариантов лишает дискуссию о стандартности того или иного решения всякой почвы кроме эмпирического "так не ходи", да. ;-)
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! ;-)
Реклама
Друг Кота
Аватара пользователя
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Сообщение oleg110592 »

так не проще ли будет:

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

//главный цикл
volatile uint16_t Data;
uint16_t pppp;
uint16_t *pointer;

int main (void)
{
	UartInit ();
	while(1){

		_delay_ms (500);
		pppp = 0xFF11;
		pointer = &pppp;
		Data = *pointer;
		UartTransmitHexInt (Data);
		UartTransmitSymb (0x0D);
	}
}
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 302
Зарегистрирован: Пн янв 07, 2008 16:56:28
Откуда: Минск

Сообщение levaclaus »

есть две константы

unsigned int calibrate;

eeprom unsigned char calibrate_eeprom_H=0xF4;
eeprom unsigned char calibrate_eeprom_L=0x24;


Как их привести к такому виду?
calibrate=0xF424;

Обратно и как я понимаю так
calibrate_eeprom_H=calibrate >> 8;
calibrate_eeprom_L=calibrate & 0xff;
Реклама
Эиком - электронные компоненты и радиодетали
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18788
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

а в чем проблема сразу сделать, как положено?

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

eeprom unsigned int calibrate_eeprom =0xF424;

calibrate = calibrate_eeprom;
если компилятор понимает префикс eeprom, то никаких проблем быть не должно. если не понимает, то придется как-то так делать считывание:

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

calibrate = eeprom_read_int(&calibrate_eeprom);
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Модератор
Аватара пользователя
Сообщения: 4618
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

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

Ну и в другую сторону также, только в обратном направлении.

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

calibrate = (calibrate_eeprom_H<<8) | calibrate_eeprom_L ;
Если компилятор достаточно умный, то он просто переместит байты по нужным адресам без всяких лишних телодвижений.
Реклама
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 302
Зарегистрирован: Пн янв 07, 2008 16:56:28
Откуда: Минск

Сообщение levaclaus »

тогда я что-то не понимаю

при первом запуске проверяю содержимое епрома, если оно больше-меньше нужного интервала - записываю туда начальное значение 0xF424. Дальше захожу в "настройки", изменяю это значение например на 0xF420, считываю программатором епром - вижу там число 0xF420. Т.е. константа изменилась и записалась.

Дальше самое интересное, перезапускаю устройство, в епром записывается начальное значение 0xF424, хотя там уже лежало число 0xF420

calibrate=calibrate_eeprom;

if (0xF618<calibrate<0xF230) {
calibrate=0xF424;
calibrate_eeprom=calibrate;
};

OCR1AH=calibrate >> 8;
OCR1AL=calibrate & 0xff;
Друг Кота
Аватара пользователя
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Сообщение oleg110592 »

if (0xF618<calibrate<0xF230) заменить на: if ((calibrate > 0xF618) && (calibrate < 0xF230))
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 302
Зарегистрирован: Пн янв 07, 2008 16:56:28
Откуда: Минск

Сообщение levaclaus »

if ((calibrate > 0xF618) && (calibrate < 0xF230)) {
calibrate=0xF424;
calibrate_eeprom=0xF424;
};

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

Сообщение ARV »

не &&, а || - у вас ведь обновление eeprom должно происходить если или больше, или меньше...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 302
Зарегистрирован: Пн янв 07, 2008 16:56:28
Откуда: Минск

Сообщение levaclaus »

ARV писал(а):не &&, а || - у вас ведь обновление eeprom должно происходить если или больше, или меньше...
да, точно
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 302
Зарегистрирован: Пн янв 07, 2008 16:56:28
Откуда: Минск

Сообщение levaclaus »

oleg110592 писал(а):if (0xF618<calibrate<0xF230) заменить на: if ((calibrate > 0xF618) && (calibrate < 0xF230))
любопытно, почему моя конструкция не работает?
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18788
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

ну сами поглядите:
1. calibrate у вас равно 0xF420
2. так как операции больше и меньше имеют одинаковый приоритет, выполняются они слева направо, т.е. как бы вот так ((0xF618<calibrate)<OxF230)
3. 0xF618<calibrate ----> 0xF618 < 0xF420. это выражение ЛОЖНО, т.е. имеет результат 0
4. теперь этот результат сравнивается с другим пределом: 0 < 0xF230 - это выражение всегда истинно, т.е. есть условие для срабатывания if
5. if срабатывает и перезаписывает вашу переменную...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 302
Зарегистрирован: Пн янв 07, 2008 16:56:28
Откуда: Минск

Сообщение levaclaus »

ARV писал(а):ну сами поглядите:
1. calibrate у вас равно 0xF420
2. так как операции больше и меньше имеют одинаковый приоритет, выполняются они слева направо, т.е. как бы вот так ((0xF618<calibrate)<OxF230)
3. 0xF618<calibrate ----> 0xF618 < 0xF420. это выражение ЛОЖНО, т.е. имеет результат 0
4. теперь этот результат сравнивается с другим пределом: 0 < 0xF230 - это выражение всегда истинно, т.е. есть условие для срабатывания if
5. if срабатывает и перезаписывает вашу переменную...
просто
Когда-то давно и не правда я писал так, девайс работает и сейчас.

if (1500<calibrate_eeprom<500) {
calibrate_eeprom=1000;
};


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

Сообщение ARV »

тогда в чем вопрос? если работает, значит, вы все правильно делаете. а если не работает - не правильно.
только если делаете правильно, то работает всегда, а когда не правильно - иной раз, как фишка ляжет. чувствуете разницу? ;)
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Нашел транзистор. Понюхал.
Аватара пользователя
Сообщения: 183
Зарегистрирован: Ср янв 25, 2012 07:26:40

Сообщение acckyiboxxx »

Здравствуйте где-бы мне почитать про следующие способы записи кода :

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

PORTB |= (0<<PB5)|(0<<PB6)|(0<<PB7);
пользоваться такой записью умею тупо зазубрив ее но хотелось-бы еще понимать , а на данный момент такая запись вызывает в моем мозгу следующий бред "порт б или равно лапа5=0 или равно лапа6=0 или равно лапа7=0 " хотя на самом деле это просто установка нужных бит порта, в данном случае в нули

и второй вопрос , почему когда я использую преобразование типов переменных размер скомпиленного файла увеличиваеться просто баснословно не стану приводить весь код но когда регистру присваиваю значение следующим образом :

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

OCR3C = 0xff;

то размер скомпиленного бинаря 350 байт

но когда пытаюсь работать с процентами и переволить тип float в char слкдующим образом

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

OCR3C = (char) (hot * 2.55);
то получаю аж 3130 байт при этом ничего кроме этой строчки в коде не меняю (перменная hot имеет тип float)

для своих проектов юзаю avr-gcc
Друг Кота
Аватара пользователя
Сообщения: 4779
Зарегистрирован: Сб апр 02, 2011 12:40:46
Откуда: Минск

Сообщение Леонид Иванович »

acckyiboxxx писал(а):хотя на самом деле это просто установка нужных бит порта, в данном случае в нули
Запись абсолютно бессмысленная, поэтому Вы ее не понимаете. Приведенная строчка не делает ровным счетом ничего - логическое "или" с нулем не меняет значения.
acckyiboxxx писал(а):то получаю аж 3130 байт при этом ничего кроме этой строчки в коде не меняю (перменная hot имеет тип float
А чему тут удивляться? Подключаются библиотечные функции работы с плавающей точкой.
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

Стоит добавить, что AVR - это всё-таки восьмибитный целочисленный контроллер. Операции с другими числами - 16-битнными и 32-битными целыми и, особенно, дробными - разворачиваются компилятором в довольно сложные и выполняющиеся гораздо дольше конструкции над теми же целыми 8-битными. Так что размер кода вырастает катастрофически.
Кстати, подобное наблюдается и при использовании многих функций из той же stdlib (разные printf-ы и прочие).
Контактная информация:
Нашел транзистор. Понюхал.
Аватара пользователя
Сообщения: 183
Зарегистрирован: Ср янв 25, 2012 07:26:40

Сообщение acckyiboxxx »

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

Сообщение ARV »

а можно я ткну? ;)
вообще-то, книг по языку Си - воз и маленькая тележка, если в гугле не забанили, то найти проще, чем нос утереть...
однако, если книжки искать и читать лень, могу предложить небольшие краткие советы лично от себя: http://arv.radioliga.com/content/category/6/33/49/
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

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

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