Sehr geehrtes Forum,
ich habe folgenden Versuchsaufbau:
Einen Atmega88, angeschlossen an einen MAX232, welcher
über RS232 an einen PC angeschlossen ist, und am PC
über das Programm HTerm empfangen wird.
Ich verwende folgenden Code:
1
.include "m88def.inc" // Definitionsdatei für den Prozessortyp einbinden
.error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!"
33
.endif
34
35
// Transceiver Definitionen
36
.def EMPFANGEN_BYTE = R16
37
.def ZU_SENDEN_BYTE = R17
38
39
// Main Methode
40
MAIN:
41
// RS232 Initialisieren
42
RCALL RS232_INIT
43
44
// AKTIVIEREN von SENDEN UND EMPFANGEN
45
RCALL ACTIVATE_RS232_TRANSMIT
46
RCALL ACTIVATE_RS232_RECEIVE
47
48
SBI PORTB, PINB0
49
50
// EMPFANGEN von BYTE
51
RCALL RECEIVE_BYTE
52
53
// Warte eine Sekunde
54
RCALL WAIT_SEC
55
56
// LED SIGNAL
57
CBI PORTB, PINB0
58
SBI PORTB, PINB1
59
60
// Zurücksenden der Nachricht
61
MOV ZU_SENDEN_BYTE, EMPFANGEN_BYTE
62
RCALL TRANSMIT_BYTE
63
RJMP MAIN
64
65
// RS232 Initialisierung
66
RS232_INIT:
67
// Baudrate einstellen
68
LDI R16, HIGH(UBRR_VAL)
69
STS UBRR0H, R16
70
LDI R16, LOW(UBRR_VAL)
71
STS UBRR0L, R16
72
73
// Frame Format einstellen (8 Bit)
74
LDI R16, (1<<UCSZ01)|(1<<UCSZ00)
75
STS UCSR0C, R16
76
RET
77
78
// RS232 Steuerungsfunktionen
79
ACTIVATE_RS232_TRANSMIT:
80
LDS R20, UCSR0B
81
SBR R20, (1<<TXEN0)
82
STS UCSR0B, R20
83
RET
84
85
DEACTIVATE_RS232_TRANSMIT:
86
LDS R20, UCSR0B
87
CBR R20, (1<<TXEN0)
88
STS UCSR0B, R20
89
RET
90
91
ACTIVATE_RS232_RECEIVE:
92
LDS R20, UCSR0B
93
SBR R20, (1<<RXEN0)
94
STS UCSR0B, R20
95
RET
96
97
DEACTIVATE_RS232_RECEIVE:
98
LDS R20, UCSR0B
99
CBR R20, (1<<RXEN0)
100
STS UCSR0B, R20
101
RET
102
103
TRANSMIT_BYTE:
104
LDS R20, UCSR0A
105
SBRS R20, UDRE0
106
RJMP TRANSMIT_BYTE
107
108
STS UDR0, ZU_SENDEN_BYTE
109
RET
110
111
RECEIVE_BYTE:
112
LDS R20, UCSR0A
113
SBRS R20, RXC0
114
RJMP RECEIVE_BYTE
115
116
LDS EMPFANGEN_BYTE, UDR0
117
RET
118
119
// Warte Methoden
120
WAIT_SEC:
121
LDI R21,255
122
123
WAIT_SEC_22:
124
RCALL WAIT_SEC_2
125
DEC R21
126
BRNE WAIT_SEC_22
127
RET
128
129
WAIT_SEC_2:
130
LDI R20,255
131
132
WAIT_SEC_21:
133
RCALL WAIT_SEC_1
134
DEC R20
135
BRNE WAIT_SEC_21
136
RET
137
138
WAIT_SEC_1:
139
NOP
140
NOP
141
NOP
142
NOP
143
NOP
144
NOP
145
NOP
146
NOP
147
NOP
148
NOP
149
RET
Folgendes soll geschehen:
Grüne LED leuchtet,
ich sende ein Zeichen vom PC aus,
eine Sekunde nach Ankommen geht die grüne aus, und die rote leuchtet,
und das empfangene Byte wird zurückgesendet
Folgendes geschieht:
Grüne LED leuchtet,
ich sende ein Zeichen vom PC aus,
eine Sekunde nach Ankommen leuchtet die Rote, die grüne seltsamerweise
immer noch,
als Antwort immer das gleiche, 216, 195
Ich wäre dankbar für eure Hilfe, wenn mir jemand erklären könnte was ich
falsch mache, danke für eure Hilfe,
m.f.G:: Developer_X
Bevor wir uns auf das Programm stürzen, erst mal die naheliegenste
Frage.
Hast du schon getestet, ob deine Serielle grundsätzlich funktioniert?
D.h. du hast ein Programm, welches ständig ein zb 'U' sendet und an
deinem Terminal taucht auch tatsächlich ein 'U' auf?
Problem gelöst,
lag daran, dass die Mainschleife wieder von vorne beginnt,
was sie gar nicht sollte.
Danke trotzdem,
m.f.G.: Developer_X
@KBuchegg:
das hat schon geklappt, ich wollte so etwas wie ein Echo programmieren,
als kleine spielerei, man sendet ein zeichen, und eine sekunde kommt es
wieder
A. B. schrieb:> Problem gelöst,> lag daran, dass die Mainschleife wieder von vorne beginnt,> was sie gar nicht sollte.
Quatsch mit Soße. Es lag daran, dass du die Initialisierung in der
Hauptschleife gemacht hast, statt davor, wo sie hingehört.
Nicht die böse Hauptschleife ist schuld, sondern einfach nur du selber!
So einfach ist das.
Das ist das Schlimme bei Assembler: du kannst dich nicht auf
irgendwelche kaputte Libs oder sonstige schrägen Schutzbehauptungen
herausreden wie die regulären C&P-C-ler. Die CPU macht (bei einwandfrei
funktionierender Hardware) immer genau das, was du ihr sagst und das ist
eben auch exakt das, was du hinschreibst.
D.h.: wenn's nicht so funktioniert, wie du wolltest, brauchst du
(fast) niemals aufwendig nach einem Schuldigen suchen: in 99,9999% der
Fälle warst du es selbst...
Hier, in diesem konkreten Fall, ist aber wohl ein besonderes Problem
akut, kein Problem der Sprache oder der Maschine, sondern ein rein
kognitives.
Du versuchst offensichtlich, Code-Einrückungen der Art zu erzeugen, wie
sie in einer strukturierten Programmiersprache sinnvoll wären. Das kann
in Asm nur schief gehen, weil Asm eben gerade keine strukturierte
Programmiersprache, sondern von Natur aus in einer "GOTO-Hölle" gefangen
ist. Jedenfalls dann, wenn man die Peformance-Vorteile der Sprache
wirklich nutzen möchte...
Deine Gewohnheiten beim Lesen von Code sind aber offensichtlich stark
von einer strukturierten Sprache geprägt. Vermutlich war genau das das
Problem, was es dir unmöglich gemacht hat, selber zu erkennen, dass die
Initialisierung innerhalb der Schleife liegt...
Einzig mögliche Abhilfe: Programmieren bis der Arzt kommt und dabei aus
Fehlern lernen. Mit der Zeit gewöhnt man sich auch an grundsätzlich
verschiedene Stile zu Code-Einrückung. Man muß einfach nur oft genug in
den verschiedenen Welten programmieren.
Oder anders ausgedrückt: Eine reine Fleißaufgabe. Oder auch: noch'n
Winter und auch du kommst dahinter...