2014-10-18 3 views
0

(я с удовольствием размещать код, если кто-то может указать на то, как вставить его здесь без использования системы 4 пространства отступа, который не работает)настройки CCS PICC КПК

Привет люди После ~ 9hours ломая мозги, я не могу найти ответ или найти, где мои расчеты идут не так ... но они есть. У меня есть схема, построенная с использованием микроконтроллера микрочипа 18F2550. Я использую эту схему для измерения задержки между двумя сигналами и использую 2 регистра CCP в режиме захвата. Все это работает, и результат отправляется на ПК (через USB-последовательный порт) все денди, но результаты неверны. Я должен применить усиление ~ 16000 к любым результатам, чтобы получить где-то около задержки, представленной на контактах.

У меня есть задержки, установленные в линии
Таймер1 устанавливаются в качестве внутреннего
Таймера 3 отключен
соответствующих прерывания разрешены

и основных рутинных работает непрерывно. Когда я восходящая обнаружение края на CCP1 штифте, прерывание выполнено с возможностью сброс Timer1 к нулю, а также счетчик переполнения

#INT_CCP1 
    void ccp1_isr() // Captures the rising edge of CCP1 pin. 
    { 
     if(timing==FALSE){ // only do this on the edge, any bouncing will reset timers etc. 
      set_timer1(0); 
      T1_Overflow = 0; 
      Pulse_Time = 0; 
      timing = 1;  // Set flag to indicate timing. 
      output_high(BLUE_LED); 
     } 
    } 

timing флага обеспечивает времена не могут быть сброшены с помощью другого импульса на CCP1 штырь. Затем Timer1 следует сбросить и начать считать как обычно. Каждый раз, когда он поворачивается на 65535 (16-битное устройство), запускается другое прерывание, после которого увеличивается количество переполнений.

#INT_TIMER1 
    void isr() 
    { 
     T1_Overflow++; 
    } 

И наконец, когда входной контакт на CCP2 идет высоко, происходит прерывание CCP_2. Это фиксирует значение регистра CCP (которое является значением Timer0 во время запуска прерывания) и регистра переполнения.

#INT_CCP2 
    void ccp2_isr()     
    { 
     if(timing == TRUE){ // only output this when preceded by CCP1 
      if(Count_Done == FALSE) // do this once only 
      { 
       Count_Done = TRUE; // and also flag to the main routine to output data to the terminal. 
       Pulse_time = CCP_2; 
       Pulse_Overflow = T1_Overflow; 
       measureCount++;  // increment the number of measures. 
      } 
      output_low(BLUE_LED); 
      timing = FALSE; 
     } 
    } 

CCP1 теперь может снова начать отвечать на входы. Идея состоит в том, что каждый раз, когда я получаю импульс одного входа на CCP1, за которым следует CCP2, строка посылается на терминал с помощью счетчика, количества переполнений и времени, оставшегося в таймере.

while(TRUE)      // do forever while connected 
    {  
     usb_task();       // keep usb alive  
     if(Count_Done == TRUE) 
     { 
      printf(usb_cdc_putc, "%lu , %lu , %lu \r\n",measureCount, pulse_time, pulse_overflow); 
      Count_Done = FALSE; 
     } 

так, что я должен получить выход к терминалу что-то вроде «1,61553,35» для ~ задержки 12ms между CCP1 и CCP2. Проблема заключается в том, что это результаты, которые я получаю для импульса в 200 мсек, подаваемого в схему. (Проверено дважды)

так, где я иду не так. У меня есть 48MHZ Clock без предварительного делителя, который подразумевает цикл каждые 20 нс. Разделите на 4 инструкции за такт на часы, что означает 5.2ns каждый цикл 16-разрядный таймер, который предполагает опрокидывание каждые 65535 * 5.2ns = 341us за опрокидывание. , когда вы выполняете вычисления (0.000341 * pulse_overflow) + pulse_time * (5.2 * (10^-9)) , тогда приведенные выше данные дают 0012.27мс, а не 200 мс.

Может ли кто-нибудь указать, где я ошибаюсь при этих расчетах ???

+0

код не удается, во время любого прерывания, чтобы сбросить флаг прерывания, связанный , Это означает, что следующее прерывание для этого источника прерывания произойдет сразу же после возврата из прерывания. – user3629249

+0

Функция прерывания ccp1_isr() должна инициализировать регистры timer1 и запустить подсчет таймера 1. В документации, счетчик таймера подсчитывает 1 раз для каждого тактового цикла «источник», поэтому скорость счета будет 1/48000000 секунд, а не каждый 5.2nsec – user3629249

+0

функция прерывания ccp2_isr() должна остановить таймер 1 от подсчета, иначе он будет продолжать подсчет и (при переполнении) увеличивать переменную T1_Overflow. – user3629249

ответ

1

Ваша ошибка в «Разделить на 4 инструкции за цикл для часов, что подразумевает 5.. 2ns каждый цикл»

Счетчик клещей один раз каждые 4 цикла, а не в 4 раза за цикл Итак, правильные расчеты:

2.08333E-08 с/цикл OSC

8.33333E-08 s/тик таймера

0,005461333 сек/опрокидывание

Вы выключены на фактор 16.

+0

Я только что это заметил, спасибо (серьезно, я сделал !!!) – deadlyBuzz

+0

Я только что заметил это, спасибо (серьезно, я сделал !!!) Я хотел бы поблагодарить вас и проголосовать, но мне не хватает репутации. У меня есть еще одна проблема, которую вы можете мне помочь. – deadlyBuzz

+0

как только я заполнил приведенные выше вычисления правильными смещениями: - | Я все еще не получаю правильных результатов от расчета. У меня есть схема, подключенная к ПЛК, генерирующему импульс 200 мс между настройкой 2 выходов, но моя схема, кажется, читает ~ 198 мс в среднем только с 9% показаний за 200 мс. Я ожидал некоторых неточностей из-за частоты обновления ПЛК ввода-вывода и обновлений цикла сканирования, сопоставленных с вводом-выводом, но это должно сделать показания более 200 мс, не менее. Я снова пересчитал расчеты, и я не вижу, откуда происходят издержки. – deadlyBuzz