Задержка в MCC18, 48 МГц, 18F87J50 - PullRequest
1 голос
/ 25 декабря 2009

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

Что у меня сейчас есть:

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

И это не похоже на мой осциллограф! : /

С уважением!

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

Ответы [ 5 ]

2 голосов
/ 28 декабря 2009

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

2 голосов
/ 26 декабря 2009

PIC делит часы на 4, поэтому для 48 МГц каждый код операции выполняется в 0,0833us или 12 циклах на нас. Я использовал MPLAB и ввел разные значения us и проверил в симуляторе, чтобы количество циклов получилось, как я и ожидал. Лучший способ настроить функцию - посмотреть на сборку или использовать симулятор.

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

#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
}
1 голос
/ 25 декабря 2009

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

0 голосов
/ 29 декабря 2009

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

#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))
0 голосов
/ 25 декабря 2009

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

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
}

Любые другие идеи или ответы по этому поводу?

Спасибо Дарио Г на .... другом форуме;)

...