Portdefinition auch in ASM nicht leicht

Oskar01

Mitglied
24. März 2008
267
0
16
Köln
Sprachen
  1. Assembler
Hallo zusammen,
auch wenn sich das angesprochene Problem mittlerweile gelöst hat,
möchte ich noch einmal diese Thematik durch ein kleines ASM-Prog
untermauern helfen.

Die Syntax:

out portx, temp

ist prinzipiell isoliert gesehen so nicht richtig.

Korrekt wäre es:

ldi temp, 0x00
out ddrx, temp
ldi temp, 0xFF
out portx, temp nur im Zusammenhang mit dem Setzen der Pullup-Widerstände.

Weitere kleine Fiestigkeiten gibt es nun, wenn nicht der gesamte Port
als Eingang/Ausgang sondern nur einzelne Bits deklariert werden sollen.
Und dann noch Ports ständig umfunktioniert werden zwischen Ausgang und Eingang.
Hier muß die Portsynchronisation abgewartet werden in Form von Setzen von NOPs,
da ja bereits eine gewisse "Entprellung" an den Eingängen der Ports wirksam ist.


Ein kleines ASM-Prog zur Demo ist angehängt.
Da ich den PortB verwende, aber nicht extra herumlöten, also
einzelne Strippen ziehen wollte, nur den 10-poligen Stecker verwendete,
dachte ich mir, ich geb's seriell noch aus, was dabei herauskommt.

Funktion:
Taste auf Port B Bit0
Taste losgelassen: LED an PortB Bit1 erlischt; Terminal zeigt Wert 02 an.
Taste gedrückt: LED an PortB Bit1 leuchtet; Terminal zeigt Wert 00 an.

Damit es keinen Kurzschluß gibt, wird Zustand von Taster eine Stelle nach links geschoben,
wo da dann die LED dranhängt.

Hier der interessante Codeschnipsel:

PHP:
;....
ausgabe:
;
nop
ldi	temp,	0xFE	; Port B Bit0 zum
out	ddrb,	temp	; Eingabeport machen
ldi	temp,	0x01	; Pullups aktivieren
out	portb,	temp	; "Knueller": direkt "out" auf "portx"
nop			; Portsynchronisation abwarten
in	temp,	pinb	; Zustand an Port B einlesen
andi	temp,	0x01	; nur Bit0 ausmaskieren
rol	temp		; Wert links schieben, sonst "Kurzschluss"
push	temp		; temp auf Stapel retten
ldi	temp,	0x02	; Port B Bit1 zum
out	ddrb,	temp	; Ausgabeport machen
nop			; Portsynchronisation abwarten
pop	temp		; temp vom Stapel zurueckholen	
out	portb,	temp	; Ausgabe Zustand Bit0 auf Bit1 
;.....


Unten noch angehängt das lauffähige Gesamtprogramm.

Gruß von Oskar01

P.S.:
Der "in" Befehl funktioniert aber auch interessanterweise hier unten im Beispiel
im Zusammemhang mit der "Rettung/Wiederherstellung" des Statusregisters.
Hab's ausprobiert, dann im Umkehrschluß temp auf SREG zurückzukopieren mit "in",
da vermeldet der Assembler/Compiler "Error, wrong register," es wird "out" erwartet.
Eigentlich war ich überrascht, daß nicht wieder auf ein temp vorher "umgeladen"
werden musste (Sozusagen der "Obergefreiten-Schnellweg").
PHP:
;....
push	temp		; Sicherung Temporaer- und
push	temp1		; Statusregister auf Stack
in	temp1,	SREG
push	temp1
;....
und korrespondierend dazu:
PHP:
;.....
pop	temp1		; Temporaerregister und
out	SREG,	temp1	; Statusregister wiederherstellen
pop	temp1
pop	temp
;ret
;.....
 

Anhänge

  • Portdef.asm
    3,5 KB · Aufrufe: 2
Hi Oskar,

Weitere kleine Fiestigkeiten gibt es nun, wenn nicht der gesamte Port
als Eingang/Ausgang sondern nur einzelne Bits deklariert werden sollen.
Und dann noch Ports ständig umfunktioniert werden zwischen Ausgang und Eingang.
Hier muß die Portsynchronisation abgewartet werden in Form von Setzen von NOPs,
da ja bereits eine gewisse "Entprellung" an den Eingängen der Ports wirksam ist.
das mit der Portsynchronisation muß ich mir wohl nochmal ansehen :D
Aber das dauernde Umschalten funktioniert bei meinen 1-Wire-Routinen
recht gut ...


CodeBox ASM
; ##################################################################
; ##################################################################
; #### Dallas 1-Wire-Subroutinen ###################################
; ##################################################################
; ##################################################################

; PC0 ---- SCL | I2C-Interface
; PC1 ---- SDA | (TwoWire)
;
; PC2 ---- EX
; PC3 ---- R/!W
; PC4 ---- IOC2 --- A
; PC5 ---- IOC1 --- B
;
; PC6 ------------- !FE
; PC7 --------------------------------- 1Wire
;
;
; __ ___________ _________
; Init/Reset |________________/ |____________/ :
; : : : : :
; | |- 15-60us -|- 60-240us -| |
; |- >=480us ------|--------- >=480us ------------|
; |- Master Tx ----|----------- Master Rx --------|
;
;
; ___ _______ <1us _______________________
; Master Tx |___________________________/ |_____/ : : :
; : : : : : : : :
; |- 15us -|- 15us -|- 30us -| |- 15us -|- 15us -|- 30us -|
; |----- 60-120us -----------|- >1us -|----- 60-120us -----------|
; | Slave-Sample^ | | Slave-Sample^ |
; |- Master Write 0-Slot ----| |- Master Write 1-Slot ----|
;
;
; ___ >1us _______ >1us ______________________
; Master Rx |____ ________/////////////// |____ // : : :
; : : : : : : : : : :
; |- 15us ---|--- 45us ------|- >1us -|- 15us ---|--- 45us ------|
; | : ^Master-Sample | | : ^Master-Sample |
; ##### vom Master generiert ##### vom Master generiert
;

; ========== DS18S20 - Commands ==========
; 0xF0 - Search ROM 0x44 - Convert T 0x48 - Copy Scratchpad
; 0x33 - Read ROM 0x4E - Write Scratchpad 0xB8 - Recall EEPROM
; 0x55 - Match ROM 0xBE - Read Scratchpad 0xB4 - Read Power Supply
; 0xCC - Skip ROM 0xEC - Alarm Search


; ==================================================================
; ===== 1-Wire initialisieren ======================================
; ==================================================================
d1winit:
push r18 ; r18 auf Stack retten (fuer wiederherstellung)

sbi ddrc,7 ; 1-Wire auf Output
cbi portc,7 ; 1-Wire-Bus auf Low
rcall wait516u ; 516us warten
sbi portc,7 ; 1-Wire-Bus auf High

cbi ddrc,7 ; 1-Wire auf Input
rcall wait33u ; warten
rcall wait33u ; warten

lds r18,d1w_stat ; Status holen
cbr r18,0b00000001 ; Flag loeschen (Vorbereitung kein Present-Puls)
sbis pinc,7 ; 1-Wire-Bus auf High ? = kein Present-Puls vom Slave
sbr r18,0b00000001 ; Flag setzen -> Present-Puls = Slave vorhanden
sts d1w_stat,r18 ; Status sichern

pop r18 ; r18 wiederherstellen
ret ; Subroutine Ende


; ==================================================================
; ===== 1-Wire 0 schreiben =========================================
; ==================================================================
d1wwr0:
sbi portc,7 ; 1-Wire-Bus auf High
sbi ddrc,7 ; 1-Wire auf Output
cbi portc,7 ; 1-Wire-Bus auf Low
rcall wait33u ; warten | ==> 66us
rcall wait33u ; warten |
sbi portc,7 ; 1-Wire-Bus auf High
rcall wait750n ; warten | ==> 1,5us
rcall wait750n ; warten |

ret ; Subroutine Ende


; ==================================================================
; ===== 1-Wire 1 schreiben =========================================
; ==================================================================
d1wwr1:
sbi portc,7 ; 1-Wire-Bus auf High
sbi ddrc,7 ; 1-Wire auf Output
cbi portc,7 ; 1-Wire-Bus auf Low
rcall wait750n ; warten | ==> 750ns
sbi portc,7 ; 1-Wire-Bus auf High
rcall wait33u ; warten | ==> 66us
rcall wait33u ; warten |

ret ; Subroutine Ende


; ==================================================================
; ===== 1-Wire 1 Byte senden =======================================
; ==================================================================
d1wsnd:
push r16 ; r16 auf Stack retten (fuer wiederherstellung)
push r18 ; r18 auf Stack retten (fuer wiederherstellung)

ldi r18,0x08 ; 8 Bits senden

d1wsloop: ror r16 ; r16 in Carry rotieren - LSB zuerst
brcs d1wsnd1 ; Carry gesetzt ?
rcall d1wwr0 ; Carry geloescht also 0 senden
rjmp d1wcont ; -> Continue
d1wsnd1: ; 1-Wire Send 1
rcall d1wwr1 ; Carry war gesetzt also 1 senden

d1wcont: ; Continue
dec r18 ; Bit-Zaehler incrementieren
brne d1wsloop ; weiter senden (noch keine 8 Bit)

pop r18 ; r18 wiederherstellen
pop r16 ; r16 wiederherstellen
ret ; Subroutine Ende


; ==================================================================
; ===== 1-Wire lesen ===============================================
; ==================================================================
d1wrd:
sbi portc,7 ; 1-Wire-Bus auf High
sbi ddrc,7 ; 1-Wire auf Output
cbi portc,7 ; 1-Wire-Bus auf Low
rcall wait750n ; warten | ==> 1,5us
rcall wait750n ; warten |
sbi portc,7 ; 1-Wire-Bus auf High

cbi ddrc,7 ; 1-Wire auf Input
rcall wait10u ; 14us warten
sec ; Set Carry
sbis pinc,7 ; 1-Wire-Bus auf High ? = 1 vom Slave
clc ; Clear Carry
ror r16 ; Bit in r16 einrotieren C->76543210
; Nach 8 Durchlaeufen ist das Byte voll und
; die Bits an der richtigen Position
rcall wait33u ; warten | ==> 66us
rcall wait33u ; warten |

ret ; Subroutine Ende


; ==================================================================
; ===== 1-Wire 1 Byte empfangen ====================================
; ==================================================================
d1wrec:
push r18 ; r16 auf Stack retten (fuer wiederherstellung)

clr r16 ; Empfangsregister loeschen
ldi r18,0x08 ; 8 Bits empfangen

d1wrloop: ;
rcall d1wrd ; Bit einlesen
dec r18 ; Bit-Zaehler incrementieren
brne d1wrloop ; weiter empfangen (noch keine 8 Bit)

pop r18 ; r16 wiederherstellen
ret ; Subroutine Ende


Da wird ein Port-Bit für den Datenempfang zuerst als Ausgang genutzt um
die Startflanke für den 1-Wire-Slave zu erzeugen und danach sofort auf
Eingang umgeschaltet um das gesendete Bit vom Slave lesen zu können.
Bei der Subroutine d1wrd (Dallas 1-Wire Read) ist das gut zu sehen.

Gruß
Dino
 
... meine Rolle als Moderator ....

Hallo Jungs,

jetzt wirds leicht Off-Topic und ich vermute Michael stellt es gerade die Nackenhaare zu Berge, oder Michael?

Das Thema finde ich sehr spannen und würde es gern an anderer Stelle weiterdiskutieren. Bitte macht doch dazu einen eigene Thread auf wo Ihr Euch austoben könnt, oder?

Grüße,
Ma

Ergänzung: Habe Eure Beiträge zu einem eigenen Thread zusammengefasst. OK?

Grüße,
Ma
 
Hi Markus,

jetzt wirds leicht Off-Topic und ich vermute Michael stellt es gerade die Nackenhaare zu Berge, oder Michael?

Ergänzung: Habe Eure Beiträge zu einem eigenen Thread zusammengefasst. OK?
ich glaube da gingen die Pferde ein wenig mit uns durch :D :D
Von BASCOM über Ports zu Assembler :rolleyes:
Geht OK.

Gruß
Dino
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)