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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Задержки в мкс на WinAVR. Нужно для 1-wire. Как?
asf
сообщение Dec 1 2006, 22:32
Сообщение #1


Участник
*

Группа: Новичок
Сообщений: 29
Регистрация: 19-12-05
Пользователь №: 12 407



Пробовал _delay_us , однако на малых значениях просто никак
Что я только не мудрил, считал фронты, пытался понять закономерность, получилось только detect presents, делал циклы, пытался понять как компилятор переводит в асм цикл задержки...
в общем результат 0. Помогайте. Все путем дергания ногой МК т.к. порт уже используется.
Есть мысль сделать селектор и т.о. повесить на один порт USART два устройства, в т.ч. и 1-wire.....
Но у кого-то ведь получалось.... Вроде скажем на 8 Мгц проц Atmega16 делает 8 тактов, далее хз как winAvr компилирует цикл типа while(time--); вроде по фронтам получается порядка 3х циклов подобной задержки на 1-ну мкс.... но пишу далее 0х33 и читаю одни 0хFF .... виимо не попал в таймслоты.... может у кого есть четкое понятие как сделать на winavr понятную задержку в мкс?
Go to the top of the page
 
+Quote Post
dvm11111111
сообщение Dec 2 2006, 03:12
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 34
Регистрация: 25-01-06
Пользователь №: 13 567



Лови, мож поможет. Сразу хочу сказать, что задержки определялись эксперементально.

Сообщение отредактировал dvm11111111 - Dec 2 2006, 03:12
Прикрепленные файлы
Прикрепленный файл  home2.rar ( 4.79 килобайт ) Кол-во скачиваний: 124
 
Go to the top of the page
 
+Quote Post
defunct
сообщение Dec 2 2006, 03:15
Сообщение #3


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(asf @ Dec 1 2006, 22:32) *
Вроде скажем на 8 Мгц проц Atmega16 делает 8 тактов
...
может у кого есть четкое понятие как сделать на winavr понятную задержку в мкс?

Код
#define __delay_us asm("NOP");\
        asm("NOP");\
        asm("NOP");\
        asm("NOP");\
        asm("NOP");\
        asm("NOP");\
        asm("NOP");\
        asm("NOP");
Go to the top of the page
 
+Quote Post
prottoss
сообщение Dec 2 2006, 19:52
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



делал как то ради любопытства...Для DS1821 правда, но работает, по сей день, как часы...
Прикрепленные файлы
Прикрепленный файл  Software.IAR.rar ( 3.2 килобайт ) Кол-во скачиваний: 105
 


--------------------
Go to the top of the page
 
+Quote Post
asf
сообщение Dec 3 2006, 10:25
Сообщение #5


Участник
*

Группа: Новичок
Сообщений: 29
Регистрация: 19-12-05
Пользователь №: 12 407



спасибо, буду пробовать, вот только как именно (по какой методике) подбирали задержки?
Go to the top of the page
 
+Quote Post
prottoss
сообщение Dec 3 2006, 10:46
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(asf @ Dec 3 2006, 14:25) *
спасибо, буду пробовать, вот только как именно (по какой методике) подбирали задержки?


Если вы ко мне обращаетесь: Вы исходники читали? Там написанно по каким аппнотам сделаны задержки...Вообще, рекомендую, при написании чего то, сначала проверить, не изобретен ли это велосипед УЖЕ. Больше времени на пиво остается)))


--------------------
Go to the top of the page
 
+Quote Post
singlskv
сообщение Dec 3 2006, 15:43
Сообщение #7


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



to prottoss
Посмотрел Ваш код на предмет задержек и был слегка удивлен:
Код
#define    CPU_CYCLE        408// длительность командного цикла МК в нс для частоты 2.4576MHz

#define COMM_PER_MCS    (1000 / CPU_CYCLE) // количество команд CPU за микросекунду
#define    OW_DEL_A        6   * COMM_PER_MCS
#define    OW_DEL_B        64  * COMM_PER_MCS
#define    OW_DEL_C        60  * COMM_PER_MCS
#define    OW_DEL_D        10  * COMM_PER_MCS
#define    OW_DEL_E        9   * COMM_PER_MCS
#define    OW_DEL_F        55  * COMM_PER_MCS
#define    OW_DEL_G        0   * COMM_PER_MCS
#define    OW_DEL_H        480 * COMM_PER_MCS
#define    OW_DEL_I        70  * COMM_PER_MCS
#define    OW_DEL_J        410 * COMM_PER_MCS


ИТОГО:
COMM_PER_MCS=2
OW_DEL_H=960 // тактов, или 960/2.4576=390,625 мкс
Ну и остальные задержки соответственно.

Э...Э...Э Ну, то есть такой код работать не должен sad.gif

А если и работает, то это нам говорит, лишь о том, что продукция Dallas
умеет хорошо подстраиваться под длительности импульсов которые ей посылаешь.
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Dec 3 2006, 16:23
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Для IAR C (DS1820/18B20) у меня автоматически считаются задержки. И компилятор их формирует правильно. См текст в библиотеках, в конце.
Go to the top of the page
 
+Quote Post
prottoss
сообщение Dec 3 2006, 16:58
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(singlskv @ Dec 3 2006, 19:43) *
to prottoss
Посмотрел Ваш код на предмет задержек и был слегка удивлен:

....
ИТОГО:
COMM_PER_MCS=2
OW_DEL_H=960 // тактов, или 960/2.4576=390,625 мкс
Ну и остальные задержки соответственно.

Э...Э...Э Ну, то есть такой код работать не должен sad.gif

А если и работает, то это нам говорит, лишь о том, что продукция Dallas
умеет хорошо подстраиваться под длительности импульсов которые ей посылаешь.
Да, на самом деле, OW_DEL_H (ResetPulse по DALLAS) меньше чем рекомендованно, но тем не менее работает. Касаемо остальных задержек - для них требования не такие строгие, минимум и максимум отличается почти в два раза...

В любом случае спасибо за подсказку cheers.gif . Я не учел, что препроцессор округляет в меньшую сторону. Думаю, что с

Код
#define COMM_PER_MCS    ((1000 / CPU_CYCLE) + 1)
Будет лучше


--------------------
Go to the top of the page
 
+Quote Post
asf
сообщение Dec 3 2006, 19:35
Сообщение #10


Участник
*

Группа: Новичок
Сообщений: 29
Регистрация: 19-12-05
Пользователь №: 12 407



так в том-то и дело, что на winavr не все так просто как на iar...
Go to the top of the page
 
+Quote Post
singlskv
сообщение Dec 3 2006, 19:40
Сообщение #11


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата
Думаю, что с
Код
#define COMM_PER_MCS    ((1000 / CPU_CYCLE) + 1)

Будет лучше


Мне кажется что лучше вот так:
Код
#define    CPU_CYCLE        408// длительность командного цикла МК в нс для частоты 2.4576MHz

#define COMM_PER_MCS    (1000000 / CPU_CYCLE) // количество команд CPU за  милисекунду
#define    OW_DEL_A      (6   * COMM_PER_MCS)/1000
#define    OW_DEL_B        (64  * COMM_PER_MCS)/1000
#define    OW_DEL_C        (60  * COMM_PER_MCS)/1000
#define    OW_DEL_D        (10  * COMM_PER_MCS)/1000
#define    OW_DEL_E        (9   * COMM_PER_MCS)/1000
#define    OW_DEL_F     (55  * COMM_PER_MCS)/1000
#define    OW_DEL_G        (0   * COMM_PER_MCS)/1000
#define    OW_DEL_H    (480 * COMM_PER_MCS)/1000
#define    OW_DEL_I     (70  * COMM_PER_MCS)/1000
#define    OW_DEL_J     (410 * COMM_PER_MCS)/1000


А для коротких интервалов можно еще уточнить:
#define OW_DEL_A (6 * COMM_PER_MCS)/1000 -1 // или -2 надо проверить в симуляторе
#define OW_DEL_E (9 * COMM_PER_MCS)/1000 -1
чтобы учесть время выдачи бита на пин.
Go to the top of the page
 
+Quote Post
aesok
сообщение Dec 3 2006, 19:42
Сообщение #12


Знающий
****

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



Цитата(asf @ Dec 3 2006, 20:35) *
так в том-то и дело, что на winavr не все так просто как на iar...


Как вы ипользуете макрос "_delay_us"? Покажите код.

Анатолий.
Go to the top of the page
 
+Quote Post
prottoss
сообщение Dec 3 2006, 19:49
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(singlskv @ Dec 3 2006, 23:40) *
Мне кажется что лучше вот так:
Код
...
Да, так точнее получится...
Цитата(singlskv @ Dec 3 2006, 23:40) *
А для коротких интервалов можно еще уточнить:
#define OW_DEL_A (6 * COMM_PER_MCS)/1000 -1 // или -2 надо проверить в симуляторе
#define OW_DEL_E (9 * COMM_PER_MCS)/1000 -1
чтобы учесть время выдачи бита на пин.
Зачем еще извращаться то? Таймслоты довольно широкие, минимум от максимума от двух до четырех раз отличается


--------------------
Go to the top of the page
 
+Quote Post
singlskv
сообщение Dec 3 2006, 20:02
Сообщение #14


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(prottoss @ Dec 3 2006, 19:49) *
Зачем еще извращаться то? Таймслоты довольно широкие, минимум от максимума от двух до четырех раз отличается

Не, ну это я уже говорил про "в общем случае", просто об этом иногда
тоже не стоит забывать smile.gif
Ну типа общая культура программирования, если есть возможность, то делаем интервал
строго по середине диапазона ...
Go to the top of the page
 
+Quote Post
singlskv
сообщение Dec 3 2006, 20:24
Сообщение #15


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(asf @ Dec 3 2006, 19:35) *
так в том-то и дело, что на winavr не все так просто как на iar...

А кто Вам мешает воспользоваться "void _delay_loop_1 (uint8_t __count)" ?
Ну, и конечно, при необходимости подкорректировать
задержку с помощью asm("nop"); ???
Go to the top of the page
 
+Quote Post
asf
сообщение Dec 4 2006, 09:41
Сообщение #16


Участник
*

Группа: Новичок
Сообщений: 29
Регистрация: 19-12-05
Пользователь №: 12 407



Цитата(aesok @ Dec 3 2006, 19:42) *
Цитата(asf @ Dec 3 2006, 20:35) *

так в том-то и дело, что на winavr не все так просто как на iar...


Как вы ипользуете макрос "_delay_us"? Покажите код.

Анатолий.


а что там может быть сверх естественного? _delay_us(6) и в путь
Go to the top of the page
 
+Quote Post
prottoss
сообщение Dec 4 2006, 10:08
Сообщение #17


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(asf @ Dec 3 2006, 23:35) *
так в том-то и дело, что на winavr не все так просто как на iar...
А что мешает перейти на ИАР? ИМХО лучшая среда программирования для AVR


--------------------
Go to the top of the page
 
+Quote Post
aesok
сообщение Dec 4 2006, 10:24
Сообщение #18


Знающий
****

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



Цитата(asf @ Dec 4 2006, 10:41) *
Цитата(aesok @ Dec 3 2006, 19:42) *

Цитата(asf @ Dec 3 2006, 20:35) *

так в том-то и дело, что на winavr не все так просто как на iar...


Как вы ипользуете макрос "_delay_us"? Покажите код.

Анатолий.


а что там может быть сверх естественного? _delay_us(6) и в путь


А "F_CPU" у вас определен? Как?

Анатолий.
Go to the top of the page
 
+Quote Post
asf
сообщение Dec 4 2006, 10:38
Сообщение #19


Участник
*

Группа: Новичок
Сообщений: 29
Регистрация: 19-12-05
Пользователь №: 12 407



Цитата(aesok @ Dec 4 2006, 10:24) *
Цитата(asf @ Dec 4 2006, 10:41) *

Цитата(aesok @ Dec 3 2006, 19:42) *

Цитата(asf @ Dec 3 2006, 20:35) *

так в том-то и дело, что на winavr не все так просто как на iar...


Как вы ипользуете макрос "_delay_us"? Покажите код.

Анатолий.


а что там может быть сверх естественного? _delay_us(6) и в путь


А "F_CPU" у вас определен? Как?

Анатолий.



#define F_CPU 8000000UL // 8 MHz
Go to the top of the page
 
+Quote Post
aesok
сообщение Dec 4 2006, 11:05
Сообщение #20


Знающий
****

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



Цитата(asf @ Dec 4 2006, 11:38) *
Цитата(aesok @ Dec 4 2006, 10:24) *

Цитата(asf @ Dec 4 2006, 10:41) *

Цитата(aesok @ Dec 3 2006, 19:42) *

Цитата(asf @ Dec 3 2006, 20:35) *

так в том-то и дело, что на winavr не все так просто как на iar...


Как вы ипользуете макрос "_delay_us"? Покажите код.

Анатолий.


а что там может быть сверх естественного? _delay_us(6) и в путь


А "F_CPU" у вас определен? Как?

Анатолий.



#define F_CPU 8000000UL // 8 MHz


F_CPU Должна быть определенна в каждом файле где используеться delay.h и до включения этого файла. Надеюсь у вас так.

Проще F_CPU определьть только один раз в Makefile, например так:
DEFS = ... -D F_CPU=8000000UL ...

У вас она кстате она не переопределена в Makefile?

Какие конкретно задежки вы пытаетесь получить с помощю _delay_us? У _delay_us есть ограничение по максимальной длительности, которую можно с помощью нее получить.


И не забывайте что пограмные задержки гарантируют только то что задержка будет не менее указанной, но она может быть больше.
Например если во время выполнения задержки в 20 мкс (_delay_us(20)) выпониться прерывание длительностью 100 мкс, то общая задежка будет 120 мкс.

Как много прерываний в вашей программе?


Анатолий.

Сообщение отредактировал aesok - Dec 4 2006, 11:05
Go to the top of the page
 
+Quote Post
asf
сообщение Dec 4 2006, 11:23
Сообщение #21


Участник
*

Группа: Новичок
Сообщений: 29
Регистрация: 19-12-05
Пользователь №: 12 407



Цитата(aesok @ Dec 4 2006, 11:05) *
Цитата(asf @ Dec 4 2006, 11:38) *

Цитата(aesok @ Dec 4 2006, 10:24) *

Цитата(asf @ Dec 4 2006, 10:41) *

Цитата(aesok @ Dec 3 2006, 19:42) *

Цитата(asf @ Dec 3 2006, 20:35) *

так в том-то и дело, что на winavr не все так просто как на iar...


Как вы ипользуете макрос "_delay_us"? Покажите код.

Анатолий.


а что там может быть сверх естественного? _delay_us(6) и в путь


А "F_CPU" у вас определен? Как?

Анатолий.



#define F_CPU 8000000UL // 8 MHz


F_CPU Должна быть определенна в каждом файле где используеться delay.h и до включения этого файла. Надеюсь у вас так.

Проще F_CPU определьть только один раз в Makefile, например так:
DEFS = ... -D F_CPU=8000000UL ...

У вас она кстате она не переопределена в Makefile?

Какие конкретно задежки вы пытаетесь получить с помощю _delay_us? У _delay_us есть ограничение по максимальной длительности, которую можно с помощью нее получить.


И не забывайте что пограмные задержки гарантируют только то что задержка будет не менее указанной, но она может быть больше.
Например если во время выполнения задержки в 20 мкс (_delay_us(20)) выпониться прерывание длительностью 100 мкс, то общая задежка будет 120 мкс.

Как много прерываний в вашей программе?


Анатолий.



Я делаю так:

#define F_CPU 8000000UL // 8 MHz
#include <util/delay.h>
#define OW_DEL_A 6
#define OW_DEL_B 64
#define OW_DEL_C 60
#define OW_DEL_D 10
#define OW_DEL_E 9
#define OW_DEL_F 55
#define OW_DEL_G 0
#define OW_DEL_H 480
#define OW_DEL_I 70
#define OW_DEL_J 410

Функция:
char OW_DetectPresence(void)
{ char status;

// устанавливаем шину в ноль
OW_DDR |= OW_BUS_MASK;

// задержка H нахождения шины в 0
__delay_cycles(OW_DEL_H);

// освобождаем шину
OW_DDR &= ~OW_BUS_MASK;

// задержка I до окончания таймслота
__delay_cycles(OW_DEL_I);

// читаем состояние шины
status = OW_PIN & OW_BUS_MASK;

// задержка J до окончания таймслота
__delay_cycles(OW_DEL_J);

return status;
}

не дает необходимого результата, однако вот такая конструкция работает:


char reset(void) //ñáðîñ òàáëåòêè
{ //
int temp; //
asm("cli"); //Çàïðåòèòü âñå ïðåðûâàíèÿ
OW_DDR |= OW_BUS_MASK; //0 íà òàáëåòêó

delay(1440);
temp=160; //ðåàëüíûé ïåðâûé îòâåò - 79 !!!
OW_DDR &= ~OW_BUS_MASK; //1 íà òàáëåòêó
do
{
if(bit_is_set(OW_PIN,OW_BUS)) goto respons1;
}while(--temp);// æäåì îñâîáîæäåíèÿ ëèíèè
goto bad;
respons1:
temp=172; //ðåàëüíûé ïåðâûé îòâåò - 86 !!!
do
{
if(!bit_is_set(OW_PIN,OW_BUS)) goto respons2;
}while(--temp);// æäåì îòâåòà òàáëåòêè
goto bad;//íåò îòâåòà òàáëåòêè
respons2:
temp=2382;
////ðåàëüíûé ïåðâûé îòâåò - 1191 !!!
do
{
if(bit_is_set(OW_PIN,OW_BUS)) goto respons3;
}while(--temp);//æäåì îñâîáîæäåíèÿ ëèíèè
goto bad;
respons3:
asm("sei"); //ðàçðåøàåì ïðåðûâàíèÿ
return 1;//òàáëåòêà èíèöèàëèçèðîâàíà
bad: //îøèáêà íà øèíå
asm("sei"); //ðàçðåøàåì ïðåðûâàíèÿ
return 0;
}//;êîíåö ñáðîñà DALLASa //

где delay(l_) - это:

do
{
}while(--l_);


----------------------
а вот на _delay_us никак не получается добиться даже detect presents

прерывания есть, но я их отключаю на время записи и чтения бит
Go to the top of the page
 
+Quote Post
asf
сообщение Dec 4 2006, 17:44
Сообщение #22


Участник
*

Группа: Новичок
Сообщений: 29
Регистрация: 19-12-05
Пользователь №: 12 407



angry.gif Работает только детект

int OW_DetectPresence()
{ char status;
asm("cli"); //Запретить все прерывания
// устанавливаем шину в ноль
OW_DDR |= OW_BUS_MASK;

// задержка H нахождения шины в 0
//_delay_loop_1(OW_DEL_H);
asf_delay_10us(48);

// освобождаем шину
OW_DDR &= ~OW_BUS_MASK;

// задержка I до окончания таймслота
_delay_loop_1(90);

// читаем состояние шины
if(!bit_is_set(OW_PIN,OW_BUS)) status = 1; else status = 0;

// задержка J до окончания таймслота
//asf_delay_10us(OW_DEL_J/10);
//_delay_loop_1(OW_DEL_J);
asf_delay_10us(41);

asm("sei"); //разрешаем прерывания

return status;
}

void asf_delay_10us(int l_)
{
int i;
for (i = 0; i < l_; i++)
{
_delay_us(10);
}
}

---------------
больше никак не могу добиться никакого ответа cranky.gif cranky.gif cranky.gif
уже даже так:
OW_DEL_A=6+koef_;
OW_DEL_B=64+koef_;
OW_DEL_C=60+koef_;
OW_DEL_D=10+koef_;
OW_DEL_E=9+koef_;
OW_DEL_F=55+koef_;
OW_DEL_G=0;//+koef_;
OW_DEL_I=70+koef_;

и увеличиваю пропорционально с 0 до ......
нихрена нет ответа....... может кто все же что подскажет? blink.gif
Go to the top of the page
 
+Quote Post
prottoss
сообщение Dec 4 2006, 18:10
Сообщение #23


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(asf @ Dec 4 2006, 21:44) *
angry.gif Работает только детект
нихрена нет ответа....... может кто все же что подскажет? blink.gif


1.Проверьте, правильно ли у Вас все подключенно и настроено (порты).

2.Попробуйте общаться с датчиком без использования прерываний в программе

3.Замените датчик...


--------------------
Go to the top of the page
 
+Quote Post
aesok
сообщение Dec 4 2006, 18:14
Сообщение #24


Знающий
****

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



1. Согласно документации:
_delay_us
...
The maximal possible delay is 768 us / F_CPU in MHz.

Тоесть для 8MHz максимальную задержку которую ва можете получить с помощю _delay_us, это около 100мкс. Если вам нужна задержка в 410 мкс, то нужно писать _delay_ms(0.41).

2. С какой оптимизацией вы компилируете проект? Если с -O0 то функции _delay_us/_delay_ms будут давать дополнительную задержку примерно в 3000 тактов.

Анатолий.

PS: Пожалуйста покажите наконец код функции OW_DetectPresence с "_delay_us".

Сообщение отредактировал aesok - Dec 4 2006, 18:58
Go to the top of the page
 
+Quote Post
asf
сообщение Dec 4 2006, 19:05
Сообщение #25


Участник
*

Группа: Новичок
Сообщений: 29
Регистрация: 19-12-05
Пользователь №: 12 407



Цитата(aesok @ Dec 4 2006, 18:14) *
1. Согласно документации:
_delay_us
...
The maximal possible delay is 768 us / F_CPU in MHz.

Тоесть для 8MHz максимальную задержку которую ва можете получить с помощю _delay_us, это около 100мкс. Если вам нужна задержка в 410 мкс, то нужно писать _delay_ms(0.41).

2. С какой оптимизацией вы компилируете проект? Если с -O0 то функции _delay_us/_delay_ms будут давать дополнительную задержку примерно в 3000 тактов.

Анатолий.

PS: Пожалуйста покажите наконец код функции OW_DetectPresence с "_delay_us".


Все, сделал disco.gif

Для Atmega16 8Mhz
#define OW_DEL_A 13
#define OW_DEL_B 90
#define OW_DEL_C 116
#define OW_DEL_D 16
#define OW_DEL_E 13
#define OW_DEL_F 78
#define OW_DEL_G 0
#define OW_DEL_H 700
#define OW_DEL_I 96
#define OW_DEL_J 560

далее везде _delay_loop_2 с этими задержками.

int OW_DetectPresence()
{ char status;
asm("cli"); //Запретить все прерывания
// устанавливаем шину в ноль
OW_DDR |= OW_BUS_MASK;
// задержка H нахождения шины в 0
_delay_loop_2(OW_DEL_H);
// освобождаем шину
OW_DDR &= ~OW_BUS_MASK;
// задержка I до окончания таймслота
_delay_loop_2(OW_DEL_I);
// читаем состояние шины
if(!bit_is_set(OW_PIN,OW_BUS)) status = 1; else status = 0;
// задержка J до окончания таймслота
_delay_loop_2(OW_DEL_J);
asm("sei");
//разрешаем прерывания
return status;
}

проект именно с -O0
почему -O0 добавляет 3000 тактов? что-то не сходится с моими показателями
Go to the top of the page
 
+Quote Post
aesok
сообщение Dec 4 2006, 19:50
Сообщение #26


Знающий
****

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



Цитата(asf @ Dec 4 2006, 20:05) *
проект именно с -O0
почему -O0 добавляет 3000 тактов? что-то не сходится с моими показателями


Чем больше информации вы будете скрывить когда задаете вопрос, тем позже получете ответ!

вот код функции _delay_ms:

Код
void
_delay_ms(double __ms)
{
    uint16_t __ticks;
    double __tmp = ((F_CPU) / 4e3) * __ms;
    if (__tmp < 1.0)
        __ticks = 1;
    else if (__tmp > 65535)
        __ticks = 0;    /* i.e. 65536 */
    else
        __ticks = (uint16_t)__tmp;
    _delay_loop_2(__ticks);
}


Для того чтобы более точно расчитать задежку параметр функции _delay_loop_2 расчитываеться с помощю действий с плавающей точкой. Если проект компилируеться без оптимизации то эти расчеты выполняються во время работы программы, а это порядка 3000 циклов по времени, и 2 Кб кода. (Лень уточнять.)

Если включить оптимизацию, даже -O1, то все вычисления будут происходить во время компиляции, и никаких дополнительных расходов.

И еще, параметр _delay_ms/_delay_us должен одязательно быть константой, по тойже самой причине.

Анатолий.
Go to the top of the page
 
+Quote Post
asf
сообщение Dec 4 2006, 21:37
Сообщение #27


Участник
*

Группа: Новичок
Сообщений: 29
Регистрация: 19-12-05
Пользователь №: 12 407



Цитата(aesok @ Dec 4 2006, 19:50) *
Цитата(asf @ Dec 4 2006, 20:05) *



проект именно с -O0
почему -O0 добавляет 3000 тактов? что-то не сходится с моими показателями


Чем больше информации вы будете скрывить когда задаете вопрос, тем позже получете ответ!

вот код функции _delay_ms:

Анатолий.


Анатолий, спасибо за помощь, но разве delay.h стоило приводить в качестве примера? Это же стандартные функции....
Go to the top of the page
 
+Quote Post
aesok
сообщение Dec 4 2006, 22:35
Сообщение #28


Знающий
****

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



Цитата(asf @ Dec 4 2006, 22:37) *
Цитата(aesok @ Dec 4 2006, 19:50) *

Цитата(asf @ Dec 4 2006, 20:05) *



проект именно с -O0
почему -O0 добавляет 3000 тактов? что-то не сходится с моими показателями


Чем больше информации вы будете скрывить когда задаете вопрос, тем позже получете ответ!

вот код функции _delay_ms:

Анатолий.


Анатолий, спасибо за помощь, но разве delay.h стоило приводить в качестве примера? Это же стандартные функции....


Функции из 'delay.h' не совсем библиотечные функции, эти функции не только задекларированы, но и определены в заголовочном файле. (Если вы откроете любую книгу по С то в ней вам скажут что так делать нельзя!). Это инлайн функции. Эти функции корректно использовать только с включенной оптимизацией, чтобы оптимизатор компилятора заоптимизировал их почти насмерть, от них в коде должен оставаться только оператор '__asm__' из _delay_loop_1/_delay_loop_2, все вычисления должны быть выполнены во время компиляции. Если вам так проще представьте себе что это макросы.

Эти функции при уровне оптимизации -O0, в общем случае, нельзя использовать вообще. Если скажем _delay_loop_1 будет использована в двух .c файлах в одном проекте вы получите ошибку при компоновке. Проверти. И еще раз повторю для _delay_us/_delay_ms, ошибка по времени будет время на одно деление чисел с плавающей точкой плюс одно умножение плюс 2 сравнения. Опять-же проверти время выполнения в симуляторе. Плюс вы подлинкуете математическую библиотеку. Смотрите размер кода.

Вывод: функции из 'delay.h' можно использовать только с включенной оптимизацией и параметры этих функций должны быть обязательно константы (или выражения которые могут бить вычислены во время компиляции).

Извиняюсь если не очень понятно объяснил, это не мое призвание. Изучайте, экспериментируйте или просто делайте как я написал в выводе.

И еще считайте что оптимизация -O0 в avr-gcc используется только для тестирования компилятора, код генерируется очень не эффективный. В 99.9% случаев вы должны использовать -Os.

Анатолий.

Сообщение отредактировал aesok - Dec 4 2006, 22:36
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Dec 5 2006, 16:57
Сообщение #29


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Я могу переписать на таймер. Например таймер 2. Тогда будет практически независим от компилятора. На такие интервалы прерывания запрещать не всегда удаётся.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 21st July 2025 - 19:22
Рейтинг@Mail.ru


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