
|
INFO - FAQ - CC2-Forum - CCPro-Forum |
|
||
|
Hallo Mitstreiter, habe das Problem das ein Assemblerprogramm (LCD über PCF /Helbig / Program halb geklaut) an der alten M-Unit definitiv geht, an der alten ersten C-Station nicht! Timingproplem? Muss ich Busy des LCD's testen? Haben Unit und Station versch. Taktfrequenzen? Grüße, Willi aus Oelde ******************************************************* * I/O-Funktionen für den I2C-Bus * W.Haf 2.08.2010 * * Der I2C-Bus wird über zwei Pins des Port B emuliert * (Pin 1 = SDA / Pin 2 = SCL) ******************************************************* bport equ $01 ; Datenport B bpdir equ $05 ; Richtung Datenport B daten equ 1 ; Datenport (Pin 2) clock equ 0 ; Clockport (Pin 1) basic_io equ $A1 ; Basic Useradresse modus_io equ $A2 ; Command / Daten Bit adresse equ $A3 ; Adresse für DS 1621 Temp1 equ $A4 ; Temperatur Ganzzahl Temp2 equ $A5 ; Temperatur 0.5°C ******************************************************* org $101 ; Startadresse jmp LCD_Befehl jmp LCD_Daten jmp DS_Read ; jmp I2C_START ; jmp I2C_STOP ; jmp I2C_WRITE ; jmp I2C_READ ; jmp pulse ; jmp I2C_GETACK ; jmp I2C_SENDACK ; jmp I2C_SENDNACK ; jmp DS_Init ; jmp REP_StART ;***************************************************** ; DS 1621_Init ;***************************************************** DS_Init jsr I2C_START lda adresse ;Adresse DS1621 lesen jsr I2C_putbyte lda #$AC ;Kommando "AC" schicken jsr I2C_putbyte lda #$00 ;Kommando "00" schicken jsr I2C_putbyte ;Dauerwandlung jsr I2C_STOP ;********** Conversion Starten mit "EE" ************** jsr I2C_START lda adresse ;Adresse DS1621 jsr I2C_putbyte lda #$EE ;Conversion starten jsr I2C_putbyte jmp I2C_STOP ;***************************************************** ; DS 1621_Read ;***************************************************** DS_Read jsr I2C_START lda adresse ;Adresse DS1621 ansprechen jsr I2C_putbyte lda #$AA ;Kommando "AA" schicken jsr I2C_putbyte jsr I2C_STOP ; ########### neues stop ? ; das wars...... jsr I2C_REP_START; Weiter lesen lda adresse ;Adresse DS1621 LESEN inca ;also Adresse + 1 jsr I2C_putbyte jsr I2C_READ ;Temperatur "1" holen sta Temp1 ; jsr I2C_SENDACK ;weiterlesen * ACK an I2C-Device senden bset daten,bpdir ; daten als Ausgang bclr daten,bport ; daten 0 setzen jsr pulse ; 1 x pulsen bset daten,bport ; daten 1 setzen jsr I2C_READ ;Temperatur "2" holen ´ sta Temp2 ; jsr I2C_SENDNACK ; * NACK an I2C-Device senden bset daten,bpdir ; daten als Ausgang bset daten,bport ; daten 1 setzen jsr pulse ; 1 x pulsen jmp I2C_STOP ***************************************************** LCD_Befehl lda #$04 ; Command NICHT gesetzt bra Willi2 ; ***************************************************** LCD_Daten lda #$05 ; Willi2 sta modus_io ; jsr I2C_START ; lda #64 ; Adresse I2C jsr I2C_putbyte ; senden lda basic_io ; Wert holen and #$f0 ; 4 Bit maskieren ora modus_io ; Daten or #5 /Enable toggeln jsr I2C_putbyte ; senden and #$f1 ; Daten or #1 /Enable toggeln jsr I2C_putbyte ; lda basic_io ; Wert holen lsla ; SHL 4-Bit lsla ; lsla ; lsla ; and #$f0 ; 4 Bit maskieren ora modus_io ; Daten or #5 /Enable toggeln jsr I2C_putbyte ; senden and #$f1 ; Daten or #1 /Enable toggeln jsr I2C_putbyte ; ; jmp I2C_STOP ; ****************************************************** * I2C-Bus anhalten ****************************************************** I2C_STOP bset daten,bpdir ; daten als Ausgang bset clock,bpdir ; clock als Ausgang bclr daten,bport ; daten 0 setzen bset clock,bport ; clock 1 setzen bset daten,bport ; daten 1 setzen rts ; zurueck ins Basic ****************************************************** * I2C-Bus starten ****************************************************** I2C_START bset daten,bpdir ; daten als Ausgang bset clock,bpdir ; clock als Ausgang bset clock,bport ; clock 1 setzen bset daten,bport ; daten 1 setzen bclr daten,bport ; daten 0 setzen bclr clock,bport ; clock 0 setzen rts ****************************************************** * Repeated START an I2C-Device senden ****************************************************** I2C_REP_START bset daten,bpdir ; daten als Ausgang bset clock,bport ; clock 1 setzen bclr daten,bport ; daten 0 setzen bclr clock,bport ; clock 0 setzen rts ****************************************************** * Byte an I2C-Bus ausgeben ****************************************************** I2C_WRITE lda basic_io ; zu sendendes Byte holen I2C_putbyte ldx #8 ; 8 Bits seriell ausgeben bset daten,bpdir ; daten als Ausgang shift lsla ; Byte um 1 Bit nach links schieben ; (oberstes Bit ins carrybit) bcc null ; verzweige wenn carrybit 0 bset daten,bport ; sonst daten auf 1 bra eins ; verzweige nach eins null bclr daten,bport ; daten auf 0 (carrybit war 0) eins jsr pulse ; 1 x pulsen decx ; Schiebezaehler -1 bne shift ; naechstes Bit ; jmp pulse ; 1 x pulsen 9. Bit schieben, läuft dann ins stop ****************************************************** * 1 Clock-Signal senden ****************************************************** pulse bset clock,bpdir ; clock als Ausgang bset clock,bport ; clock 1 setzen bclr clock,bport ; clock 0 setzen rts ****************************************************** * Byte vom I2C-Bus lesen ****************************************************** I2C_READ ldx #8 ; Schleifenzhler laden lda #0 ; bisher empfangener Wert = 0 bclr daten,bpdir ; daten auf Eingang stellen bset clock,bpdir ; clock als ausgang loop bset clock,bport ; clock 1 setzen brclr daten,bport,zero ; verzweige wenn Daten = 0 ora bits,x ; ansonsten hole passende Bitmaske und ORe sie zum Wert zero bclr clock,bport ; clock 0 setzen decx ; Schleife um 1 verkleinern bne loop ; bis Schleifenzähler = 0 ; sta modus_io ; Wert an BASIC bergeben bits rts ; "0"tes Byte der Bitmasken (wird nie benutzt) db %00000001, %00000010, %00000100, %00001000 db %00010000, %00100000, %01000000, %10000000 ****************************************************** * Auf ACK vom I2C-Device warten * (geht nicht in eine Endlosschleife wenn kein * ACK empfangen wird (wie C-Control OS-Routine), * sondern bricht nach $dc * $ff * 0,5æs * (ca. 0,5s) ab und uebergibt BASIC * eine Vollzugs- [0] / Fehlermeldung [255]) ****************************************************** ;I2C_GETACK bclr daten,bpdir ; daten als Eingang ; bset daten,bport ; daten 1 setzen ; bset clock,bport ; clock 1 setzen ; lda #$dc ; "grosse" Schleife von 0-220 ;big ldx #$ff ; "kleine" Schleife von 0-255 ;small brclr daten,bport,exit ; wenn daten = 0 ACK empfangen => raus aus der Schleife ; decx ; x = x - 1 ; bne small ; bis x = 0 ; deca ; a = a - 1 ; bne big ; bis a = 0 ; deca ; kein ACK in der vorgegebenen Zeit! => Akku = $FF ; bra tobasic ; an BASIC uebergeben ;exit lda #0 ; ansonsten ACK in der vorgegebenen Zeit empfangen Akku = 0 ;tobasic sta basic_io ; an BASIC uebergeben ; bclr clock,bport ; clock = 0 ; rts ; zurueck ins Basic ; ;****************************************************** ;* ACK an I2C-Device senden ;****************************************************** ;I2C_SENDACK bset daten,bpdir ; daten als Ausgang ; bclr daten,bport ; daten 0 setzen ; jsr pulse ; 1 x pulsen ; bset daten,bport ; daten 1 setzen ; rts ; zurueck ins Basic ; ;****************************************************** ;* NACK an I2C-Device senden ;****************************************************** ;I2C_SENDNACK bset daten,bpdir ; daten als Ausgang ; bset daten,bport ; daten 1 setzen ; jsr pulse ; 1 x pulsen ; rts ; zurueck ins Basic |
| Antwort schreiben |