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


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

向量號

程序地址

中斷源

中斷定義

中斷服務程序名稱

1

0x0000

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 }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM