'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
'IIIIIIIIIIIIIII      DEMO ZUR C-CONTROL UNIT M 1.1        IIIIIIIIIIII
'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
'(by DIE HARD  10.04)
'
' ANWENDUNG:   IIC-BUS LCD (19 83 30) MIT PCF8574 - ANSTEUERUNG -
'              ADAPTER M 1.X
'-----------------------------------------------------------------------
' Sie sehen hier die Anwendung der C-Control M 1.1 und des Adapter Boards
' ADAPTER M 1.X mit einer PCF8574 PORTerweiterung
' Der PCF8574 befindet sich auf dem IIC-BUS LCD MODUL
' ----------------------------------------------------------------------
' Sie finden bei den Beispielen zur M 1.1 auch andere Beispiele zum IIC-BUS
' Zubehör für die M 1.2 / M 2.0 , jedoch ist die Arbeitsgeschwindigkeit
' bedingt durch die geringe Geschwindigkeit der Unit M 1.1 sehr langsam.
'-----------------------------------------------------------------------
' Der PCF8574 wird über einen IIC-Bus angesteuert
' der hier als BASIC-Treiber ausgeführt ist. Der IIC-Bus benötigt zwei
' Ports, Stellt aber selbst 8 Ports zur Verfügung.
' Die Ports für den IIC-Bus sind hier PORT2=SDA und PORT5=SCL
' Sie können natürlich mehrere PCF5478 an der MICRO betreiben.
' Dazu müssen die Bausteine natürlich unterschiedliche Adressen haben.
'-----------------------------------------------------------------------
' Dieser Treiber beinhaltet eine allgemeine PCF-Anstuerung
'
' WADDRESS=xy:OUTBYTE=z:gosub WRITEBYTE
'
' Sendet den Inhalt von OUTBYTE an einen PCF8574 an Adresse WADDRESS
'
' Ausserdem enthält dieser Treiber die Routinen zum Betrieb eines LCD
' an einem PCF 8574 (hier an Adr:  define LCDADDR  &B01001110)
' Die Adress-Jumper am PCF8574 sind hier alle abgezogen.
' Die Ascii-Codes der Buchstaben sind bereits vordefiniert, sodass der
' Zugriff auf das LCD recht einfach ist:
'
' LCDDATA=D:gosub lcd_writechar         ->Buchstabe D
' LCDDATA=Z8:gosub lcd_writechar        ->Zahl 8
'
'------------------------------------------------------------------------
' Beschreibung
' Das Programm schreibt einen Text auf das LCD und zeigt einen
' laufenden Zähler an.
' Die Variable IICDATA und BUF wird vom Treiber selbst verwaltet.
' Die Variable OUTBYTE ist für Sie als Benutzer die Schnittstelle
' zum Treiber wenn Sie einen Wert an einen PCF 8574 mit WRITEBYTE übergeben wollen.
' Die Variable LCDDATA ist Ihre Schnittstelle zur Übergabe von Buchstaben an das LCD
' Das Unterprogramm SHOWCOUNTER schreibt den Inhalt einer Variablen auf das LCD.
'-----------------------------------------------------------------------
' Sie können SDA und SCL natürlich auch auf andere Digitalports legen,
' wenn Ihre Anwendung das erfordert.
'-----------------------------------------------------------------------
' ACHTUNG:
' Der IICBUS teilt sich mit dem LCD des Application Board Leitungen.
' Für eine korrekte Funktion muss unbedingt das LCD am APPLICATION-BOARD
' initialisiert werden, auch wenn Sie es nicht benötigen.
'------------------------------------------------------------------------ 
'
'Hier sehen Sie, welche PCF 8574 Ports dem LCD zugeordnet sind:
'Port 0  LCD DB4
'Port 1  LCD DB5
'Port 2  LCD DB6
'Port 3  LCD DB7
'Port 4  LCD R/W
'Port 5  LCD RS
'Port 6  LCD EN
'-------------------------------------------------------------------
'--------------------------
'------ I/O PORTS ---------
'--------------------------
'--- IIC INTERFACE  -------
define SDA      port[9]  'Fuer M 2.x Unit und M 1.x Adapter
define SCL      port[10]

'-LCD INTERFACE APP BOARD -
define lcd_port byteport[2]
define lcd_rs port[14]
define lcd_rw port[13]
define lcd_e port[15]
'--------------------------
'------ SYSTEM MEMORY -----
'--------------------------
'--- IIC INTERFACE  -------
define IICDATA      byte[1]
define OUTBYTE      byte[2]
define LCDDATA      byte[3]
define BUF          byte[4]
define WADDRESS     byte[5]
'---- PROGRAMM ------------
define COUNTER      byte[6]
'--- DEZIMAL CONVERTER ----
define value        byte[7]
define hunderter    byte[8]
define zehner       byte[9]
define einer        byte[10]
'- LCD DRIVER APP BOARD ---
define lcd_buf   byte[11]
define lcd_param byte[12]

define LCDADDR  &B01001110



'---- ZEICHENSATZ DEFINITION -------------
define Z0 &H30:define Z1 &H31:define Z2 &H32:define Z3 &H33
define Z4 &H34:define Z5 &H35:define Z6 &H36:define Z7 &H37
define Z8 &H38:define Z9 &H39
define A  &H41:define B  &H42:define C  &H43:define D  &H44
define E  &H45:define F  &H46:define G  &H47:define H  &H48
define I  &H49:define J  &H4A:define K  &H4B:define L  &H4C
define M  &H4D:define N  &H4E:define O  &H4F:define P  &H50
define Q  &H51:define R  &H52:define S  &H53:define T  &H54
define U  &H55:define V  &H56:define W  &H57:define X  &H58
define Y  &H59:define Z  &H5A:define BLK &H20

'---------- LCD APP BOARD INIT ----------------
gosub LCDINIT
'---------- IICBUS INIT -----------------------
SDA=on:SCL=on

'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
'II   PCF 8574 PORTERWEITERUNG FÜR LCD        II
'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
pause 20
'---- PCF8574 DEVICE WRITE ADDRESS -------
gosub lcd_init

'----- WRITE CHARACTERS LINE 1 ---------------
LCDDATA=4:gosub L1_GOTOPOS    'LINE 1 POS 4
LCDDATA=D:gosub lcd_writechar
LCDDATA=E:gosub lcd_writechar
LCDDATA=M:gosub lcd_writechar
LCDDATA=O:gosub lcd_writechar
LCDDATA=BLK:gosub lcd_writechar
LCDDATA=M:gosub lcd_writechar
LCDDATA=BLK:gosub lcd_writechar
LCDDATA=Z1:gosub lcd_writechar
LCDDATA=&H2E:gosub lcd_writechar
LCDDATA=Z1:gosub lcd_writechar
'----- RUNNING COUNTER LCD LINE 2 ------------
#LOOP
for COUNTER=0 to 255
LCDDATA=3:gosub L2_GOTOPOS    'LINE 2 POS 3
VALUE=COUNTER:gosub SHOWCOUNTER
LCDDATA=BLK:gosub lcd_writechar
LCDDATA=BLK:gosub lcd_writechar
next
goto LOOP


'IIIIIIIIIIIII UNTERPROGRAMME IIIIIIIIIIIIIIIIIIIIIII
#SHOWCOUNTER
hunderter=value/100
LCDDATA=hunderter+&H30:gosub LCD_WRITECHAR
zehner=(value-(hunderter*100))/10:LCDDATA=zehner+&H30:gosub LCD_WRITECHAR
einer=value-(hunderter*100)-(zehner*10):LCDDATA=einer+&H30:gosub LCD_WRITECHAR
return
'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII




'HHHHHHHHHHH IIC-BUS LCD TREIBER HHHHHHHHHHH
'-------------------------------------------
'-- WRITE BYTE IN OUTBYTE TO PCF8574  ------
'-------------------------------------------
#WRITEBYTE
gosub IICSTART:IICDATA=WADDRESS:gosub IICSEND
IICDATA=OUTBYTE:gosub IICSEND:gosub IICSTOP:return
'-------------------------------------------
#IICSTART
SDA=off:SCL=off:return
#IICSTOP
SDA=off:SCL=on:SDA=on:return
#IICSEND
SDA=(IICDATA and &H80)shr 7:SCL=on:SCL=off
SDA=(IICDATA and &H40)shr 6:SCL=on:SCL=off
SDA=(IICDATA and &H20)shr 5:SCL=on:SCL=off
SDA=(IICDATA and &H10)shr 4:SCL=on:SCL=off
SDA=(IICDATA and &H08)shr 3:SCL=on:SCL=off
SDA=(IICDATA and &H04)shr 2:SCL=on:SCL=off
SDA=(IICDATA and &H02)shr 1:SCL=on:SCL=off
SDA=(IICDATA and &H01):SCL=on:SCL=off
'---- 9th CLOCK FOR ACKNOWLEDGE ----------
deact SDA:SCL=on:SCL=off:SDA=off:return

'---------------------------------------
'------------- LCD ROUTINES -------------
'----------------------------------------
#LCD_INIT
WADDRESS=LCDADDR
OUTBYTE=0:gosub WRITEBYTE
LCDDATA=&H38:gosub LCD_WRITECMD
OUTBYTE= &B00000010:gosub WRITEBYTE '$02 to LCD
OUTBYTE= &B01000010:gosub WRITEBYTE '$02 with CLOCK
OUTBYTE= &B00000010:gosub WRITEBYTE
LCDDATA=&H28:gosub LCD_WRITECMD
LCDDATA=&H0C:gosub LCD_WRITECMD
#LCD_CLR
LCDDATA=&H02:gosub LCD_WRITECMD
LCDDATA=&H01:gosub LCD_WRITECMD
return
#L1_GOTOPOS
LCDDATA=LCDDATA +&H7F:goto LCD_WRITECMD
#L2_GOTOPOS
LCDDATA=LCDDATA +&HBF:goto LCD_WRITECMD
#LCD_WRITECMD
BUF = off:goto LCD_WRITE
#LCD_WRITECHAR
BUF = &B00100000
#LCD_WRITE
WADDRESS=LCDADDR
'--------- WRITE HI NIBBLE -------------
OUTBYTE=BUF or (LCDDATA shr 4):gosub WRITEBYTE      'DATA TO PORT
OUTBYTE=OUTBYTE or &B01000000:gosub WRITEBYTE           'STROBE HI
OUTBYTE=OUTBYTE and &B10111111:gosub WRITEBYTE          'STROBE LO
'--------- WRITE LO NIBBLE -------------
OUTBYTE=BUF or (LCDDATA and &H0F):gosub WRITEBYTE'DATA TO PORT
OUTBYTE=OUTBYTE or &B01000000:gosub WRITEBYTE           'STROBE HI
OUTBYTE=OUTBYTE and &B10111111:gosub WRITEBYTE          'STROBE LO
return

'---------------------------------------
'--     APP_BOARD LCD ROUTINES        --
'---------------------------------------
#LCDINIT
  lcd_port = OFF
  lcd_param=&H38 : gosub LCDWRITECMD
  lcd_port=&B00000010
  tog lcd_e
  tog lcd_e
  lcd_param = &H28 : gosub LCDWRITECMD
  lcd_param = &H0C : gosub LCDWRITECMD
#LCDCLS
  lcd_param = &H02 : gosub LCDWRITECMD
  lcd_param = &H01 : gosub LCDWRITECMD
   return
#LCDGOTOLINE
  if lcd_param = 1 then lcd_param = &H80
  if lcd_param = 2 then lcd_param = &HC0
  goto LCDWRITECMD
#LCDWRITECMD
  lcd_buf = OFF
  goto LCDWRITE
#LCDWRITECHAR
  lcd_buf = &B00100000

' Kommando oder Zeichen an Display senden
#LCDWRITE
  lcd_port = lcd_buf or (lcd_param shr 4) ' Hi-Nibble
  tog lcd_e
  tog lcd_e
  lcd_port = lcd_buf or (lcd_param and &H0F)  ' Lo-Nibble
  tog lcd_e
  tog lcd_e
return