Вы находитесь на странице: 1из 3

PINSEL - SELECTING PIN FUNCTIONS

Use PINSEL to choose which 'function' individual pins should perform In order to add more functionality into ever smaller physical package sizes, chip manufacturers have had to resort to 'multiplexing' their chips. All that multiplexing means is that you have more than one 'function' attached to a single 'pin' (in the case of ARM7 chips, there are as many as 4 'functions' per pin). The obvious advantage to this approach is that you can offer more functionality and peripherals, while keeping the package size reasonably small. The disadvantage, of course, is that you can only use one 'function' of a pin at a time, so you need to carefully choose which pins you use in order to avoid losing some required functionality, simply because the particular pin you need is also being used for something else. Looking at the image below, you can see a diagram of all 64 pins available on the LPC2148, along with the various functions that are physically connected to or associated with each pin.

PIN FUNCTION SELECT REGISTERS (PINSEL) To enable you to select which pin functions you would like to use, you need to use one of the three PINSEL registers: PINSEL0, PINSEL1 and PINSEL2. Which register you use depends on which pin you want to modify. While you can find a complete and detailed list of all of the pins and their functions in Chapter 7 of the LPC2148 User's Manual, you can summarize the pin organisation as follows: PINSEL0 contains GPIO pins 0.0 to 0.15

PINSEL1 contains GPIO pins 0.16 to 0.31 PINSEL2 is a special case, and is used to control whether pins 1.16..31 are used as GPIO pins, or as a Debug port in combination with a hardware JTAG debugger. Since we are using a hardware JTAG debugger in all of these tutorials, these pins will not be available to use as GPIO during testing and development (they are used by the JTAG device itself).

Each associated 'pin' in PINSEL0 and PINSEL1 is assigned a 2-bit address. P0.0, for example, uses the first two bits in PINSEL0, P0.1 uses the next two bits, and so on, until you end up with the following layout: PINSEL0 Pin 0.15 0.1 Bits 31..30 3..2 PINSEL1 Pin 0.14 0.13 0.12 0.11 0.10 0.9 0.8 0.7 0.6 0.5 0.4 0.0 29..28 27..26 25..24 23..22 21..20 19..18 17..16 15..14 13..12 11..10 9..8 1..0 0.3 7..6 0.2 5..4

0.31 0.30 0.29 0.28 0.27 0.26 0.25 0.24 0.23 0.22 0.21 0.20 0.19 0.18 0.17 0.16 Bits 31..30 29..28 27..26 25..24 23..22 21..20 19..18 17..16 15..14 13..12 11..10 9..8 7..6 5..4 3..2 1..0 To select a specific function you simply assign one the following 2-bit values to the appropriate location in your PINSEL register: Function Selection Bits Binary Value Selected Function 00 Primary (default) function (always GPIO) 01 First alternate function 10 Second alternate function 11 Third alternate function An Example: Selecting AD0.3 (PINSEL1) Looking at the diagram at the top of the page, we can that pin 15 (P0.30) contains the following 4 functions: P0.30 Pin Functions Function Description P0.30 GPIO 0.30 AD0.3 Analog to Digital Converter 0, Channel 3 EINT3 External Interrupt 3 CAP0.0 Capture 0.0 (Timer 0) Because pin 15 is associated with GPIO 0.30 (it's first or 'default' function), we know that we need to use the PINSEL1 register (which controls pins 0.16..31). We can see from the table above, or from the diagram at the top of the page that the function we want to select (AD0.3) is the first alternate function, meaning we would need to pass 01 to the PINSEL1 register on bits 28 and 29. That could be accomplished with the following code: // Defined in lpc214x.h ... provided for reference sake only #define PCB_PINSEL1_P030_MASK ((unsigned int) 0x30000000) #define PCB_PINSEL1_P030_AD03 ((unsigned int) 0x10000000)

PCB_PINSEL1 &= ~PCB_PINSEL1_P030_MASK; // Clear bits PCB_PINSEL1 |= PCB_PINSEL1_P030_AD03; // Set to AD0.3 (01) Essentially, what this code is doing of taking the current value of PINSEL1 ("PCB_PINSEL1"), setting the two bits associated with pin 0.30 to 0 ("~PCB_PINSEL1_P030_MASK"), and then turning the appropriate bits on to enable AD0.3 ("PCB_PINSEL1_P030_AD03"). (As you can see, this code takes advantage of a number of 'aliases' that are defined in our lpc214x.h header file to help make your code more readable and easier to maintain. You could just as easily provide raw numeric data in hexadecimal form, but it's generally prefferable to keep the code as easy to read and maintain as possible.) Another Example: EINT1 (PINSEL0) To give another example, what if we also wanted to use EINT1 (external interrupt 1) located on pin 0.3 (physical pin 26)? Since this pin is controlled by PINSEL0 (which controls pins 0.0..15), we could simply look up the appropriate aliases in the lpc214x.h file (they all begin with "PCB_" for 'Pin Control Block", and use the following code: PCB_PINSEL0 &= ~PCB_PINSEL0_P03_MASK; // Clear bits PCB_PINSEL0 |= PCB_PINSEL0_P03_EINT1; // Set to EINT1 (11) That's all that's required to change the function a pin is currently performing. Please keep in mind, though, that if you are using a pin for one function, you will probably lose it's other potential functions since you may not be able to 'switch' from one to the other (you may need to connect some sort of external component to that pin such as a resistor or capacitor to make it perform the way you want, and that component would almost certainly interfere with any of the other 'functions' the pin might be able to perform.) Be careful not to pain yourself into a corner by using a pin that has a second functionality you may also need. Most of the peripherals on the LPC2148 have numerous channels, and you can often perform the same functionality on two or more pins.

Вам также может понравиться