⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wheeler.4th

📁 Embedded magazine soure code for the year 1991
💻 4TH
字号:
<<< START OF CODE EXAMPLE >>>

\ I2C Demo Code by Steven R. Wheeler
\ Rationale of code:

\ We will use the 8255 on the Tiny as an interface to the I2C bus.
\ The I/O will be as follows:

\ The 8255 will be configured in Mode 0 with
\       Port A as an output port (but is unused),
\       Port B as an output port (SDA for writes), or
\       Port B as an input port  (SDA for reads and INT), and
\       Port C as an output port (SCL for reads and writes)

\ SCL (serial clock) will be on the low bit of Port C, because this
\ is  convenient. SDA (serial data) will be on the highest-but-one bit
\ of  Port B, so that it won't be too hard to write code routines which
\ efficiently move  single bits between AH and AL when sending or    
\ receiving data.  INT  will be one bit lower than SDA on Port B.  The 
\ positions of SDA and  INT are constrained because we will be using 
\ the keypad connector on  the Tiny188 as our connection to the 80196
\ keypad/lcd/tone board, so we want the inputs to have pull-up
\ resistors.

\ We will be talking to two PCF8574 chips on the keypad/lcd/tone board. 
\ Each chip is addressed separately, one at address 20h, the other at
\ address 21h. Since the addresses are only 7 bits, and the low order
\ bit indicates read or write, we will actually be sending 40h or 42h
\ to write, and 41h or 43h to read.

\ The PCF8574 at address 20h has the control signals for the LCDs and
\ the tone generator, as well as the key/nokey indication.  The PCF8574
\ at address 21h is written with data for the LCD, and provides the    
\ keypad data.

\ The control signals are sent in the following bit order:
\
\       +---+---+---+---+---+---+---+---+
\       | + | + | + | + | + | + | + | + |
\       +-|-+-|-+-|-+-|-+-|-+-|-+-|-+-|-+
\         |   |   |   |   |   |   |   +---- R/W* for LCD
\         |   |   |   |   |   |   +-------- LCD 0 enable
\         |   |   |   |   |   +------------ LCD 1 enable
\         |   |   |   |   +---------------- Keypad latch
\         |   |   |   +-------------------- Beep enable (0=on,1=off)
\         |   |   +------------------------ A0
\         |   +---------------------------- A1
\         +-------------------------------- Key available indication

\ A0 serves a dual purpose: it is the command/data register select for
\ the LCDs, and with A1, it selects the frequency of the tone          
\ generator.

\ The key available indication is an input.  As I read the             
\ documentation of the PCF8574, this means that it should always be   
\ written with a 1.


HEX
01 CONSTANT R/W*                        \ 0 = write LCD; 1 = read LCD
02 CONSTANT LCD0                        \ 1 = enable LCD0
04 CONSTANT LCD1                        \ 1 = enable LCD1
08 CONSTANT KPLATCH*                    \ 0 = latch keypad
10 CONSTANT BEEP*                       \ 0 = enable beep
20 CONSTANT RS                          \ 0 = LCD command; 1 = LCD data
20 CONSTANT A0                          \ Same as RS, but also beep freq control
40 CONSTANT A1                          \ Beep freq control
80 CONSTANT KeyMask                     \ Read ... 0 = key available

\ Composite constants for controlling the board

KeyMask A1 OR A0 OR RS OR BEEP* OR R/W* OR CONSTANT Latch-Key
\ LCDx and KPLATCH* low
Latch-Key KPLATCH* OR   CONSTANT UnLatch-Key
\ LCDx low

UnLatch-Key
BEEP*    NOT AND        CONSTANT BEEP3          \ A1,A0 = 11
BEEP3 A0 NOT AND        CONSTANT BEEP2          \ A1,A0 = 10
BEEP3 A1 NOT AND        CONSTANT BEEP1          \ A1,A0 = 01
BEEP1 A0 NOT AND        CONSTANT BEEP0          \ A1,A0 = 00

UnLatch-Key LCD0 OR
        R/W* NOT AND    CONSTANT LCD0-Data-Out
LCD0-Data-Out
        RS   NOT AND    CONSTANT LCD0-Cmd-Out

UnLatch-Key LCD1 OR
        R/W* NOT AND    CONSTANT LCD1-Data-Out
LCD1-Data-Out
        RS   NOT AND    Constant LCD1-Cmd-Out


\ 8255 configuration

80 CONSTANT B=Output                    \ A = out; B = out; C = out
82 CONSTANT B=Input                     \ A = out; B = in;  C = out


\ 8255 port bitmasks for data

40 CONSTANT DataMask                    \ Bitmask for Data to/from port B
20 CONSTANT IntMask                     \ INT signal from PCF8574 @ 20h
01 CONSTANT ClockMask           \ Clock bit to PCF5874's

01 CONSTANT Read                        \ OR in to address to read
00 CONSTANT Write                       \ OR in to address to read

\ I2C "addresses" used on the board

40 CONSTANT Control                     \ Address of control PCF8574
42 CONSTANT Data                        \ Address of data PCF8574


\ I/O address of the 8255

E080 CONSTANT CS8255                    \ Base address of 8255
DECIMAL

: Set-B-Input ( --)                     \ This is our normal state of affairs
        B=Input CS8255 3 + PC! ;

: Set-B-Output ( --)                    \ Only when sending
        B=Output CS8255 3 + PC! ;

: Clock-High ( --)                      \ Set the SCL line high
        ClockMask CS8255 2+ PC! ;

: Clock-Low ( --)                       \ Set the SCL line low
        00 CS8255 2+ PC! ;

: Toggle-Clock ( --)                    \ Set SCL high, then low
        Clock-High                      \ First we set it high
        Clock-Low ;                     \ Then we set it low

: Send-Start ( --)                      \ Send a START condition
        00 CS8255 1+ PC! ;              \ High-low data transition = START

: Send-Stop ( --)                       \ Send a STOP condition
        DataMask CS8255 1+ PC! ;        \ Low-high data transition = STOP

: Send-Next-Bit ( 8b1 -- 8b2)   \ Send highest bit of 8b1
        DUP 2/ DataMask AND             \ Isolate the bit we want
        CS8255 1+ PC!                   \ Place on the data port
        Toggle-Clock                    \ Send the bit
        2* ;                            \ Shift the next bit into position

: Read-Input ( -- 8b1)          \ Read the port B input
        CS8255 1+ PC@ ;

: Read-Bit ( -- n)                      \ Returns 0 or 1
        Clock-High                      \ Set the clock bit high
        Read-Input                      \ Read the data (bit 7)
        Clock-Low                       \ Set the clock low again
        2* 2* FLIP 1 AND ;              \ Move the data to bit 0

: Send-Byte ( 8b1 -- flag)      \ Send a byte to the I2C bus
        Set-B-Output                    \ Configure for sending data
        8 0 DO Send-Next-Bit            \ Send each bit
        LOOP DROP                       \ Remove byte when sent
        Read-Bit ;

: Key-Int? ( -- flag)           \ TRUE if key status changed
        Set-B-Input
        CS8255 1+ PC@
        IntMask AND 0<>
        Set-B-Output ;

: Read-Byte ( -- 8b1)
        Set-B-Input
        0
        8 0 DO 2* Read-Bit OR
        LOOP
        Set-B-Output Clock-High ;

: Write0 ( byte --)
        Control Write OR Send-Start Send-Byte DROP
        Send-Byte DROP Clock-High Send-Stop ;

: Write1 ( byte --)
        Data Write OR Send-Start Send-Byte DROP
        Send-Byte DROP Clock-High Send-Stop ;

: Read0 ( -- byte)
        Control Read OR Send-Start Send-Byte DROP Read-Byte Send-Stop ;

: Read1 ( -- byte)
        Data Read OR Send-Start Send-Byte DROP Read-Byte Send-Stop ;

: PKey? ( -- flag)
        Read0 KeyMask AND 0= ;

: @PKey ( -- n)
        -1 Write1                       \ Make certain they're inputs
        Latch-Key Write0                \ Latch the keypad value
        Read1 255 XOR                   \ Read the keypad value
        UnLatch-Key Write0 ;    \ Release the keypad latch

: PKey ( -- n)
        BEGIN   PAUSE PKey?     UNTIL
        @PKey ;

: Loud ( beepval --)
        WRITE0 ;

: Quiet ( --)
        UnLatch-Key Write0 ;


: LCD-Write ( byte reg --)
        SWAP Write1
        DUP Write0
        [ LCD0 LCD1 OR NOT ] LITERAL 
        AND Write0 ;

: LCD0-Command ( byte --)
        LCD0-Cmd-Out LCD-Write ;

: LCD0-Data ( byte --)
        LCD1-Cmd-Out LCD-Write ;

: LCD1-Command ( byte --)
        LCD1-Cmd-Out LCD-Write ;

: LCD1-Data ( byte --)
        LCD1-Data-Out LCD-Write ;


: Setup ( --)
        Set-B-Output
        Clock-High
        Send-Stop ;

<<< END OF CODE EXAMPLE >>>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -