Метод заключается в том, чтобы порт, который нужно задействовать для прерываний, подключить через диод к имеющемуся порту INT. Вы можете подключить через диод любой имеющийся в наличии порт, способный работать на ввод информации. При изменении его уровня с единицы на ноль, этот ноль через диод поступает еще и на вход INT микроконтроллера, который и реагирует на этот перепад. В подпрограмме обработки прерывания мы опрашиваем известные нам подключенные порты и делаем выводы. Чтобы процессор реагировал на перепад не с 1 в 0, а наоборот, нужно настроить прерывание по спаду в регистре OPTION_REG(читай даташит), подтянуть порты не к плюсу, а к минусу и инвертировать диоды.
Покажу на примере:
Схема проста. Она отображает движущийся текст на дисплее в цикле. При нажатии на любую из кнопок, происходит переход в ПП обработки прерывания и загорается либо гаснет соответствующий светодиод.
Код:
'-------------------------- Описание проекта ---------------------------------
'Проект : Interrupt_On_Any_Pin
'Автор : ADMIN
'
'Версия : 1.0.0 от 13.12.2010
'
'-------------------------- Опции компилятора --------------------------------
Declare SHOW_SYSTEM_VARIABLES = OFF ' При симуляции в Proteus не показывать внутренние переменные
Declare FSR_CONTEXT_SAVE = On ' Не заботиться о сохранении содержимого регистра FSR
Declare Reminders = OFF ' Выключить напоминания компилятора
Declare Warnings = OFF ' Выключить предупреждения компилятора
Declare Optimiser_Level 0 ' Выключить оптимизацию программы
;-------------------------- Общие настройки------------------------------------
Device = 16F628A' Используемый микроконтроллер
Xtal = 4 ' Частота осциллятора 4 МГц
'-------------------------- Конфигурация программирования --------------------
Config BODEN_OFF, BOREN_OFF, CP_OFF, PWRTE_ON, WDT_OFF, LVP_OFF, MCLRE_ON, INTRC_OSC_NOCLKOUT
'-------------------------- Настройки портов ---------------------------------
PortB_Pullups = OFF ' Выключить подтягивающие резисторы на PORTB
Declare All_Digital = On ' Установить все порты цифровыми входами/выходами
'-------------------------- Настройки подключения ЖКИ ------------------------
Declare LCD_Type ALPHA ' Тип ЖКИ - буквенно -цифровой
Declare LCD_DTPin PORTB.4 ' Порт данных ЖКИ
Declare LCD_ENPin PORTB.2 ' Управление линией E
Declare LCD_RSPin PORTB.3 ' Управление линией RS
Declare LCD_Interface 4 ' Разрядность шины данных
Declare LCD_CommandUs 2000 ' Задержка перед посылкой команды
Declare LCD_DataUs 50 ' Задержка перед посылкой данных
Declare LCD_Lines 2 ' Количество строк ЖКИ
'-------------------------- Регистры специального назначения-------------------
'-------------------------- INTCON --------------------------------------------
Symbol RBIF = INTCON.0 ' Флаг внешнего прерывания по PORTB.4-PORTB.7
Symbol INTF = INTCON.1 ' Флаг внешнего прерывания по PORTB.0(INT)
Symbol T0IF = INTCON.2 ' Флаг переполнения TMR0
Symbol RBIE = INTCON.3 ' Бит разрешения прерывания по PORTB.4-PORTB.7
Symbol INTE = INTCON.4 ' Бит разрешения прерывания по PORTB.0(INT)
Symbol T0IE = INTCON.5 ' Бит разрешения прерывания по переполнению TMR0
Symbol PEIE = INTCON.6 ' Бит разрешения прерывания от периферийных устройств
Symbol GIE = INTCON.7 ' Бит глобального разрешения прерываний
'-------------------------- Начало -------------------------------------------
Dim i As Byte ' Для цикла
Symbol LED1 = PORTA.2 ' Светодиоды
Symbol LED2 = PORTA.3 '
Symbol KEY1 = PORTA.0 ' и кнопки
Symbol KEY2 = PORTA.1 '
'-----------------------------------------------------------------------------
TRISA = %00000011 ' Для кнопок порты на ввод, остальные на вывод
TRISB = %00000001 ' Для входа INT порт на ввод
OPTION_REG = %10000000 ' Фронт прерывания - передний, отключим PULLUP
INTE = 1
GIE = 1 ' Разрешение глобального прерывания
LED1 = 0 ' Выключим светодиоды
LED2 = 0
On_Interrupt GoTo Int_Label ' При прерывании INT переход на Int_Label
GoTo MainProgram
'-------------------------- Прерывания--------------------------
Int_Label:
Context Save '
If INTF = 1 Then 'Если было прерывание по INT
If KEY1 = 0 Then 'то если нажата кнопка 1
LED1 = ~LED1 'изменим состояние светодиода 1
EndIf
If KEY2 = 0 Then 'то если нажата кнопка 2
LED2 = ~LED2 'изменим состояние светодиода 2
EndIf
INTF = 0 'сбросим флаг прерывания от INT
EndIf
Context Restore ' Возврат из обработчика прерывания
'-------------------------- Главная программа ------------------------
MainProgram: 'Составим программу, любую, для примера
For i = 16 To 1 Step -1 ' Зададим цикл движения строк справа налево
Gosub PrintString
Next
DelayMS 1000
For i = 1 To 16 ' Зададим цикл движения строк слева направо
Gosub PrintString
Next
GoTo MainProgram ' Возврат на начало основной программы
PrintString:
Cls
Print At 1,i, "Int. on any pin"
Print At 2,i, "demonstration"
DelayMS 250
Return
|
Файлы проекта здесь
Обсудить на форуме
Похожие материалы: Подключение семи кнопок на три вывода порта МК, Подключение трех кнопок на один вывод порта МК, Управление несколькими портами по времени (видео)
|