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

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

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

Сообщение ARV »

1. при чтении температуры из датчика вы обязаны считывать 8 байт + CRC, среди которых только первые 2 будут значением температуры, а остальные - всякие внутренние регистры. так вот, регистры датчиков разные для разных семейств, в частности, есть биты, которые всегда установлены в 1 и по ним можно отличить семейства - читайте даташиты. то есть переделки вашей программы должны быть минимальными.

2. листинг не смотрел, ответить не могу - подождите кого-либо, кто на это решится.

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

Мой уютный бложик... заходите!
Реклама
uk8amk
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

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

Сообщение uk8amk »

Есть же специальная тема по этому датчику.
1. Чтобы считать ROM CODE, нужно отправить соотвествующую команду

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

            if( ow_reset() == OW_PRESENCE_FAILURE)
                    return;
            ow_write_byte( DS_READ_ROM );
            for( i=0; i<8; i++ )
                    ds_code[ i ] = ow_read_byte();

            if( ow_crc(ds_code, 8) != 0 )
                    return;
3. Для этого после пуска преобразования надо ждать 750мс вместо 120 мкс.
Реклама
Аватара пользователя
shads
Опытный кот
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

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

Сообщение shads »

Заблудился в трех соснах... что не так?????

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

//гланый цикл
volatile uint16_t Data;								

int main (void)
{
	UartInit ();

	while(1){ 

		_delay_ms (500);
		uint8_t *pointer = (uint8_t*) 0x70;


		*pointer = 0x11;
		*(pointer+1) = 0xff;


		Data = *pointer; 
		Data |= (*(pointer+1) << 8);	


		UartTransmitHexInt (Data);	
		UartTransmitSymb (0x0D);
	}
}
В и тоге в Data должно получится 0xFF11... а у меня получается 0x0011...
Толи прот моросит... толи на сам деле такой результат будет (значит AVRST моросит)... ну или как обычно я мороСЮ...

Проект для AVRST4.19 и ПРОТЕУСА - внизу...

Изображение
Вложения
new.7z
(19.15 КБ) 139 скачиваний
11.png
(36.29 КБ) 837 скачиваний
Аватара пользователя
Siarzhuk
Потрогал лапой паяльник
Сообщения: 353
Зарегистрирован: Вс янв 19, 2014 22:41:55

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

Сообщение Siarzhuk »

shads писал(а):

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

//гланый цикл
[...]
		uint8_t *pointer = (uint8_t*) 0x70;
[...]

		Data |= (*(pointer+1) << 8);	
[...]
}
Всё правильно, всё справедливо. © Разыменование указателя на байт даёт нам байт, задвигаем его на восемь бит влево и остаёмся при 8-ми новеньких свежеобразовавшихся нулевых битах. Приведите результат разыменования к слову (до сдвига!) и всё получится. Либо сдвиньте Data перед OR-еньем его со вторым байтом (условия задачи чисто умозрительны - так что сменой последовательности байтов в результате, полагаю, можно пренебречь ;-)
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! ;-)
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
shads
Опытный кот
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

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

Сообщение shads »

Делаю так, результат тот же...
Спойлер

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

volatile uint16_t Data;                        

int main (void)
{
   UartInit ();

   while(1){ 

      _delay_ms (500);
      uint8_t *pointer = (uint8_t*) 0x70;

      *pointer = 0x11;
      *(pointer+1) = 0xff;

      Data = *pointer; 
      Data |= (((uint16_t)*(pointer+1)) << 8);   

      UartTransmitHexInt (Data);   
      UartTransmitSymb (0x0D);
   }
}
Хе... если выключаю оптимизацию, то все ОК... но размер становиться в 10 раз больше!!!


Кста... при выключенной оптимизации и без приведения к 16-ти разрядам - дает нормальный результат...

Siarzhuk писал(а):Либо сдвиньте Data перед OR-еньем его со вторым байтом (условия задачи чисто умозрительны - так что сменой последовательности байтов в результате, полагаю, можно пренебречь ;-)
Спасибо... помогло...
Сделал так:

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

      Data = *(pointer+1); 
	  Data <<= 8;
      Data |= *pointer;   
Реклама
Аватара пользователя
oleg110592
Друг Кота
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

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

Сообщение oleg110592 »

WinAVR 2010 с оптимизацией Os в протеусе все нормально 0xFF11
Реклама
Аватара пользователя
shads
Опытный кот
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

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

Сообщение shads »

oleg110592 писал(а):WinAVR 2010 с оптимизацией Os в протеусе все нормально 0xFF11
Странно... у меня AVRST4.19 и avr-toolchain3.3.0.710 и ведет себя так как я описал...
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

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

Сообщение WiseLord »

Всё верно.
shads писал(а):

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

Data = *pointer;
Data |= (*(pointer+1) << 8);  
Первая строчка - без вопросов, Data присваивается 0x11.
А во второй строчке *(pointer+1) - восьмибитное число, сдвинув которое 8 раз влево, Вы получаете 0. Вот и итоговое число не меняется. Результат и должен быть 0x0011.
Вот если эта строчка записывалась как-то так:

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

Data |= ((uint16_t)(*(pointer+1)) << 8);
, было бы другое дело.
Аватара пользователя
shads
Опытный кот
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

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

Сообщение 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
Результат тот же...


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

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

Сообщение Siarzhuk »

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

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

Сообщение 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);
	}
}
Аватара пользователя
levaclaus
Потрогал лапой паяльник
Сообщения: 302
Зарегистрирован: Пн янв 07, 2008 16:56:28
Откуда: Минск

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

Сообщение 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
Ум, честь и совесть. И скромность.
Сообщения: 18647
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

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

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

eeprom unsigned int calibrate_eeprom =0xF424;

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

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

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

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

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

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

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

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

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

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

Сообщение levaclaus »

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

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

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

calibrate=calibrate_eeprom;

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

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

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

Сообщение oleg110592 »

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

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

Сообщение levaclaus »

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

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

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

Сообщение ARV »

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

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

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

Сообщение levaclaus »

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

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

Сообщение levaclaus »

oleg110592 писал(а):if (0xF618<calibrate<0xF230) заменить на: if ((calibrate > 0xF618) && (calibrate < 0xF230))
любопытно, почему моя конструкция не работает?
Ответить

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