program Display; (*************************************************************************) (* Pogramm fr einen P80C32SBAA 12MHz *) (* *) (* *) (* *) (*************************************************************************) (*************************************************************************) (*** Definition der verwendeten Pascal-Konstanten ************************) (*************************************************************************) const SDA = $B4; (* I2C - Serielle Datenleitung Port P34 *) SCL = $B5; (* I2C - Serielle Clockleitung Port P35 *) S0BUF = $99; (* Sende- u. Empfangsregister der SS0 *) S0CON = $98; (* Kontrollregister der SS0 *) PCON = $87; (* SFR beinhaltet das SMOD-Bit *) BD = $DF; (* Baudratengenerator-Bit der SS0 *) RCAP2H = $CB; (* SFR Timer 2 Capture High *) RCAP2L = $CA; (* SFR Timer 2 Capture Low *) T2CON = $C8; (* SFR Timer 2 Control *) T2MOD = $C9; (* SFR Timer 2 Mode Control *) TH2 = $CD; (* SFR Timer 2 High *) TL2 = $CC; (* SFR Timer 2 Low *) LCD_B = $8000; (* LCD - Befehlsregister Schreiben *) LCD_D = $8001; (* LCD - Datenregister Schreiben *) LCD_R = $8002; (* LCD - Befehlsregister Lesen *) PortA = $8010; (* Portbaustein - Port A *) PortB = $8011; (* Portbaustein - Port B *) PortC = $8012; (* Portbaustein - Port C *) Port_S = $8013; (* Portbaustein - Steuerregister *) Port1 = $90; (* MCU Port 1 *) I2C_Port_D = $8020; (* I2C - Port Datenregister *) I2C_Port_S = $8021; (* I2C - port Steuerregister *) (*************************************************************************) (*** Definition der verwendeten Pascal-Variablen *************************) (*************************************************************************) type string = array[0..20] of char; (* Stringtype erzeugen *) var Zeichen : char; (* Zeichenveriabel *) Text : string; (* Textveriabel *) a : byte; b : byte; i : byte; wert : array[0..20] of byte; (*************************************************************************) (*** Definition der verwendeten Pascal-Prozeduren ************************) (*************************************************************************) procedure SS0_init; (* SS0 Uminitialisieren *) begin writereg ($FF , RCAP2H); writereg ($D9 , RCAP2L); writereg ($34 , T2CON); writereg ($00 , T2MOD); end; procedure Port_init; (* Portbaustein Initialisieren *) begin; writexby($9B, Port_S); (* Porteinstellung *) writexby($00, PortA); (* Port A auf $00 setzen *) Writexby($00, PortB); (* Port B auf $00 setzen *) writexby($00, PortC); (* Port C auf $00 setzen *) end; (*************************************************************************) (* I2C-Bus Unterprogramme ************************************************) (*************************************************************************) procedure Start; (* I2C-Bus Startbedingung *) begin setbit (SDA); setbit (SCL); Clearbit (SDA); end; procedure Stopp; (* I2C-Bus Stoppbedingung *) begin clearbit (SDA); setbit (SCL); setbit (SDA); end; procedure Senden (Wert : byte); (* I2C-Bus Senden *) var Teiler, a : byte; begin clearbit (SCL); Teiler := 128; for a := 1 to 8 do begin if (wert and Teiler >= 1) then setbit (SDA) else clearbit (SDA); setbit (SCL); clearbit (SCL); Teiler := Teiler div 2; end; clearbit (SDA); setbit (SCL); clearbit (SCL); end; function Empfangen : byte; (* I2C-Bus Empfangen *) var Wert, Multi, a : byte; begin clearbit (SCL); setbit (SDA); Multi := 128; Wert := 0; for a := 1 to 8 do begin setbit (SCL); if bit (SDA) then Wert := Wert + Multi; clearbit (SCL); Multi := Multi div 2; end; Empfangen := Wert; end; procedure ackowledges_Master; (* I2C-Bus ackowledges_Master *) begin clearbit (SDA); setbit (SCL); clearbit (SCL); end; (*************************************************************************) (* I2C-Port Unterprogramme fr Controller ********************************) (*************************************************************************) procedure I2C_init; begin; writexby ($80,I2C_Port_S); writexby ($55,I2C_Port_D); (* I2C Adresse festlegen *) writexby ($A0,I2C_Port_S); writexby ($1F,I2C_Port_D); (* I2C Taktrate festlegen auf 8MHz 11kHz *) writexby ($C1,I2C_Port_S); end; procedure I2C_Senden (Adr, Anzahl : Byte); var Z : byte; ex : boolean; begin; If Anzahl = 0 Then exit; repeat until ((($01) and xby(I2C_Port_S)) = 1); writexby ((Adr and $FE),I2C_Port_D); writexby ($C5,I2C_Port_S); Z := 0; ex := false; repeat repeat until ((($80) and xby(I2C_Port_S)) = 0); If (($08) and xby(I2C_Port_S)) = 1 then ex := true; If Z = Anzahl then ex := true; If not(ex) then writexby (Wert[Z],I2C_Port_D); Z := Z + 1; until (ex); writexby ($C3,I2C_Port_S); end; procedure I2C_Empfangen (Adr, Anzahl : Byte); var Z : byte; ex : boolean; ex2 : boolean; begin; If Anzahl = 0 Then exit; writexby ((Adr or $01),I2C_Port_D); repeat until ((($01) and xby(I2C_Port_S)) = 1); writexby ($C5,I2C_Port_S); Z := 0; ex := false; ex2 := false; repeat repeat until ((($80) and xby(I2C_Port_S)) = 0); If (($08) and xby(I2C_Port_S)) = 1 then begin ex := true; ex2 := true; end; If Z = (Anzahl - 1) then ex := true; If not(ex) then begin wert[Z] := xby (I2C_Port_D); Z := Z + 1; end; until (ex); if not(ex2) then begin writexby ($40,I2C_Port_S); wert[Z] := xby (I2C_Port_D); repeat until ((($80) and xby(I2C_Port_S)) = 0); Z := Z + 1; end; writexby ($C3,I2C_Port_S); wert[Z] := xby (I2C_Port_D); end; (*************************************************************************) (* LCD Unterprogramme ****************************************************) (*************************************************************************) procedure LCD_init; (* LCD Initialisieren *) begin writexby(%00111000,LCD_B); writexby(%00001100,LCD_B); writexby(%00000001,LCD_B); end; procedure LCD_ready; (*LCD bereit? *) begin; (* Warten, bis Busy-Flag=0 ist (D7) *) repeat until ((xby(LCD_R) and %10000000)=0); end; procedure LCD_cls; (* LCD Lschen *) begin writexby(%00000001,LCD_B); end; procedure LCD_print(x:string); (* LCD Text schreiben *) var i, ch :byte; begin i := 0; repeat ch := ord(x[i]); if ch <> 0 then writexby(ch,LCD_D); i := i + 1; until ch = 0; end; procedure LCD_Position(z,s:byte); (* LCD Curser positionieren *) var LCD_pos : byte; begin case z of 0: LCD_pos:=s; (* Zeile 0 *) 1: LCD_pos:=$40+s; (* Zeile 1 *) 2: LCD_pos:=$10+s; (* Zeile 2 *) 3: LCD_pos:=$50+s; (* Zeile 3 *) end; LCD_ready; (* Display bereit ? *) writexby((LCD_pos or $80),LCD_B); end; procedure LCD_shift; (* LCD Text verschieben *) begin writexby($18,LCD_B); wait_25ms(15); end; procedure LCD_zahl(zahl:byte); (* LCD Zahl *) var zw:byte; begin (* Zahl umrechnen *) zw:=zahl div 100; (* Hunderter *) writexby((zw+48),LCD_D); zahl:=zahl-zw*100; (* Zehner *) zw:=zahl div 10; writexby((zw+48),LCD_D); zahl:=zahl-zw*10; (* Einer *) writexby((zahl+48),LCD_D); end; (*************************************************************************) (* RC5 Unterprogramme ****************************************************) (*************************************************************************) function RC5 :Byte; var ra, rb, rc :byte; begin Start; Senden (114); Senden (255); Start; Senden (115); rb := Empfangen and 64; Stopp; rc := 255; repeat Start; Senden (114); Senden (255); Start; Senden (115); ra := Empfangen; Stopp; until ((rb) <> (ra and 64)); rb := ra and 64; case ((255 - ra) and 63)of 0,1,2,3,4,5,6,7,8,9: begin rc := ((255 - ra) and 63) + 48; end; else end; RC5 := rc End; (*************************************************************************) (*** Start des eigendlichen Hauptprogramms *******************************) (*************************************************************************) begin SS0_init; LCD_init; Port_init; I2C_init; LCD_Position (0,0); Text := ('Holger '); LCD_Print (Text); repeat for b := 0 to 5 do begin case b of 0: LCD_Position (1,0); 1: LCD_Position (1,8); 2: LCD_Position (2,0); 3: LCD_Position (2,8); 4: LCD_Position (3,0); 5: LCD_Position (3,8); end; Text := (' '); Start; Senden (160); Senden (b *8); Start; Senden (161); for a := 0 to 6 do begin Text[a] := chr (Empfangen); ackowledges_Master; end; Text[7] := chr (Empfangen); Stopp; LCD_Print (Text); end; until (true); end.