Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры
Войти
Регистрация
Восстановить пароль
 
Auratos
0 / 0 / 1
Регистрация: 07.08.2014
Сообщений: 59
1

Компаратор в микроконтроллере PIC18F25K22 (MPLAB C18) - Микроконтроллеры

03.08.2017, 15:24. Просмотров 437. Ответов 1
Метки нет (Все метки)

Добрый день. В данный момент у меня на руках плата с контроллером PIC18F25K22 и проект от предыдущего сотрудника. Если очень рассказать очень сжато суть проекта, то есть первичный преобразователь расхода, который состоит из магнито-механического клапана, поршня и катушки индуктивности, обеспечивающей индикацию перемещения поршня в клапане и частичное управление поршнем. При открытии клапана на катушке формируется положительный потенциал, что может быть установлено с помощью компаратора, настроенного на верхний предел (ножка RA4, она же C1OUT). При закрытии клапана на катушке формируется отрицательный потенциал, что приводит к срабатыванию компаратора, если он настроен на нижний предел.

Так вот, весь механизм фиксации открытия/закрытия клапана построен на 7 ключевых точках, в которых мониторятся определенные состояния и производятся определенныедействия. Компаратор настроен так:
C
1
2
3
4
5
6
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 высокий
И обработчик его прерывания:
C
1
2
3
4
5
6
7
8
9
10
void high_isr()
{
     if (PIR2bits.C1IF)               // прерывание от компаратора
    {
            if ((PIE2bits.C1IE) && (T3CONbits.TMR3ON == 0)) // если прерывания от компаратора разрешены и таймер TMR3 свободен
                FFComparator1Interrupt();           // войти в обработчик прерываний компаратора
            CM1CON0bits.C1OUT = 0;                     // выставить 0 на выходе компаратора
            PIR2bits.C1IF = 0;           // сбросить флаг прерывания
    }
}
Все начинается с состояния PPR_CLOSE:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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:

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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) Связаны ли эти два действия вообще друг с другом и как?
И если кому то интересно, то вот изображение самого сигнала (измеряемый промежуток находится между вертикальными пунктирными линиями):
0
Миниатюры
Компаратор в микроконтроллере PIC18F25K22 (MPLAB C18) - Микроконтроллеры  
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
03.08.2017, 15:24
Ответы с готовыми решениями:

Кодировка для кириллицы (MPLAB C18)
Добрый день. Столкнулся с такой проблемой, что при размещении данных во флеш-памяти, символы...

PIC18F25K22. Максимальная скорость передачи по USART
Добрый день. Попала ко мне в руки платка с контроллером PIC18F25K22 и проект для нее. Стоит внешний...

Компилятор mcc18 (C18), ограничения sprintf
Добрый день. У меня есть число типа float. Необходимо его записать в массив, дополнив целую и...

C18 Функция Strtok - считывается только первое число строки
Добрый день. У меня возникла необходимость парсить большое количество строк и вычленять числа из...

Компаратор
Нужно отсортировать 1. за классом 2.за буквой класса 3.за фамилией package dela; import...

1
Ethereal
7352 / 2193 / 299
Регистрация: 17.02.2013
Сообщений: 3,235
05.08.2017, 02:10 2
Цитата Сообщение от Auratos Посмотреть сообщение
1. зачем по окончании обработки прерывания компаратора выставляется CM1CON0bits.C1OUT = 0 ?
Он НЕ выставляется. Согласно pdf-ке на этот контроллер бит CM1CON0bits.C1OUT есть бит только на чтение.
Значит CM1CON0bits.C1OUT = 0 - это просто операция ЧТЕНИЕ/МОДИФИКАЦИЯ/ЗАПИСЬ над регистром CM1CON0, которая НИЧЕГО В НЕМ НЕ ИЗМЕНИТ. Опять таки согласно pdf-ке такая операция очистит mismatch condition (т.е. то, что взвело флаг прерывания). Видимо, для этого она и делается. А дальше разбирайся сам, я этот МК в глаза не видел. Только в pdf-ку глянул на ключевые места.

Добавлено через 7 минут
З.Ы. Чтобы очистить mismatch condition вообще говоря надо прочитать из регистра CM1CON. Но если пишешь на Си результат чтения надо пихнуть в какую-то переменную и тут-же про него забыть. Типа выкрасить и выбросить. Чтобы не заводить для такого глупого дела лишнюю переменную, программист видимо и написал CM1CON0bits.C1OUT = 0. Эта строчка оттранслируется в инструкцию BCF , а эта инструкция работает как чтение/модификация/запись, т.е. чтение тоже производит.

Добавлено через 10 минут
Цитата Сообщение от Auratos Посмотреть сообщение
// выставить 0 на выходе компаратора
Этот комментарий видимо ты уже написал. Ибо он не по делу.
0
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.08.2017, 02:10

Компаратор
Есть класс: public clas SortedList<E>{ E arrays; } Как сравнить элемента...

Компаратор
Есть такой код: import java.util.Arrays; import java.util.Comparator; class Product { ...

RC-ОУ- Компаратор
Здравствуйте. Подскажите пожалуйста, как к RC фильтру на ОУ приделать компаратор, чтоб от...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
2
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru