reading status inport
reading status inport
Hi,
does anyone can explain me how can i read the status of an input port.
I have several micro switches attached to my LPC2138 AE edu board and I would like to use them.
Is there a status register wich can be read?
Greets,
F.P.
does anyone can explain me how can i read the status of an input port.
I have several micro switches attached to my LPC2138 AE edu board and I would like to use them.
Is there a status register wich can be read?
Greets,
F.P.
-
- Site Admin
- Posts: 545
- Joined: Fri Dec 31, 2010 12:30 pm
- Contact:
Re: reading status inport
The five pushbuttons on the EA LPC2138 board are connected to pins P0.14 and P1.16-19.
You can access these via the GPIO registers which are defined as IOPIN0 (for pins P0.*) and IOPIN1 (for pins P1.*) in the Astrobe LPC2138 module.
The status of each bit in the register corresponds to the status of one of 32 pins. e.g. the code to check if P1.17 is pressed would look something like this:
Refer to Chapter 8 GPIO in the NXP LPC2138 User Manual (UM10120) for more details. If you haven't already got a copy download it from the NXP support site:
http://ics.nxp.com/support/documents/?search=UM10120
You can access these via the GPIO registers which are defined as IOPIN0 (for pins P0.*) and IOPIN1 (for pins P1.*) in the Astrobe LPC2138 module.
The status of each bit in the register corresponds to the status of one of 32 pins. e.g. the code to check if P1.17 is pressed would look something like this:
Code: Select all
IMPORT LPC := LPC2138, SYSTEM, Main;
...
IF SYSTEM.BIT(LPC.IOPIN1, 17) THEN ...
http://ics.nxp.com/support/documents/?search=UM10120
Re: reading status inport
Now I now where I can use the SYSTEM.BIT procedure for.
I was trying out SET operations on the status register but maybe this is easier and clearer.
The tutorial of Embedded artists is using a shift register and I would like to explore its functionality by manipulating its control lines myself.
Polling vs interrupt driven programming is another topic that i would like to investigated with buttons.
Thanks for the answer.. I will try it out.
Greets,
F.P.
I was trying out SET operations on the status register but maybe this is easier and clearer.
The tutorial of Embedded artists is using a shift register and I would like to explore its functionality by manipulating its control lines myself.
Polling vs interrupt driven programming is another topic that i would like to investigated with buttons.
Thanks for the answer.. I will try it out.
Greets,
F.P.
Re: reading status inport
I am intrigued by the article "SET: A neglected data type, and its compilation for the ARM" (Wirth 2008) https://www.astrobe.com/wirth/SETs.pdf and try to apply set types to io registers.
I found this example code in the specification of the SYSTEM.mod of the Oberon System.
http://www-old.oberon.ethz.ch/SYSTEM.html
However, I'm wondering if a procedure, something like Ports.In(port: PORT, VAR status: Status), could be useful.
As a beginner I want to check or set the status of an Port by using the Ports name, eg P101,as a value parameter.
Also the precondition that the port to be read is set as an In port should be met. Maybe with an global variable: Ports.Done a successful read action can be verified.
What would you think is the wisest approach to reading ports: the SYSTEM.BIT, the SYSTEM.GET(SYSTEM.ADR(value), SYSTEM.VAL(SET, scr2)) or the Ports.In(p101, status) way?
I found this example code in the specification of the SYSTEM.mod of the Oberon System.
http://www-old.oberon.ethz.ch/SYSTEM.html
Code: Select all
PROCEDURE Testbit*; (* Test the presence of a specific bit in scr *)
BEGIN
IF SYSTEM.BIT(SYSTEM.ADR(scr), 6) THEN END; (* first approach *)
IF 6 IN SYSTEM.VAL(SET, scr) THEN END; (* better approach *)
(* or even better, declare scr2 as a SET to starts with *)
SYSTEM.GET(SYSTEM.ADR(value), SYSTEM.VAL(SET, scr2)); (* from memory *)
IF 6 IN scr2 THEN END;
END Testbit;
As a beginner I want to check or set the status of an Port by using the Ports name, eg P101,as a value parameter.
Also the precondition that the port to be read is set as an In port should be met. Maybe with an global variable: Ports.Done a successful read action can be verified.
What would you think is the wisest approach to reading ports: the SYSTEM.BIT, the SYSTEM.GET(SYSTEM.ADR(value), SYSTEM.VAL(SET, scr2)) or the Ports.In(p101, status) way?
-
- Site Admin
- Posts: 545
- Joined: Fri Dec 31, 2010 12:30 pm
- Contact:
Re: reading status inport
Some points to be considered before implementing such a module:
Given all of the above one possible approach is:
If you had a board with pushbuttons connected to pins 0.15 to 0.18 and you wanted them to control leds on pins 1.17 to 1.20 respectively you could write something like:
Without a GPIO module I would write it like this:
If realtime performance was a critical issue the latter solution would be preferable. Otherwise the choice would depend on the preferences of the individual programmer.
- The number of ports that are available depends on the LPC2xxx device being targeted. A general solution would need to support from 1 to 4 ports.
- 4 ports with 32 pins each gives 128 possible values. A system of names P000 to P331 would be unwieldy. I would suggest two parameters: port number and pin number. Port number could be named constants if preferred e.g.
However, I see little value in identifying a pin by anything else but its number 0..31.
Code: Select all
CONST Port0* = 0; Port1* = 1; Port2* = 2; Port3* = 3;
- User-defined types in Oberon-07 are restricted to pointers, arrays and records. Type aliases (e.g. the proposed types Port and Status) are not supported.
- Some MCUs have fast IO port access (FIO) as well as the legacy (GPIO) system.
- Are the Port number and pin number in range?
- Does the port exist on the current target?
- Is the pin available for use as a GPIO pin on the current target? Too complex a check to be worth doing?
Given all of the above one possible approach is:
Code: Select all
GPIO.In(CONST portNo, pinNo: INTEGER; VAR value: BOOLEAN);
GPIO.Out(CONST portNo, pinNo: INTEGER; CONST value: BOOLEAN);
Code: Select all
(* Untested! *)
FOR pin := 15 TO 18 DO
led := pin + 2;
GPIO.In(port0, pin, state);
GPIO.Out(port1, led, state)
END;
Code: Select all
(* Untested! *)
SYSTEM.GET(LPC.IOPIN0, port0);
FOR pin := 15 TO 18 DO
led := pin + 2;
IF pin IN port0 THEN
SYSTEM.PUT(LPC.IOCLR1, {led})
ELSE
SYSTEM.PUT(LPC.IOSET1, {led})
END
END
-
- Site Admin
- Posts: 545
- Joined: Fri Dec 31, 2010 12:30 pm
- Contact:
Re: reading status inport
By definition SYSTEM features are highly platform/implementation-dependent. To avoid confusion you should always refer to the implementation-specific documentation of the Oberon system that you are curently targeting for information on how to use the SYSTEM features. In Astrobe v3.2 refer to Section 7.23 SYSTEM of the document "Oberon for LPC2000 Microcontrollers".Oberoid wrote:I found this example code in the specification of the SYSTEM.mod of the Oberon System.Code: Select all
(* or even better, declare scr2 as a SET to starts with *) SYSTEM.GET(SYSTEM.ADR(value), SYSTEM.VAL(SET, scr2)); (* from memory *)
There you will see that the second parameter of SYSTEM.GET is of type <any basic type>. Hence the SYSTEM.VAL typecast is unnecessary. Typically in Astrobe, the first parameter to SYSTEM.GET is already an address e.g. one of the register address constants defined in the module LPC.mod. Hence the SYSTEM.ADR is not required either. Consequently in Astrobe code, typical examples of the use of SYSTEM.GET are:
Using INTEGER variables:
Code: Select all
(* Real Time Clock *)
VAR
hours, minutes, seconds: INTEGER;
...
...
SYSTEM.GET(LPC.HOUR, hours);
SYSTEM.GET(LPC.MIN, minutes);
SYSTEM.GET(LPC.SEC, seconds);
Code: Select all
(* GPIO pin configuration *)
VAR
selection, direction: SET;
...
...
(* Pins P0.16..P0.18, P0.26..P0.29 are configured for GPIO usage by clearing the relevant bits *)
SYSTEM.GET(LPC.PINSEL1, selection);
SYSTEM.PUT(LPC.PINSEL1, selection - {0..5, 20..27});
(* Pins P0.16..P0.18, P0.26..P0.29 are configured as outputs by setting the relevant bits*)
SYSTEM.GET(LPC.IODIR, direction);
SYSTEM.PUT(LPC.IODIR, direction + {16..18, 26..29});