Sign in Join
Wiki copytemporary

AVR Embedded Tutorial - GPIO-Interrupt: what changed

Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.

Title: AVR Embedded Tutorial - GPIO-Interrupt

OldNewLine
1+# GPIO interrupt
2+
3+## Introduction
4+
5+How to control the GPIO and UART can be found here:
6+
7+- [[AVR Embedded Tutorial - Simple GPIO on and off output/de|GPIO]]
8+- [[AVR Embedded Tutorial - UART/de|UART]] *UARTInit* and *UARTSendString(...*
9+
10+## External interrupt
11+
12+Interrupt pin assignment for the ATmega328:
13+
14+- INT0: PD2
15+- INT1: PD3
16+
17+### Interrupt routine
18+
19+This example shows how this works with INT0. You use **EICRA** to specify which interrupt is triggered. See table below. You can also activate INT0 and INT1 at the same time.
20+
21+``` pascal
22+procedure Int0_Interrupt; public name 'INT0_ISR'; interrupt;
23+begin
24+ UARTSendString('INT0'); // Identify interrupt
25+end;
26+```
27+
28+### Activate interrupt
29+
30+The parameters are described in the table below.
31+
32+``` pascal
33+begin
34+ PORTD := %00001100; // PullUp Pin 2 + 3
35+
36+ // Initialize UART
37+ UARTInit ;
38+
39+ // Activate INT0
40+ EICRA := %11; // INT0 is triggered when the pin goes HIGH.
41+ EIMSK := %01; // activate INT0.
42+
43+ // Activate interrupt
44+ asm
45+ Sei
46+ end;
47+
48+ // Main loop
49+ repeat
50+ until 1 = 2;
51+end.
52+```
53+
54+### Register for the Atmega328p
55+
56+The following registers are responsible for the activation of the ports/pins:
57+
58+- **EICRA** Function of the interrupt.
59+- **EIMSK** Activate INT0 and/or INT1.
60+
61+Table for **EICRA** which shows what kind of action on the pin triggers an interrupt.
62+
63+<table>
64+<thead>
65+<tr>
66+<th></th>
67+<th colspan="2">INT1</th>
68+<th></th>
69+<th colspan="2">INT0</th>
70+<th></th>
71+</tr>
72+</thead>
73+<tbody>
74+<tr>
75+<td>Bit</td>
76+<td>3</td>
77+<td>2</td>
78+<td></td>
79+<td>1</td>
80+<td>0</td>
81+<td></td>
82+</tr>
83+<tr>
84+<td></td>
85+<td>0</td>
86+<td>0</td>
87+<td></td>
88+<td>0</td>
89+<td>0</td>
90+<td>Low Level on the pin</td>
91+</tr>
92+<tr>
93+<td></td>
94+<td>0</td>
95+<td>1</td>
96+<td></td>
97+<td>0</td>
98+<td>1</td>
99+<td>Every change</td>
100+</tr>
101+<tr>
102+<td></td>
103+<td>1</td>
104+<td>0</td>
105+<td></td>
106+<td>1</td>
107+<td>0</td>
108+<td>Pin goes LOW</td>
109+</tr>
110+<tr>
111+<td></td>
112+<td>1</td>
113+<td>1</td>
114+<td></td>
115+<td>1</td>
116+<td>1</td>
117+<td>Pin goes HIGH</td>
118+</tr>
119+</tbody>
120+</table>
121+
122+### INT1 interrupt
123+
124+The INT1 interrupt must be set as follows:
125+
126+``` pascal
127+ EICRA := %1100; // INT1 is triggered when the pin goes HIGH.
128+ EIMSK := %10; // activate INT1.
129+```
130+
131+For the INT1 interrupt you have to use the ISR procedure for the INT1 (**INT1_ISR**).
132+
133+``` pascal
134+procedure Int1_Interrupt; public name 'INT1_ISR'; interrupt;
135+begin
136+ // do something
137+end;
138+```
139+
140+## Pin change interrupt
141+
142+This example is for an Arduino Nano (Atmega328p).
143+
144+### Terminal issue
145+
146+Output the pin status on a terminal.
147+
148+``` pascal
149+procedure WritePort(p : byte);
150+begin
151+ UARTSendString ('PB' + char(p + 48) + ':');
152+
153+ if PinB and (1 shl p) = (1 shl p) then
154+ begin
155+ UARTSendString('HIGH');
156+ end
157+ else
158+ begin
159+ UARTSendString('LOW');
160+ end;
161+end;
162+```
163+
164+### Interrupt routine
165+
166+The interrupt fires when a pin changes.
167+
168+``` pascal
169+procedure PC_Int0_Interrupt; public name 'PCINT0_ISR'; interrupt;
170+var
171+ i : byte;
172+begin
173+ UARTSendString(#27 '[0; 0H'); // Home the cursor
174+
175+ for i := 0 to 3 do
176+ begin
177+ WritePort(i);
178+ end;
179+end;
180+```
181+
182+### Declare pin change GPIO
183+
184+Activate pins PB0, PB1, PB2 and BP3 for interrupts.
185+
186+``` pascal
187+const
188+ inPortsB = %00001111; // PCINT0 + PCINT1 + PCINT2 + PCINT3
189+```
190+
191+### Activate pin change interrupt
192+
193+The parameters are described in the table below.
194+
195+``` pascal
196+procedure PC_Int0_Interrupt; public name 'PCINT0_ISR'; interrupt;
197+begin
198+ DDRB := 0;
199+ PORTB := inPortsB; // PullUp
200+
201+ // Initialize UART
202+ UARTInit;
203+
204+ // Activate PCINT0_ISR
205+ PCICR := %001; // Only on PORTB
206+ PCMSK0 := inPortsB;
207+
208+ // Activate interrupt
209+ asm
210+ Sei
211+ end;
212+
213+ // Main loop
214+ repeat
215+ // do something
216+ until 1 = 2;
217+end.
218+```
219+
220+### Registers for the Atmega328p
221+
222+The following registers are responsible for the activation of the ports/pins:
223+
224+- **PCICR** Ports that trigger an interrupt.
225+- **PCMSKx** The individual pins.
226+
227+Table for PCICR:
228+
229+| Bit | 2 | 1 | 0 |
230+|-------|-------|-------|-------|
231+| PCICR | PORTD | PORTC | PORTB |
232+
233+Table for the pins of PCMSKx :
234+
235+| Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
236+|--------|---------|---------|---------|---------|---------|---------|---------|--------|
237+| PCMSK0 | PCINT7 | PCINT6 | PCINT5 | PCINT4 | PCINT3 | PCINT2 | PCINT1 | PCINT0 |
238+| PCMSK1 | | PCINT14 | PCINT13 | PCINT12 | PCINT11 | PCINT10 | PCINT9 | PCINT8 |
239+| PCMSK2 | PCINT23 | PCINT22 | PCINT21 | PCINT20 | PCINT19 | PCINT18 | PCINT17 | PCINT6 |
240+
241+### Example for PORT B and PORT C
242+
243+``` pascal
244+// Activate PCINT0_ISR and PCINT1_ISR
245+PCICR := %011; // PORT B and PORT C
246+PCMSK0 := %11000000; // Pin 6 + 7 of PORT B
247+PCMSK1 := %00000011; // Pin 0 + 1 of PORT C
248+```
249+
250+A second ISR procedure is added for the PCINT1_ISR. If you would like to use PORT D, then a procedure for the PCINT2_ISR would need to be added.
251+
252+``` pascal
253+procedure PC_Int1_Interrupt; public name 'PCINT1_ISR'; interrupt;
254+begin
255+ // do something
256+end;
257+```
258+
259+# See also
260+
261+- [[AVR Embedded Tutorial|AVR Embedded Tutorials]] - Overview
262+
263+---
264+*From the Free Pascal wiki, page "AVR Embedded Tutorial - GPIO-Interrupt", as it stood on 2020-01-24 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*
265+Category: AVR
266+Category: Arduino
267+Category: Embedded
268+Category: Tutorials

Back to history