Добрый день. В данный момент у меня на руках плата с контроллером 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) Связаны ли эти два действия вообще друг с другом и как?
И если кому то интересно, то вот изображение самого сигнала (измеряемый промежуток находится между вертикальными пунктирными линиями):
Нажмите для просмотра прикрепленного файла