\ Named Bits \ V 1.1 20.05.2007 \ Code: Matthias Trute \ Text: M.Kalus \ A named bit puts a bitmask on stack, so we can operate on the bit that is set. \ And it puts the address of its register on stack, too. \ So we can use this method on data registers for port pins, data \ direction registers for ports and also on other registers. \ Example: \ PD 7 portpin: PD7 ( define portD pin #7) \ PD7 is_output ( set DDRD so that portD pin #7 is output) \ PD7 on ( turn portD pin #7 on, i.e. set it high-level) \ PD7 off ( turn portD pin #7 off, i.e. set it low-level) hex \ for example: 2B constant PD \ Port D in ATmega169 2A constant DDRD \ Data direction register of Port D \ At compiletime: \ Store combination of data register address for a port \ and bit number in one cell and give it a name. \ At runtime: \ Get bitmask and register address on stack. \ Now use it for ports: : portpin: create ( C: "ccc" portadr n -- ) ( R: -- pinmask portadr ) 1 swap lshift 8 lshift or , \ packed value does> i@ \ get packed value dup 8 rshift swap ff and \ ; \ Turn a port pin on, dont change the others. : on ( pinmask portadr -- ) dup ( -- pinmask portadr portadr ) c@ ( -- pinmask portadr value ) rot ( -- portadr value pinmask ) or ( -- portadr new-value) swap ( -- new-value portadr) c! ; \ Turn a port pin off, dont change the others. : off ( pinmask portadr -- ) dup ( -- pinmask portadr portadr ) c@ ( -- pinmask portadr value ) rot ( -- portadr value pinmask ) invert and ( -- portadr new-value) swap ( -- new-value port) c! ; \ Only for PORTx bits, \ because address of DDRx is one less than address of PORTx. (ATmega169) \ Set DDRx so its corresponding pin is output. : is_output ( pinmask portadr -- ) 1- on ; \ Set DDRx so its corresponding pin is input. : is_input ( pinmask portadr -- ) 1- off ; \ finis