|
pic18fxxx, CCP, Capture mode, помогите правильно измерить время между импульсами |
|
|
|
Sep 16 2008, 06:55
|
Участник

Группа: Свой
Сообщений: 47
Регистрация: 15-09-08
Из: Россия, Москва, САО
Пользователь №: 40 220

|
задача: померить время между импульсами, с разрешением 0.1us. Максимальная длительность между импульсами - 1.5sec моё решение: настраиваю собственно CCP, прерывание по захвату ССP и по переполнению таймера. в прерывании по переполнению таймера - увеличиваю доп переменную. в прерывании по захвату ССP - сохраняю захваченные значения и доп переменную. суть проблемы: для перехода в прерывание требуется минимум три такта микроконтроллера, + анализ флажков источников прерывания (дабы понять источник прерывания) так вот если захват происходит либо за 3-4 такта до переполнения таймера либо чуть после, подняты оба флажка. И как понять происходил захват до переполнения таймера или после? Всё что я придумала - это анализировать захваченные данные, но очень хочется узнать как поступают здравомыслящие люди
|
|
|
|
|
Sep 17 2008, 10:36
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(Короткова Светлана @ Sep 16 2008, 05:55)  суть проблемы: для перехода в прерывание требуется минимум три такта микроконтроллера, + анализ флажков источников прерывания (дабы понять источник прерывания) так вот если захват происходит либо за 3-4 такта до переполнения таймера либо чуть после, подняты оба флажка. И как понять происходил захват до переполнения таймера или после? Всё что я придумала - это анализировать захваченные данные, но очень хочется узнать как поступают здравомыслящие люди  Можно сделать так. 1) Назначаете прерывания по захвату и по переполнению на вектор с высоким приоритетом. 2) При возникновении прерывания проверяете флаг захвата. - Если есть захват, то проверяете захваченное время на 0, если 0, то копируете доппеременную в другую ячейку и добавляете к ней 1, т.к. перенос мог возникнуть только в единственном случае, когда в регистре таймера было 0хFFFF и стало 0х0000. Если не 0, то просто копируете доппеременную в другую ячейку. - Если нет захвата, то переходите к п.3 3) Проверяете флаг переполнения, если есть переполнение, то инкрементируете доппеременную, иначе выходите из прерывания.
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Sep 17 2008, 11:00
|
Участник

Группа: Свой
Сообщений: 47
Регистрация: 15-09-08
Из: Россия, Москва, САО
Пользователь №: 40 220

|
Цитата(=GM= @ Sep 17 2008, 13:36)  т.к. перенос мог возникнуть только в единственном случае, когда в регистре таймера было 0хFFFF и стало 0х0000. вот как то у меня этот фрагмент вызывает подозрение. вот начало моего обработчика: org 08h movwf WTempH,0 movff STATUS,StatusTempH
btfsc PIR1,TMR1IF,0 ; прерывание от таймера1 ?. bra @TMR1 ; да, переход
btfsc PIR1,CCP1IF,0 ; прерывание от CCP1 ? bra @CCP1 ; да, переход
btfsc PIR2,CCP2IF,0 ; прерывание от CCP2 ? bra @CCP2 ; да, переход
btfsc PIR3,CCP3IF,0 ; прерывание от CCP3 ? bra @CCP3 ; да, переход
btfsc PIR3,CCP4IF,0 ; прерывание от CCP4 ? bra @CCP4 ; да, переход
btfsc PIR3,CCP5IF,0 ; прерывание от CCP5 ? bra @CCP5 ; да, переход
захват от CCP1 может произойти на проверки флага CCP5IF (последней строчке), а переполнение таймера скажем на проверке CCP3IF => захваченное время CCP1 будет уже не равно 0х0000. ... и вот скажите как с этим жить ?  PS сорьки, табуляторы форумом не парсируются, а тег я не помню
Сообщение отредактировал Короткова Светлана - Sep 17 2008, 11:14
|
|
|
|
|
Sep 17 2008, 12:26
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(Короткова Светлана @ Sep 17 2008, 10:00)  захват от CCP1 может произойти на проверки флага CCP5IF (последней строчке), а переполнение таймера скажем на проверке CCP3IF => захваченное время CCP1 будет уже не равно 0х0000 Немного не так, я уже говорил как, читайте как, и смотрите фрагмент ниже Код org 0x0008 movwf WTempH,0 movff STATUS,StatusTempH ccp1int btfss PIR1,CCP1IF,0 ; прерывание от CCP1? bra tim1ovf ; нет, продолжим разбор movff CCPR1L,newtim0 ; захваченное movff CCPR1H,newtim1 ; время и movff auxbyt3,newtim3 ; дополнительный байт movwf newtim0 ; проверим захваченное iorwf newtim1 ; время на 0 bnz tim1ovf ; не было переполнения incf newtim3 ; учтём переполнение для newtim tim1ovf btfsc PIR1,TMR1IF,0 ; прерывание от таймера1? incf auxbyte3 ; учтём перенос
btfsc PIR2,CCP2IF,0 ; прерывание от CCP2? bra @CCP2 ; да, переход btfsc PIR3,CCP3IF,0 ; прерывание от CCP3? bra @CCP3 ; да, переход btfsc PIR3,CCP4IF,0 ; прерывание от CCP4? bra @CCP4 ; да, переход btfsc PIR3,CCP5IF,0 ; прерывание от CCP5? bra @CCP5 ; да, переход Здесь вы сначала проверяете, нет ли прерывания по захвату и делаете что надо, потом проверяете прерывание по переполнению, а уж потом разбираете все оставшиеся прерывания, так что при разборе захвата и переполнения никаких доппрерываний не будет. И будет вам щастье. Теги такие: [ code] без пробелов, админы для общего удобства сделали кнопочку #.
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Sep 17 2008, 23:58
|
Участник

Группа: Свой
Сообщений: 47
Регистрация: 15-09-08
Из: Россия, Москва, САО
Пользователь №: 40 220

|
Цитата(=GM= @ Sep 17 2008, 15:26)  Немного не так, я уже говорил как, читайте как, и смотрите фрагмент ниже Меня всегда радовали люди с четкой аргументацией поэтому на этот раз приготовила свой аргумент в двух вариантах вариант I. (словесный) Если в вашем коде, произойдёт сначала прерывание по переполнению TMR1, а вслед за этим захват CCP1, то при проверке захваченное значение будет однозначно больше нуля. вариант II. (в картинках) я загрузила ваш кусочек кода в MPLAB и пошагала по вашему алгоритму. результат можно посмотреть во флеш по ссылке http://korotkovasvetlana.by.ru/CCP.htm, или отсюда
ccp.zip ( 965.72 килобайт )
Кол-во скачиваний: 105. расскажите какой вариант понравился больше
|
|
|
|
|
Sep 18 2008, 02:37
|
Группа: Новичок
Сообщений: 12
Регистрация: 7-12-07
Из: Россия, Москва
Пользователь №: 33 072

|
Сообщение отредактировал konstanta - Sep 18 2008, 02:37
--------------------
.
|
|
|
|
|
Sep 18 2008, 09:32
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(Короткова Светлана @ Sep 17 2008, 22:58)  Если в вашем коде, произойдёт сначала прерывание по переполнению TMR1, а вслед за этим захват CCP1, то при проверке захваченное значение будет однозначно больше нуля Если в моём коде сначала произойдёт прерывание по переполнению TMR1, то будет скорректирован дополнительный байт auxbyt3, если затем произойдёт захват CCP1, то при проверке захваченное значение естественно будет больше нуля, и допбайт времени auxbyt3 будет благополучно скопирован в байт newtim3 без инкрементирования. Ну и что здесь неверного? Создаётся впечатление, что вы не понимаете идеи моего кода, придётся немного поаргументировать, чтобы вы тоже порадовались. Рассмотрим ситуацию с точки зрения системного времени Т, системных тиков, если хотите, которые фиксирует таймер1 в переменных time2, time1, time0 (две последние переменные по сути - регистры таймера). Время захвата фиксируется в переменных capt2, capt1, capt0 (две последние переменные по сути - регистры схемы захвата). Ситуация 1. T=0xFFFF. Прерывания по переполнению нет, и может возникнуть прерывание захвата. Если прерывание захвата возникло, capt2=time2=0х02(произвольно), capt1=time1=0xFF, capt0=time0=0xFF. Что и должно быть. Ситуация 2. T=0x0000. Есть прерывание по переполнению, и может возникнуть прерывание захвата. Если прерывание захвата возникло, в моём коде оно обрабатывается первым, тогда capt2=time2=0х02, capt1=time1=0x00, capt0=time0=0x00. Поскольку время захвата равно 0х0000, переменная capt2=capt2+1=0х03. После этого, обрабатывается прерывание от таймера, и независимо от наличия прерывания захвата, корректируется переменная time2=time2+1=0х03. Как видите, полёт нормальный. Ситуация 3. T=0x0001. Прерывания по переполнению нет, и может возникнуть прерывание захвата. Если прерывание захвата возникло, capt2=time2=0х03, capt1=time1=0x00, capt0=time0=0x00. Как видите, в любой ситуации время появления внешнего события соответствует времени захвата. Вопрос по приведённому алгоритму. Почему вы инкрементируете CCP1U, если у вас не было прерывания захвата?
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Sep 18 2008, 13:08
|
Участник

Группа: Свой
Сообщений: 47
Регистрация: 15-09-08
Из: Россия, Москва, САО
Пользователь №: 40 220

|
Цитата(DL36 @ Sep 18 2008, 08:26)  Посмотрите на телесистемах, было интересное решение для захвата в 32 бита. Пересмотрела всю конференцию где упоминалось про CCP. Потратила час времени. Нет ни одного обсуждения сохранения хотя бы флажка переполнения таймера!!! Вы вероятно имели ввиду ветку Можно ли используя аппаратные возможности Capture/Compare (Timer_B) в MSP430F149, реализовать 4 счетчика внешних импульсов (32-разрядные), с частотой счета до 1МГц? (МК работает на 8МГц) так это как говорится ноу коментс... Цитата(=GM= @ Sep 18 2008, 12:32)  Создаётся впечатление, что вы не понимаете идеи моего кода, придётся немного поаргументировать, чтобы вы тоже порадовались. Уважаемый =GM=, я крайне благодарна Вам за Вше внимание к проблеме. Однако очень прошу вас отойти от мысли, что Вас не понимают. Ваша идея мне понятна как 5 копеек! И я всячески пытаюсь обратить Ваше внимание на её неработоспособность, уже и в картинках и развлекательных видеофильмах  Попробуйте хоть на 10 минут посмотреть с позиции, что что-то в вашем алгоритме не так. И тогда у нас скорее всего получится нормальное обсуждение. Цитата(=GM= @ Sep 18 2008, 12:32)  Если в моём коде сначала произойдёт прерывание по переполнению TMR1, то будет скорректирован дополнительный байт auxbyt3, если затем произойдёт захват CCP1, то при проверке захваченное значение естественно будет больше нуля, и допбайт времени auxbyt3 будет благополучно скопирован в байт newtim3 без инкрементирования. Ну и что здесь неверного? Да и мне тоже сначала так показалось. Давайте предположим что этот "...если затем произойдёт захват CCP1, то..." произойдёт на первой или второй строчке нашего обработчика прерывания. тогда оба флажка будут в 1! и CCP1IF и TMR1IF, рассмотрите пожалуйста эту ситуацию! Именно она продемонстрирована на диафильме Цитата(=GM= @ Sep 18 2008, 12:32)  Рассмотрим ситуацию с точки зрения системного времени Т, системных тиков, если хотите, которые фиксирует таймер1 в переменных time2, time1, time0 (две последние переменные по сути - регистры таймера). Время захвата фиксируется в переменных capt2, capt1, capt0 (две последние переменные по сути - регистры схемы захвата). Ok давайте рассмотрим. Цитата(=GM= @ Sep 18 2008, 12:32)  Ситуация 1. T=0xFFFF. Прерывания по переполнению нет, и может возникнуть прерывание захвата. Если прерывание захвата возникло, capt2=time2=0х02(произвольно), capt1=time1=0xFF, capt0=time0=0xFF. Что и должно быть. Не вызывает сомнений! 5+ Цитата(=GM= @ Sep 18 2008, 12:32)  Ситуация 2. T=0x0000. Есть прерывание по переполнению, и может возникнуть прерывание захвата. Если прерывание захвата возникло, в моём коде оно обрабатывается первым, тогда capt2=time2=0х02, capt1=time1=0x00, capt0=time0=0x00. Поскольку время захвата равно 0х0000, Вот давайте посчитаем! Команды перехода выполняются за два таката, следовательно значение таймера будет=2. а вы только на на адресе 0008h и до первого btfss CCP1IF надо ещё сохранить WREG, а если сейчас произойдет захват? захваченное значение будет 0002h, (и появится флаг CCP1IF см диафильм) Цитата(=GM= @ Sep 18 2008, 12:32)  Ситуация 3. T=0x0001. Прерывания по переполнению нет, и может возникнуть прерывание захвата. Если прерывание захвата возникло, capt2=time2=0х03, capt1=time1=0x00, capt0=time0=0x00. тут я не поняла почему не возникло прерывание по таймеру... Цитата(=GM= @ Sep 18 2008, 12:32)  Вопрос по приведённому алгоритму. Почему вы инкрементируете CCP1U, если у вас не было прерывания захвата? предположим у меня только два источника прерывания, ССP1 и TMR1. Ну может конечно я чего то недопонимаю, Но тогда вам нужно дать конкретный комментарий именно к тому месту моих рассуждений который вам кажется неверным. А не просто повторять свою идею да ещё в мельчайших подробностях. Пожалуйста обратите внимание на ход моих мыслей!
|
|
|
|
|
Sep 18 2008, 14:14
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(Короткова Светлана @ Sep 18 2008, 12:08)  Вот давайте посчитаем! Команды перехода выполняются за два такта, следовательно значение таймера будет=2. а вы только на на адресе 0008h и до первого btfss CCP1IF надо ещё сохранить WREG, а если сейчас произойдет захват? захваченное значение будет 0002h Ну не так вы всё интерпретируете. Рассмотрим ситуацию 2, когда системное время Т=0х0000. 1) Возникают одновременно ДВА прерывания: захват и переполнение. Причём заметьте, переполнение может возникнуть только при Т=0х0000, надеюсь, что вам это очевидно. 2) Что такое захват? По фронту входного импульса, который вы измеряете, происходит ПЕРЕЗАПИСЬ содержимого таймера в регистры модуля захвата и оно не меняется до прихода следующего фронта. какое там будет значение? Ну конечно, 0х0000. 3) В прерывании по захвату вы спокойно, не торопясь, переписываете содержимое регистров модуля захвата в ячейки памяти capt2=time2 (ваша доппеременная системного времени), capt1=CCPR1Н, capt0=CCPR1L. 4) Проверяете, не ноль ли у вас в ячейках capt1, capt0? Там действительно ноль. Значит, говорите вы себе, в прерывании по таймеру надо будет учесть перенос, и в захваченном времени надо учесть, давайте я его учту добавлением единицы к capt2, да и всё. 5) Позволяете отработать остальной части кода, а именно, прерыванию по переполнению, чтобы текущее время было адекватным. (Замечу в скобках, время в таймере по-прежнему бежит, но кого это волнует? Поскольку мы точно зафиксировали момент наступления фронта входного импульса и подправили доппеременную ЗАХВАЧЕННОГО системного времени). Цитата(Короткова Светлана @ Sep 18 2008, 12:08)  тут я не поняла почему не возникло прерывание по таймеру... Потому что оно может возникнуть при Т=0х0000, но никак не при Т=0х0001. Ну что тут непонятного? Как таймер считает? 0х0000, 0х0001, 0х0002,..., 0хFFFF, затем 0х0000 и ПЕРЕНОС, 0х0001, 0х0002, и т.д. Перенос надо учесть в доппеременной, что и делается в моём коде в прерывании по переполнению, а именно, инкрементируется переменная time2.
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Sep 18 2008, 14:48
|
Участник

Группа: Свой
Сообщений: 47
Регистрация: 15-09-08
Из: Россия, Москва, САО
Пользователь №: 40 220

|
Цитата(=GM= @ Sep 18 2008, 17:05)  1) Возникают одновременно ДВА прерывания: захват и переполнение. Причём заметьте, переполнение может возникнуть только при Т=0х0000, надеюсь, что вам это очевидно. Очевидно что в этой ситуации проблем нет, но я вас очень прошу рассмотреть ситуацию когда захват произойдет между переполнением таймера+1такт и началом анализа флага CCP1IF. тогда захваченное значение не будет равно нулю! Цитата(=GM= @ Sep 18 2008, 17:05)  2) Что такое захват? По фронту входного импульса, который вы измеряете, происходит ПЕРЕЗАПИСЬ содержимого таймера в регистры модуля захвата и оно не меняется до прихода следующего фронта. какое там будет значение? Ну конечно, 0х0000. Пожалуйста давайте не будем рассматривать нижележащие пункты а остановимся на этом! Я на всякий случай опишу эту ситуацию: 1. Значение таймера FFFFh 2. В следующем такте происходит прерывание по переполнению таймера. 3. Мы оказываемся в обработчике прерывания по адресу 0008h (значение таймера=0002h) 4. происходит захват. (захваченное значение 0002h). и далее по вашему алгоритму.... Давайте сначала рассмотрим эту ситуацию! Цитата(=GM= @ Sep 18 2008, 12:32)  Ситуация 3. T=0x0001. Прерывания по переполнению нет, и может возникнуть прерывание захвата. Если прерывание захвата возникло, capt2=time2=0х03, capt1=time1=0x00, capt0=time0=0x00. мне было не понятно как при "T=0x0001" может "capt1=time1=0x00, capt0=time0=0x00" Цитата(=GM= @ Sep 18 2008, 17:14)  Потому что оно может возникнуть при Т=0х0000, но никак не при Т=0х0001. Ну что тут непонятного? Как таймер считает? 0х0000, 0х0001, 0х0002,..., 0хFFFF, затем 0х0000 и ПЕРЕНОС, 0х0001, 0х0002, и т.д. Перенос надо учесть в доппеременной, что и делается в моём коде в прерывании по переполнению, а именно, инкрементируется переменная time2. 1. "Потому что оно может возникнуть при Т=0х0000, но никак не при Т=0х0001" 2. "Как таймер считает? 0х0000, 0х0001, 0х0002,..." 3. "T=0x0001" исходя из вышеизоженных вами правил становится непонятно как при T=0x0001 [пункт 3] не возникло прерывания, которое обязано было возникнуть ещё при Т=0х0000 [пункт 1], исходя из [пункта 2]. Но это я просто ответила на вопрос что мне было непонятно. давайте это обсудим после рассомтрения синутации выше.
Сообщение отредактировал Короткова Светлана - Sep 18 2008, 14:49
|
|
|
|
|
Sep 18 2008, 17:33
|
Участник

Группа: Свой
Сообщений: 47
Регистрация: 15-09-08
Из: Россия, Москва, САО
Пользователь №: 40 220

|
Цитата(=GM= @ Sep 18 2008, 18:49)  Похоже, у вас какое-то фундаментальное недопонимание(:-). Давайте откатимся назад, расскажите, что вы хотите измерить, как планируете измерить, какие сигналы и куда вы подключаете, и какие делаете настройки. Ну и приведите соответствующие фрагменты программ. Конечно же я могу все рассказать но зачем? я прошу вас разобрать конкретную ситуацию, прошу прокомментировать неадекватное поведение вашего кода который вы приводили. А в ответ не получаю ни йотую долю внимания к СВОИМ вопросам! У меня встречное предложение. Давайте сначала закончим разбор вашего кода, а затем двинемся дальше. PS. поймите правильно, я конечно же в курсе что всё можно решить на ПЛИС, DSP итд... но меня интересует именно МОЙ вопрос.
|
|
|
|
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|