2009-12-25 1 views
1

Как написать макрос задержки для PIC 18f87J50 с кристаллом 48 МГц и компилятор MCC18. Задержка должна быть в нас. Поэтому я, например, могу написать: Delay_us (201) и действительно получить задержку 201us.Задержка в MCC18, 48Mhz, 18F87J50

То, что я сейчас:

#define Delay_us(n) (Delay10TCYx(((n) * (uint16_t) 12 + 9)/10)) 

И does'nt кажется правильным в моем осциллографе! :/

С уважением!

И веселого Рождества!

ответ

2

ПИК делит часы на 4 так и для 48MHz каждый опкод работает в 0.0833us или 12 циклов в нас. Я использовал MPLAB и вводил разные значения и проверял в симуляторе так, что количество циклов вышло, как я ожидал. Лучший способ настроить функцию - посмотреть на сборку или использовать симулятор.

Вы можете сделать что-то вроде следующего, но вам нужно будет отрегулировать вызов функции для вашего complier.

#define OVERHEAD (2) 

void Delay_us(uint8_t us) 
{ 
    if (us <= OVERHEAD) return; // prevent underflow 
    us -= OVERHEAD ;    // overhead of function call in us. 

    Nop();  // 1 extra overhead to make function overhead an even us. 
    Nop();  // 1 add or remove Nop's as necessary. 
    Nop();  // 1 
    //Nop();  // 1 
    //Nop();  // 1 
    //Nop();  // 1 
    //Nop();  // 1 
    //Nop();  // 1 
    //Nop();  // 1 
    //Nop();  // 1 
    //Nop();  // 1 
    //Nop();  // 1 

    do // loop needs to be 12 cycles so each cycle is 1us. 
    { 
     Nop();  // 1 
     Nop();  // 1 
     Nop();  // 1 
     Nop();  // 1 
     Nop();  // 1 
     Nop();  // 1 
     Nop();  // 1 
     Nop();  // 1 
     ClrWdt(); // 1 
    } while(--us); // 3 
} 
+0

И я обнаружил, что это было еще точнее! :) – Christian

1

Руководство MCC объясняет очень простую математику, которая участвует в создании циклов задержки. Вы можете просто реализовать свой собственный цикл вместо того, чтобы полагаться на функции задержки библиотеки.

+0

Спасибо за комментарий! Плохо ли полагаться на библиотеку? – Christian

0

Я обнаружил, что это сделало мою задержку нам гораздо более точное:

void Delay_uS(byte uSec) { 

    do { 
     Delay1TCY();   // 1 
     Delay1TCY();   // 1 
     Delay1TCY();   // 1 
     Delay1TCY();   // 1 
     Nop();      // 1 
     Nop();      // 1 
     Nop();      // 1 
     ClrWdt();      // 1; Clear the WDT 
     } while(--uSec);  // 3 
} 

Любые другие идеи или отвечено относительно этого?

Благодаря Dario G на .... другой форум;)

+1

Что произойдет, если во время этой задержки произойдет прерывание? –

2

Часть неточностью может быть связано с оценкой выражения, вычисляет значение, которое передается в Delay10TCYx. Поскольку это выражение содержит деление, для вычисления этого значения может потребоваться некоторое время.

0

Я слышал, что это будет еще более точным, но мой оциллоскоп просто дает мне другие значения, затем правильные. Может ли это что-то делать, когда я компилирую ?? Что я не делаю этого на самом высоком уровне?

#define CONST_RANGE(min, val, max) (sizeof(char (*)[(val) >= (min) && (val) <= (max) ? +1 : -1]), (val)) 
#define Delay_ms(n) Delay1KTCYx(CONST_RANGE(1, (n) * 12L, 255)) 
#define Delay_us(n) Delay10TCYx(CONST_RANGE(1, ((n) * 12L + 6)/10, 255)) 
Смежные вопросы