Главная » Статьи » Proton PICBasic

Прерывание по любому порту МК

Метод заключается в том, чтобы порт, который нужно задействовать для прерываний, подключить через диод к имеющемуся порту 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


Файлы проекта здесь

Обсудить на форуме

Похожие материалы: Подключение семи кнопок на три вывода порта МК, Подключение трех кнопок на один вывод порта МКУправление несколькими портами по времени (видео)




Категория: Proton PICBasic | Добавил: ADMIN (13.12.2010)
Просмотров: 9107 | Комментарии: 5 | Теги: INT, Программа, пример, прерывание, статья, порт | Рейтинг: 5.0/6
Всего комментариев: 5
1 retas   (02.03.2011 20:28)
Да, вариант интересный, но, пожалуй, подходит только для регистрации медленных событий (как здесь, для кнопок), но если предусмотреть что кнопка должна хоть чуток при нажатии удерживаться, то её можно засечь без прерываний и обойтись меньшим количеством деталей.

2 ADMIN   (06.03.2011 10:26)
Здесь выигрыш именно в том, что этот метод позволяет поймать нажатие любой кнопки, или прихода импульса в любом случае и на любом порту, причем количество этих портов практически неограничено. А далее все зависит от фантазии.

3 amid-   (05.03.2012 15:01)
Спас очень помогло

4 Light   (11.12.2012 22:38)
Здравствуйте!
Возник вопрос по одной строке:
OPTION_REG = %10000000 ' Фронт прерывания - передний, отключим PULLUP

Написано, что фронт прерывания передний, но 6-ой бит у вас указан = 0. По даташиту это задний фронт.
Это очепятка или я туплю где-то? Просто я новичок в этом деле и пытаюсь осознать эту беду wacko

0
5 ADMIN   (24.10.2014 05:19)
Да, это опечатка. Это задний фронт.

Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]