ARM : GPIO ( General Purpose Input Output Register )


What are GPIOs??

ARM is 32-bit architecture. And that provides 32 bit GPIO ports.  In this tutorial, we are going to cover about GPIO pins, how to use them, GPIO registers and an example how microcontroller can interact with outside world with GPIO pins? For this tutorial I am just taking LPC2129 as reference and with the use of CMSIS library and explaining a few lines of code in this tutorial (want to know about CMSIS ??)

So, what is GPIO?

GPIO_LPC2129

LPC2129 PORT PIN description

Whether the peripherals are internal or external that doesn’t matter, the core should interact with pins which we call them GPIO pins. Here GPIO pins means, General Purpose Input Output pins. Every peripheral must interact with outside world through these GPIO pins.

With the help of GPIO we can easily get connected to basic peripherals like buttons, LEDs, switches and other components. Complex peripherals like GLCDs, TFTs, GPS, different sensors etc.

In order to get started with GPIO ports, we need to look into the four ‘registers’ that controls pins PORTs it: IODIRIOSETIOCLR and IOPIN.  Each of these registers is explained in detail below with some basic examples of how they work.

 

IODIR

  • It’s 32-bit GPIO.
  • It is used to set the direction of pin.
  • By using this register, we can set a particular pin as input/output.

For example, if we want to use our GPIO pin to send signals ‘out’ from the microcontroller to some external device, we need to set a pin to ‘Output’ (1).

Consider the below example to understand more about this register. Suppose we need to set 0th port 26th pin as output,  the code will be as follows.

IODIR0 |= (1 << 26);

IODIR0 is #defined macro in controller’s header file.For example, if you set that 0th port 26th pin then that become output pin. That means we can take the signal from microcontroller through this output pin to the outside world.

Note: To set any pin we will use | operation.

If we wanted to use our GPIO pin to receive information from the outside world (reading it inside the microcontroller), we would need to set GPIO 0.10 to ‘Input’ (0).  That could be accomplished the following code:

IODIR0&= ~(1 << 10);

Note: to set the pin as input pin, you need to use & operation.

Sometimes we may want more than one pin as output pins. So, in that case we can accomplish this by setting ‘1’ in those pins as below mentioned line.

 

// Set GPIO 1.14, 1.17, and 1.19 to output

IODIR1 |= (1 << 14) | (1 << 17) | (1 << 19);

Like in the same way we can set more than one pin at a time as input pins.

IOSET:

  • It’s 32-bit GPIO.
  • It is used to set the direction of pin.
  • By using this register, we can set a particular pin as input/output.

If your GPIO pin is set as Output (using the IODIR register mentioned above), you can use IOSET to set your GPIO pin to ‘high’ (providing a small 3.3V electrical current) or IOCLR to set it to ‘low’ (providing a connection to GND).

Actually, wedon’t need tothink about high being ‘on’ and low being ‘off’, though, since … as we’ll see in the example below … you can often turn a device ‘on’ by setting it low and ‘off’ by setting it ‘high’, depending on how the components are connected.

IOPIN:

Regardless of whether your GPIO pin’s direction is set to Input or Output, you can use the IOPIN register to read the current ‘state’ of every GPIO pin in the pin block.

If the value when you read by using IOPIN register is 1 then that pin is currently ‘high’, and a 0 value means the pin is currently ‘low’.

Note: Since IOPIN returns the current state of ALL 32 pins in the pin block, you have to do a little bit of extra work to determine the value of one specific pin. That we can know by using this line of code.

 Pin_state = (IOPIN0)&(1<<pin_num)?1:0;

Note: Here IOPIN0 is for 0th port, if you want you can take IOPIN1,IOPIN2 like that

LPC_2129 GPIO

We can take one example on these registers

1  	include "lpc21xx.h"
2  	
3  	#define BUT1PIN         15
4  	#define BUT2PIN         9
5  	#define LED1PIN         8
6  	#define LED2PIN         10
7  	
8  	static void delay(void )
9  	{
10  	   volatile inti,j;
11  	   for (i=0;i<100;i++)
12  	      for (j=0;j<1001;j++);
13  	}
14  	
15  	int main(void)
16  	{
17  	inti;
18  	
19  	   IODIR0 |= (1<<LED1PIN)|(1<<LED2PIN); // define LED-Pins as outputs
20  	   IOSET0 = (1<<LED1PIN)|(1<<LED2PIN); // set Bits = LEDs off (active low)
21  	   IODIR0 &= ~((1<<BUT1PIN)|(1<<BUT2PIN));// define Button-Pins as inputs
22  	i=0;
23  	  while (i<5){
24  	   IOCLR0 = (1<<LED1PIN);
25  	   IOSET0 = (1<<LED2PIN);
26  	   delay();
27  	   IOSET0 = (1<<LED1PIN);
28  	   IOCLR0 = (1<<LED2PIN);
29  	   delay();
30  	i++;
31  	}
32  	   while (1)
33  	   {
34  	      if (IOPIN0 & (1<<BUT1PIN))     // true if button released (active low)
35  	      IOCLR0 = (1<<LED1PIN);            // clear I/O bit -> LED on (active low)
36  	      else 
37  	IOSET0 = (1<<LED1PIN);            // set I/O bit -> LED off (active low)
38  	
39  	if (IOPIN0 & (1<<BUT2PIN))    // true if button released (active low)
40  	         IOCLR0 = (1<<LED2PIN);            // clear I/O bit -> LED on (active low)
41  	else 
42  	   IOSET0 = (1<<LED2PIN);            // set I/O bit -> LED off (active low)
43  	   }
44  	   return 0; // never reached45  	}

Explanation:

Assume that we are taking Active Low pins

  • In line 1, we added a header file which includes all registers related macros we used in program. So it must be there.
  • 3,4,5,6 lines define the button pins and led pin numbers.
  • In 8th line the delay function starts. In this function we are generating manually a few seconds delay by taking two for loops.
  • Coming to main function, in 19th line we are making LED pin as output pin.
  • And then, in 20th line: by making the LED pins values High, our LEDs will be in OFF state.
  • In 21st line we are making the Button pins as input pins by making zeroes in those pin bits with use of IODIR register.
  • Now, from 23rd line the first line will start. Here, I am taking a condition to repeat this loop for 5 times. And inside the loop, clearing the first LED pin and setting the second LED pin. And then calling the delay function to see the effect of our LEDs glow. After this, I am doing the reverse to those LED pins. Again the same delay function to see the same LEDs effect.
  • From 32nd line the second while loop will start. This second line is infinite one. In this while loop, the first if condition checks the first button pin value is high or not. If the value is high the button is released, so we need to switch off the LED. That we are doing by clearing the first LED pin with use of IOCLR register. In else condition we came to know that the button is still pressed, so we need to switch ON the LED. That we did by setting the LED pin with use of IOSET register.
  • In the second if and else conditions we are doing the same thing for second LED.

One sincere request to all the readers, please comment down and correct us, this site is trying to help people to understand embedded technology, this is only possible with your comments and corrections. Please subscribe to the newsletter to get latest project/article updates right in your email inbox. Take few moments and like zembedded facebook page, follow on tweeter, thanks!

Related posts:

About author

This article was written by admin

Admin has over twenty years experience in the electronics industry, largely dedicated to embedded software. A frequent presenter at conferences and seminars and author of numerous technical articles. Working presently as Development Manager in India. A firm Believer in Knowledge grows when it shared.

Comments

Comments (5)
  1. tarik from algeria says - Posted: March 8, 2013

    hello,
    1-does it mean that LED1PIN and LED2PIN are in High (3.3 V) because IOSET0 mean high:
    IOSET0 = (1<<LED1PIN)|(1<<LED2PIN); // set Bits = LEDs off (active low)

    2-
    if (IOPIN0 & (1<<BUT1PIN)) // true if button released (active low)—where is the condition please
    IOCLR0 = (1< LED on (active low)— why LED on but we know that IOCLR0 means LOW (grd)
    else
    IOSET0 = (1< LED off (active low)

    thank you very much

  2. Pardhu says - Posted: March 10, 2013

    Hi Tarik,
    1. if you set the pins HIGH, it’s not mean that LEDs should turn on. It depend up on how you connected your LEDs with controller.
    see this link, you may get idea on this.
    http://itis4all.blogspot.in/2013/03/led-pin-connections.html

    2. To under stand this you just need basic knowledge about if statement.
    if(1) – The condition is satisfied to get execute the if block.
    if(0) – The condition fails so, it goes to else block or next statement.

    • tarik from algeria says - Posted: March 12, 2013

      thank you very much friends

  3. Kribe says - Posted: April 25, 2015

    Note: Don’t try to execute the code direct under Linux application, because the applications use virtual memory, not physical memory.

  4. chari says - Posted: November 10, 2015

    thank you very much…..can u post the adc coding..with detailed explanation…..

Leave your comment

Your email address will not be published. Required fields are marked *