Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Микроконтроллеры (MCU) и микропроцессоры (MPU) > Функция задержки DelayUs()


Автор: Specialist 31.7.2008, 14:51
Пишу прогу и нужно было поставить кварц на 20 мГц поставил. До этого стоял на 4мГц и все норм было . И конечно у меня задержки уменьшились в 5 раз, странно. smile))
Использую Proteus для отладки, пишу в MPLAB на C, компилятор Hi-Tech. Функции Delay там есть в примерах я использую их. Проблема в том, что я не пойму как указать частоту правильно. 
Цитата
/*
 *    Delay functions for HI-TECH C on the PIC
 *
 *    Functions available:
 *  DelayUs(x)    Delay specified number of microseconds
 *  DelayMs(x)    Delay specified number of milliseconds
 *
 *    Note that there are range limits: x must not exceed 255 - for xtal
 *    frequencies > 12MHz the range for DelayUs is even smaller.
 *    To use DelayUs it is only necessary to include this file; to use
 *    DelayMs you must include delay.c in your project.
 *
 */

/*    Set the crystal frequency in the CPP predefined symbols list in
    HPDPIC, or on the PICC commmand line, e.g.
    picc -DXTAL_FREQ=4MHZ
    
    or
    picc -DXTAL_FREQ=100KHZ
    
    Note that this is the crystal frequency, the CPU clock is
    divided by 4.

 *    MAKE SURE this code is compiled with full optimization!!!
    
 */

Тут написано, что нужно в командную строку добавить -DXTAL_FREQ=20MHZ. Иду в Project>Build Options>main.c добавляю там строчку эту и задержка изменяется на 31мкс но это не правильно.
Код
void main()
{


    //Настройка портов
    TRISA=0xFF;
    TRISB=0x0;
    TRISC=0b00000011;
    PORTA = 0;
    PORTB = 0;
    PORTC = 0;
///////////////////////////////////////////////////////////
    while (1){
        
        PORTB = 0xFF;
        DelayUs(50);
        PORTB = 0;
    }    
}

Может у кого-то есть другая функция задержки ? Или как эту использовать ??? Помогите плиз, очень нужно !

Автор: cardinal 2.8.2008, 18:27
Ты уже нашел CPP predefined symbols list? Или прогу picc?

Автор: Specialist 3.8.2008, 19:04
Цитата

Ты уже нашел CPP predefined symbols list? Или прогу picc?

Ничего не понял.

Автор: cardinal 3.8.2008, 19:11
Specialist, ты сам выложил комментарии, ты их читал, сделал что там написано?

Автор: Specialist 3.8.2008, 19:54
Цитата

Specialist, ты сам выложил комментарии, ты их читал, сделал что там написано?

Читал конечно.

Цитата

Иду в Project>Build Options>main.c добавляю там строчку эту и задержка изменяется на 31мкс но это не правильно.


А должна быть 50мкс.

Автор: cardinal 4.8.2008, 00:39
Цитата

 *    Note that there are range limits: x must not exceed 255 - for xtal
 *    frequencies > 12MHz the range for DelayUs is even smaller.
 *    To use DelayUs it is only necessary to include this file; to use
 *    DelayMs you must include delay.c in your project.

Ради интереса, посмотри правильно ли отсчитывает 10, 20 и там 30 мкс. Если при какой то паузе начинается погрешность, то это и есть even smaller.

Автор: UniBomb 4.8.2008, 10:33
Specialist, на своём относительно небольшом опыте скажу - вместо рабора "чего не так" с библиотечными функциями проще написать свои. Благо в отношении контроллеров это не такая уж и проблема. Практически весь функционал я пишу для свои проектов я пишу сам, исключение составляют разве что небольшие макросы, которые неправильно работать просто немогут. В отношении данной темы могу сказать вот что - сделай цикл (можно даже ассемблерной вставкой и инлайновским) - посмотри сколько циклов мк он длится. Например в моих проектах такой цикл выглядит так:


Код

DEL1MS:
            ldi  tim_count1,100 ;загружаем значение
lrex:       
    ldi  tim_count2,26  ;загружаем значение
lrin:       
    dec  tim_count2     ;декремент
            brne lrin                 ;если больше нуля, то переходим
            dec  tim_count1
            brne lrex
            ret


Поиграв со значениями и вставив по необходимости пустые операторы можно добится круглового количества циклов. Далее при необходимости задержки в извесное количество циклов - просто столько раз и вызови эту функцию. Со временем то же самое, просто необходимо сначала высчитать количество вызовов (надо умножить частоту кристалла на количество времени задержки)...

Автор: Specialist 5.8.2008, 10:03
Цитата

Ради интереса, посмотри правильно ли отсчитывает 10, 20 и там 30 мкс. Если при какой то паузе начинается погрешность, то это и есть even smaller.

Не правильно. Наверно после 12мГц начинается "range limits". И к 20 мГц вообще перестает работать. Нету времени сейчас проверить.


UniBomb, не сильно понял, что этот код делает(кроме декремента) но сам смысл понятен. Чуть позже этим займусь.
Спасибо!

Автор: eladrea 5.8.2008, 11:31
была похожая проблема...
реализовывал нужную задержку оператором "for" внутри которой пару "nop" команд и вызов функции опроса клавиатуры


Автор: UniBomb 5.8.2008, 14:58
Specialist, 
этим декрементом ты занимаеш процессорное время. Чего и требовалось))) Вместо декремента можно инкремент сделать, или вообще что угодно  smile Тем более плюсом такого подхода (все функции реализовываются самим) почти полная компиляторонезависимость. Ну разве что придётся подправить название функцй обработки прерываний...


eladrea, фор в зависимости от настроек компилятора (да и вообще в зависимости от самого компилятора) может быть по разному реализован. Как следствии можно говорить о точности "+- чего то там". Да и потом такой цикл может быть вообще проигнорирован. Как следствие задержка получается наглазок, когда как инлайновские ассемблеровские вставки дают задержку в точное количество тактов.

Автор: eladrea 7.8.2008, 06:44
UniBomb а отладка на что? даже в MPLAB SIM можно все задержки прослеживать и корректировать 
фор удобен еще тем что в любой момент можно прервать задержку(при срабатывании прерывания и возврата в ту же самую точку), если речь идет о hi-tech picc, мое мнение -  компилятор кривой(8.05 PL2 точно),  щас перешел на ccs c - пока нареканий нету.

Автор: UniBomb 7.8.2008, 15:26
eladrea, ну я с пиками дела не имел, только авр... avr-gcc имеет такую особенность, что он часто оптимизирует то, чего не ждёт программист. И если написать просто фор с нопами, то такой цикл "оптимизируется" до нуля циклов. Даже очень много переменных не создются ни при отладке, ни при рантайме (которые используются всего несколько раз - например всякие счётчики, представляеш как удобно отлаживать, считая количесвто циклов в уме)))))

Автор: Ofer 4.9.2008, 20:46
UniBomb, чтоб оптимизатор не убирал код, его можно насильно заставить вставить через volatile, а чтоб считать циклы было удобней, то в сишном коде можно сделать ассемблерные вставки с упоминанием того же volatile. В таком случае можно добиться очень большой точности задержки, если конечно просчитать и не ошибиться smile

Автор: UniBomb 8.9.2008, 09:57
Цитата(Ofer @  4.9.2008,  20:46 Найти цитируемый пост)
делать ассемблерные вставки


Гы)) я эту мысль уже озвучил:
Цитата(UniBomb @  4.8.2008,  10:33 Найти цитируемый пост)
сделай цикл (можно даже ассемблерной вставкой и инлайновским)




Автор: Ofer 12.9.2008, 19:36
Цитата(UniBomb @  8.9.2008,  09:57 Найти цитируемый пост)
Гы)) я эту мысль уже озвучил:
Цитата(UniBomb @  4.8.2008,  10:33 )сделай цикл (можно даже ассемблерной вставкой и инлайновским)

Вот-вот!! Мысль подхвачена, но предлагаю коррективу в виде volatile  smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)