Auratos 0 3 августа, 2017 Опубликовано 3 августа, 2017 · Жалоба Добрый день. В данный момент у меня на руках плата с контроллером PIC18F25K22 и проект от предыдущего сотрудника. Если очень рассказать очень сжато суть проекта, то есть первичный преобразователь расхода, который состоит из магнито-механического клапана, поршня и катушки индуктивности, обеспечивающей индикацию перемещения поршня в клапане и частичное управление поршнем. При открытии клапана на катушке формируется положительный потенциал, что может быть установлено с помощью компаратора, настроенного на верхний предел (ножка RA4, она же C1OUT). При закрытии клапана на катушке формируется отрицательный потенциал, что приводит к срабатыванию компаратора, если он настроен на нижний предел. Так вот, весь механизм фиксации открытия/закрытия клапана построен на 7 ключевых точках, в которых мониторятся определенные состояния и производятся определенныедействия. Компаратор настроен так: TRISAbits.RA4 = 0; // установить порт RА4 на выход (выход компаратора) PORTAbits.RA4 = 0; CM1CON0bits.C1POL = 0; // логика на C1OUT не инвертирована CM1CON0bits.C1SP = 0; // компаратор работает в режиме малой мощности и низкой скорости CM1CON0bits.C1R = 0; CM1CON0bits.C1CH = 1; // выставить канал компаратора на верхний предел IPR2bits.C1IP = 1; // приоритет прерываний от компаратора C1 высокий И обработчик его прерывания: void high_isr() { if (PIR2bits.C1IF) // прерывание от компаратора { if ((PIE2bits.C1IE) && (T3CONbits.TMR3ON == 0)) // если прерывания от компаратора разрешены и таймер TMR3 свободен FFComparator1Interrupt(); // войти в обработчик прерываний компаратора CM1CON0bits.C1OUT = 0; // выставить 0 на выходе компаратора PIR2bits.C1IF = 0; // сбросить флаг прерывания } } Все начинается с состояния PPR_CLOSE: void FFComparator1Interrupt() { switch(PPR.State) { case PPR_CLOSE: DelayInterrupt = 0; //исключаем пересечения if (CM1CON0bits.C1CH == 1) // если компаратор переключен на верхний порог (т.е. фиксируем движение клапана) { PPR.State = PPR_START_OPEN; // изменить состояния клапана на "Начал открываться" PIE2bits.C1IE = 0; // отключить прерывания от компаратора PORTAbits.RA4 = 1; // поднять уровень сигнала на линии TAU CM1CON0bits.C1OE = 0; // отключить выход компаратора (не реагировать на изменения на выходе) timer3Delay(2); // установить задержку в 2мс DelayInterrupt = 1; // выставить флаг для обработчика прерываний таймера TMR3 } else { CM1CON0bits.C1CH = 1; // переключить компаратор на верхний порог } break; } return; } В следующем же состоянии PPR_START_OPEN: void FFTimerEvent() { switch(PPR.State) { case PPR_START_OPEN: if (CM1CON0bits.C1CH == 1) // если компаратор переключен на верхний порог { if (CM1CON0bits.C1OUT == 1) // если клапан действительно открывается { timer3Delay(40); // установить задержку в 40мс для исключения дребезга DelayInterrupt = 1; // выставить флаг для обработчика прерываний таймера TMR3 PPR.State = PPR_PRE_OPEN;// изменить состояния клапана на "Почти открылся" StateChanged = 1; // выставить флаг о смене состояния клапана } else // иначе это был дребезг { PPR.State = PPR_CLOSE; CM1CON0bits.C1OE = 1; // подключить выход компаратора PIR2bits.C1IF = 0; // сбросить флаг прерывания компаратора PIE2bits.C1IE = 1; // включить прерывания от компаратора } } else { CM1CON0bits.C1CH = 1; // переключить компаратор на верхний порог timer3Delay(1); // установить задержку в 1мс DelayInterrupt = 1; // выставить флаг для обработчика прерываний таймера TMR3 } break; } } При попытке разобраться возникли спорные моменты: подскажите, пожалуйста 1. зачем по окончании обработки прерывания компаратора выставляется CM1CON0bits.C1OUT = 0 ? 2. зачем в след. за первым состоянием мониторится CM1CON0bits.C1OUT == 1, когда только что был CM1CON0bits.C1OUT = 0 ? Что мы просто мониторим в данном случае, и что сейчас на выходе компаратора реально? 3. действие PORTAbits.RA4 = 1 в первом состоянии не идентично CM1CON0bits.C1OUT = 1? Просто по даташиту Pin #6 = RA4 (C1OUT, SRQ, CCP5, T0CKI) Связаны ли эти два действия вообще друг с другом и как? И если кому то интересно, то вот изображение самого сигнала (измеряемый промежуток находится между вертикальными пунктирными линиями): Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться