Вопросы по С/С++ (СИ)
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18649
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
1. при чтении температуры из датчика вы обязаны считывать 8 байт + CRC, среди которых только первые 2 будут значением температуры, а остальные - всякие внутренние регистры. так вот, регистры датчиков разные для разных семейств, в частности, есть биты, которые всегда установлены в 1 и по ним можно отличить семейства - читайте даташиты. то есть переделки вашей программы должны быть минимальными.
2. листинг не смотрел, ответить не могу - подождите кого-либо, кто на это решится.
3. запустите первое преобразование до входа в главный цикл и дождитесь, пока преобразование кончится. в этом случае ваш главный цикл отработает уже с корректными показаниями температуры.
2. листинг не смотрел, ответить не могу - подождите кого-либо, кто на это решится.
3. запустите первое преобразование до входа в главный цикл и дождитесь, пока преобразование кончится. в этом случае ваш главный цикл отработает уже с корректными показаниями температуры.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Реклама
-
uk8amk
- Поставщик валерьянки для Кота
- Сообщения: 2222
- Зарегистрирован: Вт ноя 27, 2007 11:32:06
- Откуда: Tashkent
Re: Вопросы по С/С++ (СИ)
Есть же специальная тема по этому датчику.
1. Чтобы считать ROM CODE, нужно отправить соотвествующую команду
3. Для этого после пуска преобразования надо ждать 750мс вместо 120 мкс.
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;Re: Вопросы по С/С++ (СИ)
Заблудился в трех соснах... что не так?????
В и тоге в Data должно получится 0xFF11... а у меня получается 0x0011...
Толи прот моросит... толи на сам деле такой результат будет (значит AVRST моросит)... ну или как обычно я мороСЮ...
Проект для AVRST4.19 и ПРОТЕУСА - внизу...

Код: Выделить всё
//гланый цикл
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);
}
}Толи прот моросит... толи на сам деле такой результат будет (значит AVRST моросит)... ну или как обычно я мороСЮ...
Проект для AVRST4.19 и ПРОТЕУСА - внизу...
Re: Вопросы по С/С++ (СИ)
Всё правильно, всё справедливо. © Разыменование указателя на байт даёт нам байт, задвигаем его на восемь бит влево и остаёмся при 8-ми новеньких свежеобразовавшихся нулевых битах. Приведите результат разыменования к слову (до сдвига!) и всё получится. Либо сдвиньте Data перед OR-еньем его со вторым байтом (условия задачи чисто умозрительны - так что сменой последовательности байтов в результате, полагаю, можно пренебречьshads писал(а):Код: Выделить всё
//гланый цикл [...] uint8_t *pointer = (uint8_t*) 0x70; [...] Data |= (*(pointer+1) << 8); [...] }
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
Re: Вопросы по С/С++ (СИ)
Делаю так, результат тот же...
Хе... если выключаю оптимизацию, то все ОК... но размер становиться в 10 раз больше!!!
Кста... при выключенной оптимизации и без приведения к 16-ти разрядам - дает нормальный результат...
Сделал так:
Спойлер
Код: Выделить всё
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);
}
}
Кста... при выключенной оптимизации и без приведения к 16-ти разрядам - дает нормальный результат...
Спасибо... помогло...Siarzhuk писал(а):Либо сдвиньте Data перед OR-еньем его со вторым байтом (условия задачи чисто умозрительны - так что сменой последовательности байтов в результате, полагаю, можно пренебречь
Сделал так:
Код: Выделить всё
Data = *(pointer+1);
Data <<= 8;
Data |= *pointer;
- Реклама
- oleg110592
- Друг Кота
- Сообщения: 3832
- Зарегистрирован: Сб сен 10, 2011 17:46:25
Re: Вопросы по С/С++ (СИ)
WinAVR 2010 с оптимизацией Os в протеусе все нормально 0xFF11
Re: Вопросы по С/С++ (СИ)
Странно... у меня AVRST4.19 и avr-toolchain3.3.0.710 и ведет себя так как я описал...oleg110592 писал(а):WinAVR 2010 с оптимизацией Os в протеусе все нормально 0xFF11
- WiseLord
- Друг Кота
- Сообщения: 4905
- Зарегистрирован: Чт апр 11, 2013 11:19:59
- Откуда: Минск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Всё верно.
А во второй строчке *(pointer+1) - восьмибитное число, сдвинув которое 8 раз влево, Вы получаете 0. Вот и итоговое число не меняется. Результат и должен быть 0x0011.
Вот если эта строчка записывалась как-то так:, было бы другое дело.
Первая строчка - без вопросов, Data присваивается 0x11.shads писал(а):Код: Выделить всё
Data = *pointer; Data |= (*(pointer+1) << 8);
А во второй строчке *(pointer+1) - восьмибитное число, сдвинув которое 8 раз влево, Вы получаете 0. Вот и итоговое число не меняется. Результат и должен быть 0x0011.
Вот если эта строчка записывалась как-то так:
Код: Выделить всё
Data |= ((uint16_t)(*(pointer+1)) << 8);Re: Вопросы по С/С++ (СИ)
На сам деле, как я понял не совсем так...WiseLord писал(а):А во второй строчке *(pointer+1) - восьмибитное число, сдвинув которое 8 раз влево, Вы получаете 0. Вот и итоговое число не меняется. Результат и должен быть 0x0011.
Дело в том, что если слева от "=" стоит 16-ти разрядная переменная, то справа, выражения автоматически приводятся к 16-ти разрядам...
Так что в данном случае приведение справа к 16-ти разрядам - необязательно...
Пробовал так, тут: http://radiokot.ru/forum/viewtopic.php? ... 1#p2252521WiseLord писал(а):Вот если эта строчка записывалась как-то так:, было бы другое дело.Код: Выделить всё
Data |= ((uint16_t)(*(pointer+1)) << 8);
Результат тот же...
В общем, как я понял, не стоит сдвигать результат чтения по указателю... т.к. компилятор это иногда решает не верно...
Лучше сначала прочитать в переменную старшее значение, потом переменную сдвинуть, а потом добавить младшее значение...
В итоге я так и сделал...
Re: Вопросы по С/С++ (СИ)
Неявное преобразование в данном случае возможно либо при присваивании - когда уже поздно, либо promote to int в арифметической операции справа - которой там вроде как и не наблюдается (а есть побитовая).shads писал(а):На сам деле, как я понял не совсем так...
Дело в том, что если слева от "=" стоит 16-ти разрядная переменная, то справа, выражения автоматически приводятся к 16-ти разрядам...
Так что в данном случае приведение справа к 16-ти разрядам - необязательно...
В любом случае наблюдаемая катастрофическая разница на выходе оптимизированного и неоптимизированного вариантов лишает дискуссию о стандартности того или иного решения всякой почвы кроме эмпирического "так не ходи", да.
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
- oleg110592
- Друг Кота
- Сообщения: 3832
- Зарегистрирован: Сб сен 10, 2011 17:46:25
Re: Вопросы по С/С++ (СИ)
так не проще ли будет:
Код: Выделить всё
//главный цикл
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: Вопросы по С/С++ (СИ)
есть две константы
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;
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
- Ум, честь и совесть. И скромность.
- Сообщения: 18649
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
а в чем проблема сразу сделать, как положено?
если компилятор понимает префикс eeprom, то никаких проблем быть не должно. если не понимает, то придется как-то так делать считывание:
Код: Выделить всё
eeprom unsigned int calibrate_eeprom =0xF424;
calibrate = calibrate_eeprom;Код: Выделить всё
calibrate = eeprom_read_int(&calibrate_eeprom);если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Ну и в другую сторону также, только в обратном направлении.
Если компилятор достаточно умный, то он просто переместит байты по нужным адресам без всяких лишних телодвижений.
Код: Выделить всё
calibrate = (calibrate_eeprom_H<<8) | calibrate_eeprom_L ;
- levaclaus
- Потрогал лапой паяльник
- Сообщения: 302
- Зарегистрирован: Пн янв 07, 2008 16:56:28
- Откуда: Минск
Re: Вопросы по С/С++ (СИ)
тогда я что-то не понимаю
при первом запуске проверяю содержимое епрома, если оно больше-меньше нужного интервала - записываю туда начальное значение 0xF424. Дальше захожу в "настройки", изменяю это значение например на 0xF420, считываю программатором епром - вижу там число 0xF420. Т.е. константа изменилась и записалась.
Дальше самое интересное, перезапускаю устройство, в епром записывается начальное значение 0xF424, хотя там уже лежало число 0xF420
calibrate=calibrate_eeprom;
if (0xF618<calibrate<0xF230) {
calibrate=0xF424;
calibrate_eeprom=calibrate;
};
OCR1AH=calibrate >> 8;
OCR1AL=calibrate & 0xff;
при первом запуске проверяю содержимое епрома, если оно больше-меньше нужного интервала - записываю туда начальное значение 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: Вопросы по С/С++ (СИ)
if (0xF618<calibrate<0xF230) заменить на: if ((calibrate > 0xF618) && (calibrate < 0xF230))
- levaclaus
- Потрогал лапой паяльник
- Сообщения: 302
- Зарегистрирован: Пн янв 07, 2008 16:56:28
- Откуда: Минск
Re: Вопросы по С/С++ (СИ)
if ((calibrate > 0xF618) && (calibrate < 0xF230)) {
calibrate=0xF424;
calibrate_eeprom=0xF424;
};
код не выполняется, содержимое eeprom не меняется
calibrate=0xF424;
calibrate_eeprom=0xF424;
};
код не выполняется, содержимое eeprom не меняется
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18649
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
не &&, а || - у вас ведь обновление eeprom должно происходить если или больше, или меньше...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- levaclaus
- Потрогал лапой паяльник
- Сообщения: 302
- Зарегистрирован: Пн янв 07, 2008 16:56:28
- Откуда: Минск
Re: Вопросы по С/С++ (СИ)
да, точноARV писал(а):не &&, а || - у вас ведь обновление eeprom должно происходить если или больше, или меньше...
- levaclaus
- Потрогал лапой паяльник
- Сообщения: 302
- Зарегистрирован: Пн янв 07, 2008 16:56:28
- Откуда: Минск
Re: Вопросы по С/С++ (СИ)
любопытно, почему моя конструкция не работает?oleg110592 писал(а):if (0xF618<calibrate<0xF230) заменить на: if ((calibrate > 0xF618) && (calibrate < 0xF230))


