AVR開發 Arduino方法(二) 中斷子系統

  在瞭解中斷子系統以前,首先要了解中斷的概念。你正在看書,這時電話響了,你會怎麼作呢?相信大多數人會這樣:先標記看到的位置,接完電話回來後繼續閱讀。這就是一個現實生活中中斷的例子,咱們把電話響了成爲中斷源。Arduino UNO R3的主處理器ATMega328P擁有26箇中斷源,以下表所示:git

向量號編程

程序地址函數

中斷源oop

中判定義ui

中斷服務程序名稱spa

1code

0x0000blog

RESET接口

外部電平復位,上電覆位,掉電檢測復位,看門狗復位事件

 

2

0x0002

INT0

外部中斷請求0

INT0_vect

3

0x0004

INT1

外部中斷請求1

INT1_vect

4

0x0006

PCINT0

引腳電平變化中斷請求0

PCINT0_vect

5

0x0008

PCINT1

引腳電平變化中斷請求1

PCINT1_vect

6

0x000A

PCINT2

引腳電平變化中斷請求2

PCINT2_vect

7

0x000C

WDT

看門狗溢出中斷

WDT_vect

8

0x000E

TIMER2 COMPA

定時/計數器2比較匹配A

TIMER2_COMPA_vect

9

0x0010

TIMER2 COMPB

定時/計數器2比較匹配B

TIMER2_COMPB_vect

10

0x0012

TIMER2 OVF

定時/計數器2溢出

TIMER2_OVF_vect

11

0x0014

TIMER1 CAPT

定時/計數器1事件捕捉

TIMER1_CAPT_vect

12

0x0016

TIMER1 COMPA

定時/計數器1比較匹配A

TIMER1_COMPA_vect

13

0x0018

TIMER1 COMPB

定時/計數器1比較匹配B

TIMER1_COMPB_vect

14

0x001A

TIMER1 OVF

定時/計數器1溢出

TIMER1_OVF_vect

15

0x001C

TIMER0 COMPA

定時/計數器0比較匹配A

TIMER0_COMPA_vect

16

0x001E

TIMER0 COMPB

定時/計數器0比較匹配B

TIMER0_COMPB_vect

17

0x0020

TIMER0 OVF

定時/計數器0溢出

TIMER0_OVF_vect

18

0x0022

SPI STC

SPI串行傳輸結束

SPI_STC_vect

19

0x0024

USART RX

USART接收結束

USART_RX_vect

20

0x0026

USART UDRE

USART數據寄存器空

USART_UDRE_vect

21

0x0028

USART TX

USART,發送結束

USART_TX_vect

22

0x002A

ADC

模數轉換結束

ADC_vect

23

0x002C

EE READY

EEPROM準備好

EE_READY_vect

24

0x002E

ANALOG COMP

模擬比較器

ANALOG_COMP_vect

25

0x0030

TWI

兩線串行接口

TWI_vect

26

0x0032

SPM READY

保存程序存儲器內容就緒

SPM_ready_vect

  這裏之外部中斷0爲例瞭解對中斷子系統的編程,沿用上一章中用於數字輸入示例的電路,這個示例使得按鍵在按下時LED的狀態取反:

 1 // Interrupt.ino
 2 const byte ledPin = 13;
 3 const byte interruptPin = 2;
 4 volatile byte state = LOW;
 5 
 6 void setup() {
 7   pinMode(ledPin, OUTPUT);
 8   pinMode(interruptPin, INPUT_PULLUP);
 9   attachInterrupt(digitalPinToInterrupt(interruptPin), blink, CHANGE);
10 }
11 
12 void loop() {
13   digitalWrite(ledPin, state);
14 }
15 
16 void blink() {
17   state = !state;
18 }

  與外部中斷相關的Arduino庫函數有:

 

  attachInterrupt(digitalPinToInterrupt(pin), ISR, mode):啓用指定引腳的外部中斷並鏈接到指定中斷服務程序

  pin:指定外部中斷的引腳

  ISR:指定中斷服務程序的名稱

  modeLOW(低電平觸發中斷),CHANG(邏輯電平變化觸發中斷),RISING(上升沿觸發中斷)或FALLING(降低沿觸發中斷)

  detachInterrupt(digitalPinToInterrupt(pin)):禁用指定中斷

  pin:指定取消外部中斷的引腳

  interrupts():開啓總中斷

  noInterrupts():禁用總中斷

 

  ATMega328P的外部中斷由2個相關寄存器控制,外部中斷控制寄存器EICRA的結構以下圖所示:

 

 

 

INT1

INT0

 

 

 

ISC11

ISC10

ISC01

ISC00

ISCx[1:0]x = 0, 1位用於設置外部中斷的觸發方式,以下表所示:

ISCx[1:0]

x = 0, 1

外部中斷觸發方式

00

低電平

01

邏輯電平變化

10

降低沿

11

上升沿

  外部中斷屏蔽寄存器EIMSK用於設置是否屏蔽外部中斷,它的結構以下圖所示:

 

 

 

 

 

INT1

INT0

若向其中某位寫入1,則該位控制的外部中斷啓用;寫入0則禁用。

  經過直接訪問寄存器改寫以上程序爲:

 1 // Interrupt_reg.ino
 2 volatile byte state = LOW;
 3 
 4 void setup() {
 5   DDRB |= (1 << PB5);
 6   
 7   DDRD &= ~(1 << PD2);
 8   PORTD |= (1 << PD2);
 9   EICRA &= ~(1 << ISC01) & ~(1 << ISC00);
10   EIMSK |= (1 << INT0);
11   sei(); // 啓用總中斷
12 }
13 
14 void loop() {
15   if (state == HIGH) {
16     PORTB |= (1 << PB5);
17   } else {
18     PORTB &= ~(1 << PB5);
19   }
20 }
21 
22 // 外部中斷0中斷處理函數
23 ISR(INT0_vect) {
24   state = !state;
25 }
相關文章
相關標籤/搜索