Использование нескольких внешних прерываний в PIC


9

Я использовал PIC16F877( таблица данных ) для нескольких проектов. Для прерывания смены одного внешнего вывода вы можете использовать PORTB0прерывание. Но теперь мне нужно поддерживать 8 независимых внешних прерываний смены контактов в одной цепи.

В таблице указано, что в ней 15 прерываний PIC16F877, но я думаю, что они учитываются, включая прерывания по переполнению таймера и т. Д., Которые в этом случае бесполезны.

Это то, что технические данные говорят о INTCONрегистрации.

введите описание изображения здесь

Могу ли я иметь 4 независимых прерываний с помощью Bit0, RBIF? Это представляет изменение в PB7:PB4. Как я могу определить, какой контакт изменился, читая значение порта в процедуре прерывания?

Даже если я получу положительные ответы на выше, мне нужно 8 прерываний? конечно, я все еще могу использовать INTE, для PORTB0изменения. Тогда 4 + 1 = 5, а как насчет других 3? (Однако, учитывая, что все 8 событий прерывания относятся к одному и тому же типу, 4 + 1 + 3 = 8все выглядит ужасно, не правда ли?)

Никаких других тяжелых задач от микроконтроллера не ожидается, кроме мониторинга 8 контактов. (Говоря о других задачах, он должен будет поддерживать набор отдельных переменных счетчика и часто передавать около 4 байтов на ПК последовательно)

Любые предложения приветствуются. Даже если речь идет о замене микроконтроллера на более подходящий (но ... не говорите мне уходить от PICs).


2
Без использования прерываний, возможно, вы сможете отслеживать контакты в основной программе. Но это не идеально, хотя. В качестве альтернативы вы можете пойти на Arduino. Хотя это не PIC, это довольно просто, вы легко поймете, поскольку вы уже знакомы с PIC.
Анубис

1
Если вы используете прерывание RBIE, вы можете просто буферизовать предыдущее значение каждый раз и XOR, чтобы найти то, что изменилось. Должно быть довольно быстро выполнить.
PeterJ

@PeterJ я не совсем понял это. Буфер какое значение?
Кодовое название SC

@PeterJ отлично! жду ...
Кодовое название SC

1
Одним из способов является использование внешнего 8-входного вентиля (например, 74LS30 в прежние времена) для объединения внешних сигналов на один контакт прерывания. Поскольку 74 (HC) 30 является шлюзом NAND, вам потребуются все входы с высоким уровнем в состоянии покоя - их также необходимо подключить к выводам порта, чтобы вы могли определить, какие прерывания были активными, прочитав порт.
Брайан Драммонд

Ответы:


3

Это псевдокод C для объяснения одной идеи. Он использует исключительное ИЛИ для определения, какие контакты были изменены, и будет вызывать ваши разные обработчики в пределах одного прерывания RBIE. В зависимости от того, насколько критичным является приложение, вы можете проверить, как PIC обрабатывает такие ситуации, как изменение порта во время выполнения прерывания, чтобы убедиться, что вы не пропустите ни одного события.

int old_port_b;

void isr_handler()
{
    int new_port_b, changed_pins;
    new_port_b = read_port_b();
    changed_pins = new_port_b ^ old_port_b;
    if (changed_pins | 1)
        rb0_hander();
    if (changed_pins | 2)
        rb1_hander();
        // ... etc
    old_port_b = new_port_b;
}

int main()
{
    old_port_b = read_port_b();
    enable_interrupt();
}

Я понял, спасибо! но это не точный ответ, который я ищу. Таким образом, вы можете контролировать RB7:RB4только 4 контакта. Но я прошу способ контролировать 8 контактов. любое предложение?
кодовым названием SC

Я полагаю, есть причина, по которой вы не можете использовать RB0 - RB7, на который должно работать вышеупомянутое? В противном случае я не могу придумать способ, если быстрое выполнение кода не является жизненно важным, вы можете использовать вышеуказанный стиль кода в прерывании по таймеру (или просто в основном цикле).
PeterJ

Для этого PIC, если вам нужно использовать прерывания, чтобы сделать это, трюк XOR на RB4: RB7 и четыре прерывания для RB0: RB3 - путь. Если вам не нужно прерывание, просто опросите весь порт в вашем коде или используйте прерывание по таймеру для обработки опроса, если вам нужна жесткая частота дискретизации
Скотт Сейдман

and four interrupts for the RB0:RB3? PIC16F877 не поддерживает прерывания RB1:RB3, а?
кодовым названием SC

Я пропустил это в техническом описании, я предполагал, что это покрыло весь порт. Но я видел твой второй комментарий примерно раз в секунду, так что я думаю, что тебе будет лучше, просто запустив это в своем основном цикле. С прерываниями вам нужно позаботиться об обновлении переменных в любой точке во время выполнения и о том, как обрабатывать изменения выводов во время выполнения прерывания. Это действительно звучит так, как будто это только усложнит это без реальной выгоды. Единственное исключение, о котором я мог подумать, - это если вы хотите использовать wake from sleep для прерывания, и в этом случае вам понадобится аппаратный MUX.
PeterJ

1

Эта часть имеет только 4 прерывания смены контактов и еще несколько, которые вы можете установить на выбранных ребрах. Одной из стратегий будет внешнее обнаружение изменения 8-битного значения, а затем прерывание при несовпадении. Это становится грязным в оборудовании, но будет именно то, что вы хотите.

Важные параметры, которые вы не указали, это то, как быстро вам нужно реагировать на смену булавки, и какое минимальное время будет сохраняться для смены булавки, чтобы она действовала. В зависимости от ответов, вы можете опросить на основе регулярного прерывания в прошивке. 16F877 может работать с частотой команд 5 МГц, и проверка изменений займет всего несколько инструкций. Допустим, вы устанавливаете прерывание каждые 50 инструкций. Это оставило бы большую часть процессорного времени на переднем плане кода. Частота прерывания будет 100 кГц, а период 10 мкс. Конечно, передний план должен все еще видеть флаг изменения и что-то с ним делать, поэтому время отклика будет больше 10 мкс, но вы ничего не сказали о том, что вам нужно делать, когда обнаруживается изменение. Если это просто нужно ответить в человеческое время,


Извините за недостающие детали. В качестве ожидаемого ответа once per secondбудет достаточно. При обнаружении изменения пина (только одно ребро, скажем, повышение) счетчик (переменная) должен быть увеличен. В главном цикле он должен контролировать значения счетчика, и когда один становится выше определенного значения, четыре байта должны быть переданы через USARTПК. Затем сбросьте значение соответствующего счетчика до нуля. Просто как тот. Я думаю, что вариант опроса пойдет хорошо, верно?
Кодовое название SC

2
Раз в секунду ! Так для чего все агонизирующие прерывания? Это легко сделать с опросом периодически. В чем проблема тогда?
Олин Латроп

хм ... я думаю, что будет лучше, так как их 8, а также, ответ не может быть предсказан (но это значение можно считать минимальным). Привет! люди могут делать ошибки, верно .. :(
Кодовое название SC

1

Вы можете использовать 8-входной вентиль NAND, как упомянуто @Brian Drummond, для нарастания прерывания через вывод INT, а также для подключения источников прерываний к 8-битному регистру сдвига с параллельным входом / последовательным выходом, таким как «74HC165N», так что тогда вам потребуется просто читать данные из этого регистра сдвига после возникновения прерывания, и это даст вам информацию о вашем фактическом источнике прерывания ... это может быть не самый быстрый способ, но его легко расширить и использовать не более 5 контактов, и если вы добавите систему управления адресами (MUX, LATCH, ...), то вам потребуется только одна шина для уведомления о прерывании, и другие булавки могут быть повторно использованы в разное время для разных ресурсов;)

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.