|
|
  |
Что означает этот код? |
|
|
|
Mar 9 2014, 07:11
|
Частый гость
 
Группа: Участник
Сообщений: 163
Регистрация: 25-10-10
Из: Ростовская обл.
Пользователь №: 60 401

|
Цитата(aaarrr @ Mar 9 2014, 08:09)  По приведенному к типу char адресу переменной записать ничего нельзя, это и не скомпилируется. Это примерно как написать: 5 = 10; Понял. Да, мог бы конечно и сам понять что в адрес ничего не запишешь, можно записать по указателю адреса. Цитата Переменная temp должна иметь тип как минимум short, чтобы в нее поместилось два char'а. Но short вроде бы тип для целых чисел, а у меня переменная Temp потом будет преобразовывать свое содержимое из двух байт двоичного кода в десятичные показания температуры с точностью до десятых. И сама функция будет возвращать такое число. Поэтому я и спросил за float, может лучше это тип использовать?
Сообщение отредактировал RW6MKA - Mar 9 2014, 07:12
|
|
|
|
|
Mar 9 2014, 08:20
|
Частый гость
 
Группа: Участник
Сообщений: 163
Регистрация: 25-10-10
Из: Ростовская обл.
Пользователь №: 60 401

|
Цитата(aaarrr @ Mar 9 2014, 11:30)  Обычно из таких - низкоуровневых - функций данные в плавающей точке все же не вытаскивают. Но если очень хочется, то можно. Другой вопрос, нужен ли будет на деле этот float потом. Хорошо, может это стрельба по воробьям из пушки. Какой тип вы для этой функции и переменной порекомендуете, если в результате функция должна вернуть число от -45,5 до 45,5 ?
|
|
|
|
|
Mar 9 2014, 09:35
|
Частый гость
 
Группа: Участник
Сообщений: 163
Регистрация: 25-10-10
Из: Ростовская обл.
Пользователь №: 60 401

|
Понятно. Тогда с учетом того, что я пишу код в AVRStudio под tiny2313 будет ли правильной вот эта функция Код uint16_t temp_18b20(){//функция получает с датчика данные с температурой в виде двух байт
uint16_t temp = 0; if(TD_find()==1)//если устройство присутствует на шине { TD_sendcmd(0xcc);//пропустить ROM код, так ка датчик в устройстве один и не требуется идентификация TD_sendcmd(0x44);//команда датчику преобразовать температуру _delay_ms(750);//преобразование в 12 битном режиме занимает 750ms TD_find();//снова посылаем Presence и Reset TD_sendcmd(0xcc); TD_sendcmd(0xbe);//команда датчику передать байты (у 18b20 в первых двух байтах содержится температура) //читаем два байта с температурой и записываем оба байта в двух байтную переменную temp = TD_receive_byte(); temp = (temp << 8) | TD_receive_byte(); } //возвращаем температуру return temp; }
|
|
|
|
|
Mar 9 2014, 09:48
|
Частый гость
 
Группа: Участник
Сообщений: 163
Регистрация: 25-10-10
Из: Ростовская обл.
Пользователь №: 60 401

|
Цитата(aaarrr @ Mar 9 2014, 13:38)  Правильнее будет int16_t, а не uint - результат ведь знаковый. И проверьте, что TD_receive_byte() возвращает char, а не больше. Нет, знак еще находится в коде, т.е. если 11-15 биты 1,то знак будет -. Так же и с дробной частью. Она заложена в 0-3 битах. Все это буду извлекать в отдельной функции с преобразованием в код LCD дисплея. Функция TD_receive_byte() возвращает uint8_t.
|
|
|
|
|
Mar 9 2014, 10:06
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(RW6MKA @ Mar 9 2014, 13:48)  Нет, знак еще находится в коде, т.е. если 11-15 биты 1,то знак будет -. Это понятно. Но если Вы хотите, чтобы этот знак был учтен в дальнейшем, то результат должен быть знаковый: short s = 0xffff; unsigned short us = 0xffff; float f; f = s; // f = -1; f = us; // f = 65535 Цитата(RW6MKA @ Mar 9 2014, 13:48)  Функция TD_receive_byte() возвращает uint8_t. Тогда порядок.
|
|
|
|
|
Mar 9 2014, 10:15
|
Частый гость
 
Группа: Участник
Сообщений: 163
Регистрация: 25-10-10
Из: Ростовская обл.
Пользователь №: 60 401

|
Цитата(aaarrr @ Mar 9 2014, 14:06)  Но если Вы хотите, чтобы этот знак был учтен в дальнейшем, то результат должен быть знаковый: Понятно. Учту. Спасибо всем за подробные ответы. Надеюсь и в дальнейшем на вашу помощь.
|
|
|
|
|
Mar 9 2014, 10:34
|

Гуру
     
Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237

|
Судя по стартовому посту темы, вопрос касался оптимизации кода, т.е. стремления избавиться от операции 8-кратного сдвига, который МК обычно не умеют делать одной инструкцией. А то и вызывают на этом месте библиотечную функцию, которая осуществляет сдвиги в цикле со счетчиком. Тогда как ответы в общем-то сводятся к тому, как этот сдвиг красивше записать. Т.е. в плане оптимизации эти ответы не только бесполезны, но и уже негативно проявили себя по части всевозможных ошибок при реализации. В этом плане выражение Код *(char *)&Temp = TD_receive_byte(); *((char *)&Temp + 1) = TD_receive_byte(); было вполне оптимальным, с тем лишь недостатком, что оказалось непонятным топикстартеру. Т.е. его и надо было просто разъяснить, но не возвращаться к сдвигу. На этот счет могу предложить альтернативу с union, которая в максимальной степени оптимальна, но гораздо проще в понимании: Код uint16_t temp_18b20() { union { unsigned char byte[2]; uint16_t word; } temp;
... temp.byte[1] = TD_receive_byte(); temp.byte[0] = TD_receive_byte(); ... return temp.word; } Здесь union располагает в одной и той же памяти 2 байта byte и одно слово word, тем самым, позволяя заполнить последнее по частям.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|