Definition and management of PORT connections

published: 4 June 2020 / updated 4 June 2020

Lire cette page en français

 


Definition of ARDUINO ports

During the development in FORTH language for ARDUINO, it appeared necessary to have unique words to manage the ports of the different ARDUINO cards.

Here are these words, which we will find throughout the articles and whose definition does will be repeated more in these articles:

Definition of an input or output (pin)

\ Use: 
\ PORTD %10000000 defPIN: PD7  ( define portD pin #7) 
: defPIN: ( PORTx mask ---  |  --- mask port) 
    create 
        c, c,           \ compile PORT and min mask 
    does> 
        dup c@          \ push pin mask 
        swap 1+ c@      \ push PORT 
  ; 

The word defPIN: creates a type of constant that aggregates into two bytes the binary mask of a pin and the address of the corresponding port.

Before using defPIN:, you must declare the address of the ports used as constants (see example).

When you have a specific program, name the pin by its function rather than by its pin number. Example:

PORTD %00000001 defPIN: LED.red     ( pin PD0)
PORTD %00000010 defPIN: LED.yellow  ( pin PD1)
PORTD %00000100 defPIN: LED.green   ( pin PD2)

In programs in PHP language, constants are declared in uppercase characters.

In FORTH, any data whose content never changes is a constant or assimilated. We will therefore take the habit of defining them in capital letters, here PORTB PORTD LED, etc ...

Action on ports

\ Turn a port pin on, dont change the others. 
: high ( pinmask portadr -- ) 
    mset 
  ; 
\ Turn a port pin off, dont change the others. 
: low ( pinmask portadr -- ) 
    mclr 
  ; 

The words high and low allow:

Action on DDR registers

DDR registers control the direction of data processing. Initially, data ports cannot be used for output.

\ Only for PORTx bits,  
\ because address of DDRx is one less than address of PORTx. 
 
\ Set DDRx so its corresponding pin is output. 
: output ( pinmask portadr -- ) 
    1- high 
  ; 
\ Set DDRx so its corresponding pin is input. 
: input  ( pinmask portadr -- )    
    1- low 
  ; 
 

The words output and input allow: /p>

Pin state recovery

\ read the pins masked as input 
: pin@  ( pinmask portaddr -- fl ) 
    2- mtst \ select PINx register as input 
    if      true 
    else    false   then 
  ; 

The word pin@ retrieves the state of a bit in a data read register PINx. Stacks -1 (true) if this bit is non-zero, stacks 0 if this bit is zero.

Example

-testLED 
marker -testLED 
 
\ tests 
\ PORTB 
37 constant PORTB	\ Port B Data Register 
PORTB %10000000 defPIN: LED 
: init.ports ( ---) 
    LED output 
  ; 
 
init.ports 
LED high 
500 ms 
LED low