реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Closed TopicStart new topic
> Atmega48, DS18S20 и пресловутая оптимизация AVRStudio
NikitoS-86
сообщение Jan 23 2009, 12:19
Сообщение #1


Участник
*

Группа: Новичок
Сообщений: 28
Регистрация: 22-09-08
Пользователь №: 40 380



Доброго всем времени суток.
Появилась задачка мерить температуру на нескольких датчиках. В качестве управляющего МК дана ATmega48, в качестве датчика решил использовать DS18S20, поскольку работа через 1-wire показалась очень удобной штукой. Проштудировал переведённую статью про интерфейс 1-wire и вперёд.
Вооружившись осциллографом стал пытаться что-нибудь отиравить и принять. Отправка РЕСЕТ и приём ПРЕСЕНС прошли замечательно, отправка команды SEARCH ROM тоже, а вот попытка получить ответ на последнюю команду как-то не прошла... Точнее так, судя по осциллографу датчик мне отвечает, а вот если пытаться посмотреть на экране монитора через Watch, то он говорит, что одни нули...
Вот тут я добрался до самого неприятного момента и пока малопонятного для меня. Дело в том, что я себе не очень хорошо представляю, что есть пресловутая оптимизация в АВРСтудии. Да, я знаю, что она выкидывает ненужный по её мнению код, куда она ессно отправляет функции, которые ничего не получают и не возвращают, переменные, которые по ЕЁ мнению не несут смысловой нагрузки и что её вроде как можно отучить от этого через написание магического слова volatile перед объявлением переменных. Всё, более точно я про неё ничего не знаю, а в настройках проекта помимо этого, можно выбрать аж 4 режима этой оптимизации... Так вот, дабы она не компостировала мне мозги, я её всегда вырубал и не испытывал никаких угрызений совести, а тут вот проблема - на шине 1-wire необходимо строго выдерживать временные интервалы, естественно я сразу желаю использовать функции "_delay_us/ms" (просто другого я не знаю способа), но тут как обычно всё обламывается, т.к. они без оптимизации не работают... Что делать дальше - хз... Можно конечно использовать таймер, но почему-то не очень хочется=), хотя если это единственный выход как обойти проблема - куда деваеться... Просто проект будет дальше разрастаться, а как-то мучатся в нём с этой оптимизацией не хочется=/

Вот этот простой код, с которым у меня ничего пока не вышло сегодня.

Заранее спасибо за ответы


CODE
#include <avr/io.h>
#include <avr/sfr_defs.h>
#include <avr/interrupt.h>

#define F_CPU 20000000UL
#include <util/delay.h>

#define READ_ROM 0x33

void init_ports(void)
{
DDRB = (1<<DD0);
PORTB = (1<<PB0);

PORTD = (1<<PD6) | (0<<PD5) | (0<<PD4) | (0<<PD3) | (0<<PD2);
DDRD = (1<<DDD6) | (1<<DDD5) | (1<<DDD4) | (1<<DDD3) | (1<<DDD2);
asm("nop");
return;
}

volatile void write1()
{
DDRB = (1<<DDB0);
PORTB &= ~(1<<PB0);
_delay_us(2);
PORTB = (1<<PB0);
_delay_us(28);
DDRB = (0<<DDB0);
_delay_us(10);
}

volatile void write0()
{
DDRB = (1<<DDB0);
PORTB &= ~(1<<PB0);
_delay_us(30);
DDRB = (0<<DDB0);
_delay_us(10);
}

void main ()
{
volatile char help_byte = 0xFF;
volatile char help_byte_2 = 0;
init_ports();


//---отсылка импульса RESET-----
PORTB &= ~(1<<PB0);
_delay_us(500);

//---приём импульса PRESENSE-----
DDRB = (0<<DDB0);
_delay_us(61);
help_byte = PIN0;

help_byte_2 = help_byte;
_delay_us(500);

//---отправка команды чтения адреса устройства-----
volatile char command = READ_ROM;


for (int i=0;i<8;i++)
{
if((command & 1) == 1)
write1();
else
write0();
command = command >> 1;
}
_delay_ms(1);


//---попытка получить от устройства его серийник---
volatile char serial_number[8] =
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
volatile char help_byte_3 = 0x00;

for (int i=0;i<8;i++)
{

for (int k=0;k<8;k++)
{
serial_number[i] = serial_number[i]<<1;
DDRB = (1<<DDB0);
PORTB &= ~(1<<PB0);
_delay_us(5);
DDRB = (0<<DDB0);
_delay_us(8);
help_byte_3 = PINB0;
serial_number[i] = serial_number[i] + (help_byte_3<<k);
_delay_us(45);
_delay_us(10);
}
}
}
Go to the top of the page
 
+Quote Post
aesok
сообщение Jan 23 2009, 12:54
Сообщение #2


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Вы читали описание функции _delay_us(..)?

Анатолий.

Сообщение отредактировал aesok - Jan 23 2009, 12:55
Go to the top of the page
 
+Quote Post
NikitoS-86
сообщение Jan 23 2009, 13:06
Сообщение #3


Участник
*

Группа: Новичок
Сообщений: 28
Регистрация: 22-09-08
Пользователь №: 40 380



Да, читал соответственно в доке WinAVR/// Всё что там сказано, если не ошибаюсь, то это то, что должна быть включена оптимизация и то, что она не может реализоватть задержку свыше 768мкс разделённые на частоту проца в МГц.
Go to the top of the page
 
+Quote Post
aesok
сообщение Jan 23 2009, 13:17
Сообщение #4


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Цитата(NikitoS-86 @ Jan 23 2009, 16:06) *
Да, читал соответственно в доке WinAVR/// Всё что там сказано, если не ошибаюсь, то это то, что должна быть включена оптимизация и то, что она не может реализоватть задержку свыше 768мкс разделённые на частоту проца в МГц.


void _delay_us ( double __us )
...
The maximal possible delay is 768 us / F_CPU in MHz.

#define F_CPU 20000000UL

768 us / 20 = 38,4 us

_delay_us(500); - ?????
_delay_us(45); - ?????


Попробуйте:

_delay_ms(0.5);
_delay_ms(0.045);

Анатолий.

Сообщение отредактировал aesok - Jan 23 2009, 13:18
Go to the top of the page
 
+Quote Post
NikitoS-86
сообщение Jan 23 2009, 13:20
Сообщение #5


Участник
*

Группа: Новичок
Сообщений: 28
Регистрация: 22-09-08
Пользователь №: 40 380



Попробую, хотя на мой взгляд это не поможет... Ибо в том же мануале есть запись:
If the user requests a delay greater than the maximal possible one, _delay_us() will
automatically call _delay_ms() instead. The user will not be informed about this case.
Go to the top of the page
 
+Quote Post
GDI
сообщение Jan 23 2009, 14:08
Сообщение #6


Профессионал
*****

Группа: Свой
Сообщений: 1 235
Регистрация: 14-05-05
Из: Санкт-Петербург
Пользователь №: 5 008



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


--------------------
http://www.embedders.org Блоги разработчиков электроники.
Go to the top of the page
 
+Quote Post
aesok
сообщение Jan 23 2009, 14:47
Сообщение #7


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Цитата(NikitoS-86 @ Jan 23 2009, 16:20) *
Попробую, хотя на мой взгляд это не поможет... Ибо в том же мануале есть запись:
If the user requests a delay greater than the maximal possible one, _delay_us() will
automatically call _delay_ms() instead. The user will not be informed about this case.


_delay_us так начала работать в только в последних версиях avr-libc. В следующий раз указывайте верию WinAVR.

volatile void write0(){
DDRB = (1<<DDB0);
PORTB &= ~(1<<PB0);
// хорохо пин установили в 0

_delay_us(30);
// подождали 30 us

DDRB = (0<<DDB0);
// отпустили пин

_delay_us(10);
}



Тоесть 0 присутствует на пине 30 us, но согласно рисенку 11 даташита, DS18S20 может прочитать состояния пина в любой момнт начиная с 15 и по 60 us после того как он установлен в 0. Так что задержка должна быть немного больше 60 us. Тоже самое в write1.


Анатолий.

Сообщение отредактировал aesok - Jan 23 2009, 15:04
Go to the top of the page
 
+Quote Post
NikitoS-86
сообщение Jan 23 2009, 14:52
Сообщение #8


Участник
*

Группа: Новичок
Сообщений: 28
Регистрация: 22-09-08
Пользователь №: 40 380



На счёт оптимизации - можно тогда узнать, что это такое? Почему несколько вариантов? Что именно оптимизируется и как?
Go to the top of the page
 
+Quote Post
Qwertty
сообщение Jan 23 2009, 14:56
Сообщение #9


Местный
***

Группа: Свой
Сообщений: 408
Регистрация: 21-10-06
Из: Санкт-Петербург
Пользователь №: 21 527



Битовый интервал в 40мкс это очень мало. Должно быть не меньше 60 и не больше 120.
Если так напрягает оптимизация - вынесите функции задержки в отдельный файл, для него оптимизацию включите. Остальным можно не включать. smile.gif
Go to the top of the page
 
+Quote Post
haker_fox
сообщение Jan 23 2009, 15:05
Сообщение #10


Познающий...
******

Группа: Свой
Сообщений: 2 963
Регистрация: 1-09-05
Из: г. Иркутск
Пользователь №: 8 125



Уж на Си-то исходников для работы с DS18B20 хватает! Здесь, на www.avrfreaks.net Ну как я понял, Вы используете AVR Studio для работы. Просимулируйте в ней всю работы программы, заодно и увидите как работают паузы.
Успехов!


--------------------
Выбор.
Go to the top of the page
 
+Quote Post
aesok
сообщение Jan 23 2009, 15:08
Сообщение #11


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Цитата(NikitoS-86 @ Jan 23 2009, 17:52) *
На счёт оптимизации - можно тогда узнать, что это такое? Почему несколько вариантов? Что именно оптимизируется и как?


В 99.9 случаев наилудшим выбором является -Os. Считайте что -O0 это только для разработчиков компилятора.

Очень долго отвечать на заданые вами вопрасы, но ответ все равно будет -Os.

Анатолий

Сообщение отредактировал aesok - Jan 23 2009, 15:12
Go to the top of the page
 
+Quote Post
haker_fox
сообщение Jan 23 2009, 15:11
Сообщение #12


Познающий...
******

Группа: Свой
Сообщений: 2 963
Регистрация: 1-09-05
Из: г. Иркутск
Пользователь №: 8 125



Цитата(NikitoS-86 @ Jan 23 2009, 22:52) *
На счёт оптимизации - можно тогда узнать, что это такое?

Ну например вот это код никогда не выполнится:
Код
if(10 > 15)
  {
     // something here
   }

Есть ли смысл переводить его в машинный код и формировать с ним hex? Нет такого смысла! Оптимизатор спокойно выкинит этот фрагмент, ну а программист получит предупреждение (зависит от опций компилятора).

Вообще оптимизация может быть выключена. Тогда все, что Вы написали будет переведено в машинный код именно в том виде, в которым программа написана.
Оптимизация по объему дасти минимальный объем машинного кода, но не обязательно он будет быстро выполняться.
Оптимизация по скорости наоборот даст минимальный по времени машинный код, но не обязательно его размер будет малым.
Вообще все что я показал, это довольно примитивно. Уважаемый aesok лучше расскажет! Он, как я понял, gcc лучше многих знает!


--------------------
Выбор.
Go to the top of the page
 
+Quote Post
aesok
сообщение Jan 23 2009, 15:22
Сообщение #13


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Цитата(haker_fox @ Jan 23 2009, 18:11) *
Уважаемый aesok лучше расскажет! Он, как я понял, gcc лучше многих знает!


Пожалуйста избавьте меня от этого, в GCC над программой выполняться порядка
200 проходов, основная масса из них оптимизирующие. Я не знаю их все. И зачем
Вам процесс, Вас же интересует результат. А результат это -Os (оптимизация по размеру)
плюс, иногда отключение проходов которые вредны для AVR платформы. В очень
редких случаях оптимизация по скорости -O3.

Анатолий.

Сообщение отредактировал aesok - Jan 23 2009, 15:23
Go to the top of the page
 
+Quote Post
haker_fox
сообщение Jan 23 2009, 15:26
Сообщение #14


Познающий...
******

Группа: Свой
Сообщений: 2 963
Регистрация: 1-09-05
Из: г. Иркутск
Пользователь №: 8 125



Цитата(aesok @ Jan 23 2009, 23:22) *
Пожалуйста избавьте меня от этого

Простите, если я неосторожно "ляпнул"!


--------------------
Выбор.
Go to the top of the page
 
+Quote Post
NikitoS-86
сообщение Jan 23 2009, 15:47
Сообщение #15


Участник
*

Группа: Новичок
Сообщений: 28
Регистрация: 22-09-08
Пользователь №: 40 380



Итак, спасибо всем откликнувшимся=)
1) Вроде бы получилось считать его серийник и он совпал с показаниями осциллографа, уже радует=). Правда на всякий несколько завысил некоторые интервалы, которые были слишком малы. Как говорится, когда ничего не работает - надо садиться и писать всё заного и пошагово=). Но теперь буду дальше мучать датчик, измерение температуры ведь ещё не пробовал, так что может опять на что напорюсь)
2) Возвращаясь к оптимизации - ну хорошо, опустим все объяснения, но есть ли какие-нибудь источники, где можно это всё почитать? Общение с атмегами мне ещё долгое предстоит, а не на один раз (сделал и забыл), так что надо вникать, без вариантов.

Спасибо.

Сообщение отредактировал NikitoS-86 - Jan 23 2009, 15:49
Go to the top of the page
 
+Quote Post
haker_fox
сообщение Jan 23 2009, 16:23
Сообщение #16


Познающий...
******

Группа: Свой
Сообщений: 2 963
Регистрация: 1-09-05
Из: г. Иркутск
Пользователь №: 8 125



Цитата(NikitoS-86 @ Jan 23 2009, 23:47) *
2) Возвращаясь к оптимизации - ну хорошо, опустим все объяснения, но есть ли какие-нибудь источники, где можно это всё почитать?

Да, впринципе, зачем это знать? То, что сказал уважаемый aesok, вполне достаточно. Ну если уж так хочется, то google.com рулит.


--------------------
Выбор.
Go to the top of the page
 
+Quote Post
aesok
сообщение Jan 23 2009, 16:35
Сообщение #17


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Цитата(NikitoS-86 @ Jan 23 2009, 18:47) *
2) Возвращаясь к оптимизации - ну хорошо, опустим все объяснения, но есть ли какие-нибудь источники, где можно это всё почитать? Общение с атмегами мне ещё долгое предстоит, а не на один раз (сделал и забыл), так что надо вникать, без вариантов.


Почитать что каждая оптимизация делает Вы можете в GCC User Manual. В разделе посвященном ключам оптимизации. А вот о том какие какие из них полезны/вредны для AVR очень мало информации. Немножко есть в avr-libc-user-manual. И повторяюсь, пока Вам хватит -Os.

Анатолий.
Go to the top of the page
 
+Quote Post
NikitoS-86
сообщение Jan 25 2009, 09:49
Сообщение #18


Участник
*

Группа: Новичок
Сообщений: 28
Регистрация: 22-09-08
Пользователь №: 40 380



Значит так, в пятницу вечером мне, как я уже писал, удалось прочитать серийник припаянного и единственного на шине датчика. Но вот дальше что-то дело не пошло...
Естественно первое, что я попытался сделать, это прочитать температуру. Для этого в соответствии с даташитом я выбрал следующую последовательность действий:
1) Посылаю импульс сброса и принимаю ответ термометра.
2) Т.к. датчик на шине единственный, то посылаю сразу команду Skip ROM [CCh].
3) Посылаю команду Convert T [44h].
4) Формирую задержку 750мс (для уверенности даже попытался формировать 1 с).
5) Опять импульс сброса и ответ термометра.
6) Опять команда Skip ROM [CCh].
7) Команда Read Scratchpad [BEh]....
И вот после этого при попытке принять данные по температуре он мне шлёт сплошные единицы.... Сейчас я пишу не со своего компа, где прога плата, поэтому может быть, что я впопыхах в пятницу где-то ошибся, поэтому поставим вопрос так:
1) Правильную ли я делаю последовательность?
2) Можно ли считать данные и забить на CRC? Просто на сколько я понял, сами данные это вообще всего два байта... При этом в даташите в примерах написано, что присылается 9 байт, включая данные для проверки CRC... Какие данные являются непосредственно температурой?

Заранее спасибо за советы...
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 25 2009, 09:56
Сообщение #19


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(NikitoS-86 @ Jan 25 2009, 11:49) *
2) Можно ли считать данные и забить на CRC?
Можно, если вас не интересует результат.
Цитата(NikitoS-86 @ Jan 25 2009, 11:49) *
При этом в даташите в примерах написано, что присылается 9 байт, включая данные для проверки CRC... Какие данные являются непосредственно температурой?
Там же в даташите и написано. Просьба прочитать за вас даташит выглядит несколько, хм...странной. И вы надеетесь, что кто-то захочет помогать человеку, которому лень почесть даташит?


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
777777
сообщение Jan 26 2009, 07:35
Сообщение #20


Профессионал
*****

Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357



Цитата(NikitoS-86 @ Jan 23 2009, 15:19) *
Так вот, дабы она не компостировала мне мозги, я её всегда вырубал и не испытывал никаких угрызений совести

Я слышал много страшилок об ошибках оптимизации, но не помню ни одного случая, чтобы они подтвердились - всегда ошибка оказывалась в программе. Поэтому выключать оптимизацию - это... глупо - самое мягкое, что можно сказать. От этого код становится больше раза в 4...5 и, соответственно медленнее. Я подозреваю, что такой режим оставлен для тех, кто помешан на ошибках оптимизатора - чтобы они могли отключив оптимизацию убедиться в том, что ошибка не исчезла.

Сообщение отредактировал 777777 - Jan 26 2009, 07:36
Go to the top of the page
 
+Quote Post
NikitoS-86
сообщение Jan 26 2009, 16:31
Сообщение #21


Участник
*

Группа: Новичок
Сообщений: 28
Регистрация: 22-09-08
Пользователь №: 40 380



Да, в оптимизации судя по всему действительно нет ничего криминального... Отключал по неопытности и по причине страшилок того, что оптимизатор чуть ли не всё лишнее по его мнению порезает, но вот вроде сейчас работает и нормально...

По теме: Тему можно закрывать=) Разобрался со всем полностью. Данные и принимает и CRC считает... Хотя конечно было тяжеловато понять алгоритм CRC... Однако сейчас всё работает и всё прекрасно считает и отсылает/принимает).

Всем спасибо.
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Closed TopicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th July 2025 - 23:38
Рейтинг@Mail.ru


Страница сгенерированна за 0.01555 секунд с 7
ELECTRONIX ©2004-2016