понедельник, 20 ноября 2023 г.

Внешнее прерывание PCINT при программировнии Attiny13 в среде Microchip Studio на языке С

 


        В данной статье рассмотрим использование прерываний в микроконтроллерах 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 погаснет:


Комментариев нет:

Отправить комментарий