В данной
статье рассмотрим использование прерываний в микроконтроллерах AVR на
примере микроконтроллера attiny13. В этот раз это будет внешнее прерывание
PCINT:
В отличие
от прерывания INTx, которое может работать только на определенном порту (для
Attiny13 это порт PB1), прерывание PCINTx работает на любом из портов (В
PCINTx – x указывает на порт):
Для работы с прерыванием PCINTx необходимо:
1) Подключить стандартную
библиотеку для работы с прерываниями:
#include <avr/interrupt.h>
2) Разрешаем прерывания в программе
sei()
3) В регистре –
General Interrupt Mask Register (GIMSK) записью логической «1» в бит
в 5й бит разрешаем использование в программе прерывания PCIE
(PCINT0)
GIMSK|= (1<<PCIE)
4) В регистре
Pin Change Mask Register (PCMSK) задаются номера выводов, по которым
будет срабатывать прерывание PCINTx.
PCMSK |= (1<<PCINT1) | (1<<PCINT2); //Разрешаем прерывания на 1м и 2м порту
5) Добавляем обработчик
прерываний с подпрограммой, которая должна быть выполнена при наступлении
события, указанном в прерывании в формате:
ISR(«имя прерывания»_vect) {выполняемая подпрограмма}. В нашем случае
это:
ISR(PCINT0_vect) { // Код подпрораммы выполняемый при наступлении события, // указанного в прерывании }
На этом с
теорией все. Далее изменим программу мигания светодиодом из предыдущей
статьи, добавив в схему две кнопки, подключенные к портам PB1 и PB2 и
светодиод, который будем управлять на PB4. При нажатии на любую из кнопок
будет срабатывать прерывание, которое в зависимости от того, какая кнопка
нажата будет включать и выключать светодиод на PB4.
/* * Interrupt PCINT.c * Мигание светодиодом и 2 кнопки через прерывание * Created: 06.11.2023 12:57:42 * ============================================ * H A R D W A R E I N F O R M A T I O N S * ============================================ * Attiny13a ___________ * 1 /____ |8 * o--|RESET Vcc|--o +5V * ADC o--|PB3/ADC3 PB2|--o Key2 * Led2 o--|PB4/ADC2 PB1|--o Key1 * GND o--|GND PB0|--o Led1 ----LED--->+5V * |_____________| * * Author : Vyacheslav */ #define F_CPU 1000000L // Частота для delay.h #include <avr/io.h> // Порты ввода-вывода для AVR #include <util/delay.h> // Задержка в ms #include <avr/interrupt.h> #define ZADERZHKA 1000 // Задержка в ms для _delay_ms (1 сет) ISR(PCINT0_vect) { if (!(PINB&(1<<PB1))) PORTB&=~(1 << PB4); //Запись 0 в BP4 если PB1 нажата if (!(PINB&(1<<PB2))) PORTB|=(1 << PB4); //Запись 1 в BP4 если PB2 нажата } int main(void) { DDRB = (1 << PB0) | (1 << PB4); // Устанавливаем порт PB0 и PB4 на выход, остальные на вход sei(); PCMSK |= (1<<PCINT1) | (1<<PCINT2); // Прерывание будет по любому изменению сигнала для портов 1 и 2 GIMSK |= (1<<PCIE); PORTB |= (1 << PB1) | (1 << PB2); // Включаем подтяжку к 5В на кнопку while (1) // Повторяем все что ниже { _delay_ms(ZADERZHKA); // Ждем 1с PORTB |= (1 << PB0); // Выключаем PB0 светодиод _delay_ms(ZADERZHKA); // Ждем 1с PORTB &= ~ (1 << PB0); // Включаем PB0 светодиод } }
Визуально работа программы выглядит следующим образом: все время мигает светодиод на порту PB0. Если нажать кнопку, подключенную к PB1 загорится светодиод, подключенный к порту PB4. При нажатии на кнопку PB2 – светодиод на PB4 погаснет:
Комментариев нет:
Отправить комментарий