The LPC1768 GPIO Tutorial will be first important tutorial which explains a major peripheral of the ARM Cortex-M3 MCU. IMPORTANT NOTE: I have mentioned this already in the previous tutorials but I will repeat it in every LPC1768 Tutorial. Download both the Datasheet and User Manual for LPC1768 MCU from the official NXP website. I cannot explain / discuss each and every topic in detail. You have to look up for the topic of discussion in those documents and gather additional information.
Introduction
GPIO, which is short for General Purpose Input Output, is one of the basic and simplest peripherals in Arm Cortex-M3 LPC1768. As the name suggests, the purpose of a GPIO Peripheral is to act as either an Input or an Output, with respect to the processor so that the MCU can interact with external World. (Here, the term external means external to the MCU i.e. other than its internal peripherals). Except Power related, Clock related and a few other debug pins, almost all pins of LPC1768 can be configured as a GPIO Pin. Additionally, each GPIO Pin can be further set as either an Input pin or as an Output Pin. When a GPIO Pin is set as Input, the MCU can read the data from external component in terms of voltage. Similarly, when a GPIO Pin is set as Output, the MCU will control the voltage on the pin and thus the external component. Before understanding more about GPIO in LPC1768 and its registers, there are a few other basics you need to understand like Pin Multiplexing, Pin Control Block and the register associated with it.
Pin Connect Block of LPC1768
The most common IC Packaging for LPC1768 is LQFP100 i.e. there are 100 Pins in the package. Out of these 100 pins, 30 pins are used for Main Power Supply (VDD and VSS), Oscillator for Processor and RTC (XTAL1, XTAL2, RTCX1 and RTCX2), few reference voltage pins and pins for Debug Interface (JTAG / SWD). Coming to the remaining 70 Pins, they all can be used as GPIO Pins. But what if we want to output a PWM through one of the pins or use it for UART communication. Since these 70 pins are only way for the MCU to communicate with the external world (either through GPIO or any other peripheral), there should be a mechanism to decide which pin acts a GPIO pin and which pin acts as PWM Output Pin (as an example). This is where the Pin Connect Block of LPC1768 comes into picture. Since pins are physically a limited resource, all of these 70 pins have more than one functionality. Internally, this is implemented using a Multiplexer, where a pin can be configured to have one of many possible functions. For example, if you refer to the Pin Configuration Section in the datasheet of LPC1768, pin number 37 on the IC, which is named P0.0 can have any of the following functions:
GPIO – General Purpose Digital Input / Output Pin RD1 – CAN1 Receiver Input Pin TXD3 – UART3 Transmitter Output Pin SDA1 – I2C1 Data Pin (non-I2C Compliant)
Similarly, all the other pins have corresponding multiple functions to be selected from. Pin Connect Block is responsible for configuring the internal Multiplexers to connect the Pin and the on-chip peripheral (including GPIO). Before activating a peripheral, it must be connected to appropriate pins. When a pin is assigned to a particular function, all the other peripheral functions are excluded on the pin.
Pin Description of LPC1768
Before taking a look at the registers of Pin Control Module, let us take a brief look at the PORTS in LPC1768. All the 70 Pins of LPC1768 i.e. pins other than the power, oscillator and debug pins (i.e. pins which can be configured as GPIO Pins) are grouped into Ports. LPC1768 MCU has 5 such Ports called Port 0 (P0), Port 1 (P1), Port 2 (P2), Port 3 (P3) and Port 4 (P4). Each Port can be 32-bit wide i.e. each port can have a maximum of 32-pins. So, pins in a Port are named as follows: Px.y ––––– where x is the Port (0 – 4) and y is the pin (0 – 31). But all the ports in LPC1768 may not have 32 pins and they unavailable pins are usually marked as “Reserved”. This following is the list of all the available pins in each of the five Ports of LPC1768.
Port 0 – P0[30:0] – Pins 12, 13, 14 and 31 in Port 0 are not available. Port 1 – P1[31:0] – Pins 2, 3, 5, 6, 7, 11, 12 and 13 in Port 1 are not available. Port 2 – P2[13:0] – Pins 14 to 31 in Port 2 are not available. Port 3 – P3[26:25] – Only Pins 25 and 26 in Port 3 are available. Rest are not available. Port 4 – P4[29:28] – Only Pins 28 and 29 in Port 4 are available. Rest are not available.
If you count all the available pins, you will get the result as 70.
Registers of Pin Control Module
There are three sets of registers associated with the Pin Connect Block. They are:
PINSEL ––––– Pin Function Select Registers PINMODE ––––– Input Mode Control Registers PINMODE_OD ––––– Open Drain Mode Control Registers
Of these three sets of registers, we are interested in PINSEL Registers. There are 8 PINSEL Registers. The following table shows the list of PINSEL Registers and the Pins they control.
Register Control PINSEL0 P0[15:0] PINSEL1 P0[31:16] PINSEL2 P1[15:0] – Ethernet PINSEL3 P1[31:16] PINSEL4 P2[15:0] PINSEL7 P3[31:16] PINSEL9 P4[31:16] PINSEL10 Trace Port Enable
Two bits in each PINSEL register are used to control a single pin. For example, Bits 0 and 1 in PINSEL0 are used to configure the functionality of P0.0 pin. The following table shows the values of Bits of PINSEL Registers and corresponding Functions they assign to a particular Pin.
PINSEL0 – PINSEL9 Values Function 00 Primary (Default) Function (Usually, GPIO) 01 First alternate function 10 Second alternate function 11 Third alternate function
The following table shows different values of PINSEL0 Register, Bits 0 and 1 i.e. Possible Functions of P0.0 Pin.
PINSEL0[1:0] Function on P0.0 00 GPIO Port 0.0 01 RD1 10 TXD3 11 SDA1
Similarly, you can refer to the Pin Connect Block Chapter in the Reference Manual of LPC1768 and understand different PINSEL Register Values and corresponding Functions.
Accessing PINSEL Registers in Programming
All the registers and their corresponding locations in the memory map of LPC1768 are already defined in the lpc17xx.h header file. Depending on functionality, registers of LPC1768 are grouped into several C Structures. For example, all the registers associated with the Pin Connect Block are grouped in to a structure called LPC_PINCON. The elements of this structure can be accessed using standard C Structure accessing techniques. For example, if you want to set P0.2 as GPIO, then you have to make the bits 5 and 4 of PINSEL0 as 00. For this you can use the following statement. LPC_PINCON->PINSEL0 &= ~ ((1«5) | (1«4)); Similarly, if you take a look at the other possible functions of P0.2, then it is possible to configure it as TXD0 or AD0.7. So, if you want to set P0.2 Pin as ADC Input AD0.7, then you have to make bits 5 and 4 of PINSEL0 as 10 for which you can use the following statement. LPC_PINCON->PINSEL0 |= (1«5);
GPIO in LPC1768
If you recall the Block Diagram of LPC1768 mentioned in the Getting Started with LPC1768 Tutorial, the GPIO Peripheral is directly connected to the AHB Bus (AMBA High-performance Bus) for fast I/O Operations. If you worked with ARM7 MCUs, then you might remember that there are two sets of GPIO Peripherals in those MCUs called GPIO and Fast GPIO. In LPC1768, all the GPIO Ports are Fast GPIO Ports. In order to differentiate normal GPIO with Fast GPIO, the registers associated with Fast GPIO Ports are usually prefixed with FIO. As mentioned previously, if we want to use a Pin as a GPIO Pin then we have to configure the PINSEL registers to make a Pin as a GPIO Pin and then use the registers of GPIO Peripheral to make the pin as either Input or Output and also read or write to the Pins (depending how it is configured). By default, all the 70 pins are configured as GPIO Input Pins on reset.
GPIO Registers in LPC1768
There are five registers associated with the GPIO Peripheral of LPC1768 MCU. Their names and description are mentioned in the following table. Name of GPIO Register Description Function FIODIR Fast GPIO Port Direction Control register Used to control the direction (Input or Output) of individual Port Pin. When 0, pin is Input. When 1, pin is Output. FIOMASK Fast Mask Register for Port. Used to mask a Pin from Read and Write operations. When a bit is 0, Read/Write tasks by other four registers are reflected on the Pin. When 1, Pin isn’t affected by other registers. FIOPIN Fast Port Pin Value Register. Used to Read or Write directly to Port Pins. Pin status can be read irrespective of the direction. FIOSET Fast Port Output Set Register. Used to control HIGH state of output Pins. When 1, output pin produces HIGH. 0 has no effect. FIOCLR Fast Port Output Clear Register. Used to control LOW state of output Pins. When 1, output pin produces LOW. 0 has no effect.
Accessing GPIO Registers in Programming
Similar to Pin Control Block Registers, the GPIO Registers are also grouped into structures, one for each GPIO Port. The structures are:
LPC_GPIO0 LPC_GPIO1 LPC_GPIO2 LPC_GPIO3 LPC_GPIO4
If you want to modify the FIODIR Register of a particular Port, then simple access the member of the structure as follows: LPC_GPIOn->FIODIR Here, n can be any number between 0 and 4, based on the selected Port. Now, let us see few programming statements for making P0.2 Pin as Output and make the output value HIGH and LOW. First, the P0.2 pin must be configured as GPIO Pin using PINSEL Registers (which we already did in the previous step). LPC_PINCON->PINSEL0 &= ~ ((1«5) | (1«4)); Now, to make the pin as output, use the FIODIR Register of GPIO0. LPC_GPIO0->FIODIR |= (1«2); To make the pin as HIGH, use the FIOSET Register. LPC_GPIO0->FIOSET |= (1«2); To make the pin as LOW, use the FIOCLR Register. LPC_GPIO0->FIOCLR |= (1«2);
Example: Blink an LED
Let us now see how to Blink an LED connected to P1.14 Pin of LPC1768 MCU. #include <lpc17xx.h> void delay(void); int main(void) { LPC_GPIO1->FIODIR |= (1«14); // Configure P1.14 as Output while (1) { LPC_GPIO0->FIOSET |= (1«14); // Output HIGH delay (); LPC_GPIO0->FIOCLR |= (1«14); // Output LOW delay (); } return 0; } void delay(void) { int count, i=0; for (count=0; count < 6000000; count++) { i++; } }
Conclusion
In this tutorial, I have explained some basic information about GPIO in LPC1768 MCU. This includes configuring a Pin as GPIO, how to make it as Input or Output, when set as Output, how to make the Pin HIGH or LOW. I suggest you to explore the Pin Control Block and GPIO Blocks in Reference manual and read about additional registers. Lets consider a simple 32 bit register (b[31]…b[0]) named R0 with the content 0x0F0F (0000 1111 0000 1111). We have too a mask M used for the bits b[5] and b[2], in another words, have the value 0x24 (..10 0100). If we make the operation: R0 &= ~M Our R0 will be modifyed to: 0x000B (0000 0000 0000 1011) But, in the other case, with the same variables but OR operation (in the case of your question, not negated): R0 |= 0x24 Our R0 will be modifyed to: 0x0F2F (0000 1111 0010 1111) So, you use the &=~ when you want to “clean” only de Mask bits from a register, and the |= when you want to apply change the whole register with your M. Note that sometimes you don’t want to set another bits else than your mask in the |= operation, so is well used a mask M&(Value to Put) in the register. Like this you are assure that you didn’t change other bits that the mask bits. I hope that it helps you! Comment * Name * Email * Website
Δ