Forum: Mikrocontroller und Digitale Elektronik Probleme ATmega8


von Peter (Gast)


Angehängte Dateien:

Lesenswert?

1
.include "m8def.inc"  ;ACHTUNG in FUSES Frequenz auf 1MHZ stellen!    
2
 
3
         ldi r16, 0xFF      ;Port B sind Ausgänge
4
         out DDRB, r16         ;Port B Ausgänge
5
                             
6
         ldi r16, 0x00      ;Port D sind Eingänge
7
         out DDRD, r16         ;Port D Eingänge
8
9
     .cseg
10
     rjmp Power
11
12
     .org OVF0addr
13
         rjmp    timer0_overflow       ; Timer Overflow Handler
14
15
Power:   sbic PinD, 1
16
     sbi PortB, 2
17
     ldi r28, 1
18
     rjmp Ausw
19
Power1:  ldi r28,0
20
         
21
      ldi r27, 1
22
     rjmp timer
23
test:   ldi r27, 0
24
     cbi PortB, 2
25
     rjmp Start    ; Überspringen der TimerOVV
26
27
wait:   rjmp Timer
28
  
29
30
Start:   sbis PinD, 1      ; PinD1 (Aus) unbetätigt
31
     rjmp Ausw  ; Wenn Aus betätigt springe zu Aus
32
     sbis PinD, 5    ; PinD5 (Störung) unbetätigt
33
     rjmp stoerung    ; Wenn Störung betätigt springe zu stoerung
34
     sbic PinD, 0    ; Ein betätigt
35
     rjmp Start    ; Wenn ein betätigt dann gehts Weiter
36
37
Motor_AN:sbis PinD, 1      ; PinD1 (Aus) unbetätigt
38
     rjmp Ausw  ; Wenn Aus betätigt springe zu Aus
39
     sbis PinD, 5  ; PinD5 (Störung) unbetätigt
40
     rjmp stoerung  ; Wenn Störung betätigt springe zu stoerung
41
     sbic PinD, 0    ; Ein betätigt
42
     rjmp Start    ; Wenn ein betätigt dann gehts Weiter
43
44
     cbi PortB, 2    ; Störung löschen
45
     sbi PortB, 0  ; Setze PortB 0 (Motor geht an)
46
      
47
       ldi r25, 4    ; Lade r25 mit 4
48
     ldi r26, 1    ; Lade r26 mit 1
49
     rjmp Timer    ; Springe zu Wait
50
51
Flanke:   tst r25        ; Prüfe r25 auf null
52
       brne wait
53
     ldi r25, 0    ; Lade R25 mit 0
54
     ldi r26, 0    ; Lade R26 mit 0
55
     sbis PinD, 0    ; Ein losgelassen
56
     rjmp Flanke  ; Solange wie Ein gedrückt, Warten
57
58
Wahl:   ldi r23, 0      ; Lade r23 mit 0
59
     ldi r23, 77    ; Lade r23 mit 77
60
Wahl1:   cbi PortB, 1      ; Ventil Aus
61
     ldi r18,0    ; Lade r18 mit 0
62
     ldi r19,0    ; Lade r19 mit 0
63
     ldi r20,0    ; Lade r20 mit 0
64
     ldi r21,0    ; Lade r21 mit 0
65
     ldi r22,0    ; Lade r22 mit 0
66
     sbis PinD, 1    ; PinD1 (Aus) unbetätigt
67
     rjmp Aus    ; Wenn Aus betätigt springe zu Aus
68
     sbis PinD, 5  ; PinD5 (Störung) unbetätigt
69
     rjmp Aus    ; Wenn Aus betätigt springe zu Aus
70
     sbis PinD, 0      ; Ein betätigt
71
     rjmp Man    ; Wenn ein betätigt dann gehts Weiter
72
     sbis PinD, 2      ; Auto betätigt
73
     rjmp Auto1      ; Springe zu Auto 1
74
     tst r23      ; r23 auf null testen
75
     breq Aus5
76
     rjmp Timer      ; Springe zu Timer
77
     
78
79
Man:   sbis PinD, 1    ; PinD1 (Aus) unbetätigt
80
     rjmp Aus    ; Wenn Aus betätigt springe zu Aus
81
     sbis PinD, 5    ; PinD5 (Störung) unbetätigt
82
     rjmp Aus    ; Wenn Aus betätigt springe zu Aus
83
     sbic PinD, 0           ; Ein betätigt
84
     rjmp Wahl  ; Wenn ein betätigt dann gehts Weiter
85
86
     sbi PortB, 1    ; Setze PortB 1 (Ventil zieht an)
87
88
Man2:   sbis PinD, 1      ; PinD1 (Aus) unbetätigt
89
     rjmp Aus    ; Wenn Aus betätigt springe zu Aus
90
     sbis PinD, 5    ; PinD5 (Störung) unbetätigt
91
     rjmp Aus    ; Wenn Aus betätigt springe zu Aus
92
     sbis PinD, 0    ; Ein betätigt
93
     rjmp Man2    ; Wenn ein unbetätigt dann gehts Weiter
94
95
     cbi PortB, 1  ; Lösche PortB 1 (Ventil fällt ab)
96
97
     rjmp Wahl    ; Springe wieder zur Wahl 
98
99
Auto1:   sbis PinD, 1      ; PinD1 (Aus) unbetätigt
100
     rjmp Aus      ; Wenn Aus betätigt springe zu Aus
101
     sbis PinD, 5    ; PinD5 (Störung) unbetätigt
102
     rjmp Aus      ; Wenn Aus betätigt springe zu Aus
103
     sbic PinD, 2    ; Auto betätigt
104
     rjmp Wahl    ; Wenn nicht dann zu Wahl
105
106
     sbi PortB, 1    ; Setze PortB 1 (Ventil zieht an)
107
108
Auto2:   sbis PinD, 1      ; PinD1 (Aus) unbetätigt
109
     rjmp Aus      ; Wenn Aus betätigt springe zu Aus
110
     sbis PinD, 5    ; PinD5 (Störung) unbetätigt
111
     rjmp Aus      ; Wenn Aus betätigt springe zu Aus
112
     sbic PinD, 2    ; Auto betätigt
113
     rjmp Wahl    ; Wenn nicht dann zu Wahl
114
     ldi r18,1    ; Setze r18 auf 1
115
     ldi r19,4    ; Lader r19 mit 4
116
     rjmp Timer    ; Springe zum Timer
117
118
Weiter2: sbis PinD, 1      ; PinD1 (Aus) unbetätigt
119
     rjmp Aus    ; Wenn Aus betätigt springe zu Aus
120
     sbis PinD, 5    ; PinD5 (Störung) unbetätigt
121
     rjmp Aus    ; Wenn Aus betätigt springe zu Aus
122
     sbic PinD, 2    ; Auto betätigt
123
     rjmp Wahl    ; Wenn nicht dann zu Wahl
124
     tst r19      ; Teste r19 auf Null          
125
     brne Timer    ; Springe bei r19 ungleich 0
126
     sbic PinD, 3    ; 3bar erreicht?
127
     rjmp Weiter2    ; Warten bis 3bar
128
     dec r18      ; r18 - 1
129
130
     cbi PortB, 1  ; Lösche PortB 1 (Ventill fällt ab)
131
132
     rjmp Auto3
133
Aus5:   rjmp Aus
134
     rjmp Auto3
135
Power2:   rjmp Power1
136
137
Auto3:    sbis PinD, 1      ; PinD1 (Aus) unbetätigt
138
     rjmp Aus      ; Wenn Aus betätigt springe zu Aus
139
     sbis PinD, 5    ; PinD5 (Störung) unbetätigt
140
     rjmp Aus      ; Wenn Aus betätigt springe zu Aus
141
     sbic PinD, 2    ; Auto betätigt
142
     rjmp Wahl    ; Wenn nicht dann zu Wahl
143
     ldi r20,1    ; Setze r20 auf 1
144
     ldi r19,4    ; Lader r19 mit 4
145
     rjmp Timer    ; Springe zum Timer
146
147
Weiter3: sbis PinD, 1      ; PinD1 (Aus) unbetätigt
148
     rjmp Aus      ; Wenn Aus betätigt springe zu Aus
149
     sbis PinD, 5    ; PinD5 (Störung) unbetätigt
150
     rjmp Aus      ; Wenn Aus betätigt springe zu Aus
151
     sbic PinD, 2    ; Auto betätigt
152
     rjmp Wahl    ; Wenn nicht dann zu Wahl
153
     tst r19      ; Teste r19 auf Null          
154
     brne Timer    ; Springe bei r19 ungleich 0
155
     sbic PinD, 4    ; 90bar erreicht
156
     rjmp Weiter3    ; wenn nicht dann warte
157
     dec r20      ; r20 -1
158
159
     sbi PortB, 1    ; Setze PortB 1 (Ventil zieht an)
160
161
     rjmp Auto1    ; Wieder von vorne beginnen
162
163
Aus:   cbi PortB, 0       ; Lösche PortB 0 (Motor aus)
164
     cbi PortB, 1    ; Lösche PortB 1 (Ventil fällt ab)
165
Ausw:   ldi r21, 1      ; Lade r21 mit 1
166
     ldi r19,4    ; Lade r19 mit 4
167
168
     rjmp Timer
169
170
Kurz:   tst r19        ; Teste r19 auf Null          
171
     brne Timer    ; Springe bei r19 ungleich 0 
172
     dec r21      ; r21-1
173
     sbi PortB, 1    ; Setze PortB 1 (Ventil zieht an)
174
     ldi r22,1    ; Lade r22 mit 1
175
     ldi r19,4    ; Lade r19 mit 4
176
177
     rjmp Timer
178
179
Kurz1:   tst r19        ; Teste r19 auf Null        
180
     brne Timer    ; Springe bei r19 ungleich 0   
181
      dec r22      ; r22-1
182
     cbi PortB, 1     ; Lösche PortB 1 (Ventil fällt ab)
183
184
     sbis PinD, 1    ; Aus noch betätigt?
185
     rjmp Kurz1    ; Warte bis losgelassen
186
     sbis PinD, 5    ; Störung noch betätigt?
187
     rjmp stoerung
188
     tst r28
189
     brne Power2
190
191
     rjmp Start
192
193
Timer:   ldi     r17, HIGH(RAMEND)  ; Stackpointer initialisieren
194
         out     SPH, r17
195
         ldi     r17, LOW(RAMEND)     
196
         out     SPL, r17
197
    
198
         ldi     r17, (1<<CS02) | (1<<CS00)   ; Teiler 1024
199
200
         out     TCCR0, r17
201
 
202
         ldi     r17, (1<<TOIE0)      ; TOIE0: Interrupt bei Timer Overflow
203
         out     TIMSK, r17
204
 
205
         sei
206
 
207
loop:   rjmp loop
208
 
209
timer0_overflow:                 ; Timer 0 Overflow Handler
210
        
211
     nop  
212
     dec r19      ; r19 - 1
213
     dec r23      ; r23 - 1
214
     dec r25      ; r25 - 1
215
216
zum1:   tst r27        ; r27 auf null testen
217
     breq zum2    ; Wenn Null dann zu nächstem
218
     rjmp test    ; Springe zu Weiter 2
219
220
zum2:   tst r20        ; r20 auf null testen
221
     breq zum3    ; Wenn Null zum nächsten
222
     rjmp Weiter3    ; WSpringe zu Weiter 3
223
224
zum3:   tst r21        ; r21 auf null testen
225
     breq zum4    ; Wenn null dann zum nächsten
226
     rjmp Kurz    ; Springe zu Kurz
227
228
zum4:   tst r22        ; r22 auf null testen
229
     breq zum5    ; Wenn null dann zu nächsten
230
     rjmp Kurz1    ; Springe zu Kurz 1   
231
232
zum5:   tst r26        ; r26 auf null testen
233
     breq zum6    ; Wenn null dann zum nächsten    
234
     rjmp Flanke    ; Springe zu Flanke
235
236
zum6:   tst r18
237
     breq zum7
238
     rjmp Weiter2
239
240
zum7:    rjmp Wahl1      ; Springe zu Wahl 1
241
242
stoerung:sbi PortB, 2      ; Störungs LED an
243
     sbis PinD, 5    ; Störung noch betätigt
244
     rjmp stoerung    ; LED bleibt an
245
     cbi PortB, 2    ; LED aus
246
     rjmp Start    ; Springe zu Start
247
    
248
ende:    rjmp ende

Hallo Leute,

folgende Schaltung und Programm wie oben zusehen.
An sich ist auch alles toll und läuft, WENN das erste einschalten 
erfolgreich war. Was mein ich:
Ich stecke denn Stecker in die Steckdose. Nun Soll PortB 2 gesetzt 
werden, PortB 1 anziehen, 1 Sekunde warten abfallen, und PortB 2 
gelöscht werden.
Nur das passiert nicht, PortB2 wird gesetzt und nach ca. einer halben 
Sekunde wieder gelöscht. Wenn ich jedoch denn Stecker ziehe und sofort 
wieder in die Dose Stecke dann kann es sein, dass der Schritt 
erfolgreich ist.
Meine vermutung, die Timer werden beim ersten mal nicht bearbeitet oder 
so.
Bitte schaut euch mal mein Programm an. Wie gesagt wenn es mal läuft 
dann geht alles ohne Probleme, daher ist eigentlich ein 
Programmierungsfehler sowie Schaltungsfehler fast nicht möglich. Aber 
wieder ist dieser Fehler immer nur beim ersten mal Spannungzuschalten 
da?
Kennt jemand das Problem?

Grüße

von Holger P. (Gast)


Lesenswert?

Nun so werde ich mal versuchen dir in ASM zu helfen :-)

Dein Program beschreibt die Interruptvektoren. Was da so alles passiert. 
Dafür bin ich noch zu neu.

Aber versuche es mal so:
1
.include "m8def.inc"
2
 
3
.org 0x000                    ; kommt ganz an den Anfang des Speichers
4
         rjmp reset           ; Interruptvektoren überspringen
5
                              ; und zum Hauptprogramm
6
         reti                 ; IRQ0 Handler
7
         reti                 ; IRQ1 Handler
8
         reti           
9
         reti           
10
         reti                 ; Timer1 Capture Handler
11
         reti                 ; Timer1 CompareA Handler
12
         reti                 ; Timer1 CompareB Handler
13
         reti                 ; Timer1 Overflow Handler
14
         rjmp timer0_overflow ; Timer0 Overflow Handler
15
         reti                 ; SPI Transfer Complete Handler
16
         reti                 ; USART RX Complete Handler
17
         reti                 ; UDR Empty Handler
18
         reti                 ; USART TX Complete Handler
19
         reti                 ; ADC Conversion Complete Interrupthandler
20
         reti                 ; EEPROM Ready Handler
21
         reti                 ; Analog Comparator Handler
22
         reti                 ; Two-wire Serial Interface Handler
23
         reti                 ; Store Program Memory Ready Handler
24
 
25
reset:                        ; hier beginnt das Hauptprogramm
26
27
         ldi r16, LOW(RAMEND)
28
         out SPL, r16
29
         ldi r16, HIGH(RAMEND)
30
         out SPH, r16
31
32
33
34
         ldi r16, 0xFF        ;Port B sind Ausgänge
35
         out DDRB, r16        ;Port B Ausgänge
36
                             
37
         ldi r16, 0x00        ;Port D sind Eingänge
38
         out DDRD, r16        ;Port D Eingänge
39
40
Power:

Du solltest auch immer den Stack initialisieren.

Nur so ein Tipp von einem unwissenden :-)

Ach ja
1
ldi r18,0    ; Lade r18 mit 0
2
     ldi r19,0    ; Lade r19 mit 0
3
     ldi r20,0    ; Lade r20 mit 0
4
     ldi r21,0    ; Lade r21 mit 0
5
     ldi r22,0    ; Lade r22 mit 0

warum schreibst du nicht

clr r19

ist übersichtlicher. So muss man erst schauen mit was du r19 
beschreibst. Anderst sieht man es sofort.

Sorry aber um so mehr ich in deinem Programm lese um soo schwindliger 
wird es mir. Ich mach das ja auch noch nicht so lange. Aber du solltest 
ein Interupt immer mit reti beenden.

Ei Ei Ei ich lese lieber nicht in dem Code weiter. Wer weiß was da noch 
alles kommt grins

von Wolfgang (Gast)


Lesenswert?

Ähh, Du weißt schon, daß PC6 = Anschluß 1 der *Reset ist? Da gehört 
erstmal ein 100n gegen Masse dran und der R1 kann prinzipiell entfallen. 
War das erste, was mir aufgefallen ist, bevor ich Deinen Quellcode 
überflog. Ohne mich darüber auszulassen 8-) mach erstmal den 
*Reset-Kerko dran.

Gruß - Wolfgang

von Holger P. (Gast)


Lesenswert?

Sorry Wolfgang.. Ich glaub da liegst Du falsch. Reset immer über ein 
Wiedrstand gegen Plus..

von Wolfgang (Gast)


Lesenswert?

Wozu, Holger?

Der ATMega8 hat einen 60kR-Widerstand intern als Pull-up. Beweis: 
Datenblatt (Version 2486P-AVR-02/06), S. 242 ganz unten (30-80kR).

Gruß - Wolfgang

von Holger P. (Gast)


Lesenswert?

Nun das kann sein, bin ja noch recht neu bei der Sache. Beim ATMega88 
mach ich das immer so. Falsch ist es aber nicht, bzw. führt zu keinem 
Fehler ODER?

von Wolfgang (Gast)


Lesenswert?

Anschluß 1 = PC6 = *Reset. 30-60kR int. Pull-up. Beweis: Datenblatt 
(Version 2545K-AVR-04/07) S. 304.

Wer µC/µP ohne ordentlichen Rücksetzer betreibt, gehört mit Stacheldraht 
ausgepeitscht 8-P

Gruß - Wolfgang

von Holger P. (Gast)


Lesenswert?

Kleiner Nachtrag an Peter:

Bitte so das nicht euren Kunden verkaufen. grins

Zitat: "Das bestens ausgebildete und erfahrene Servicepersonal sichert 
die Wartung, Instandhaltung,...."

Ei Ei Ei

von Peter (Gast)


Lesenswert?

Danke bis hierher.
Die Sache mit dem Pullup an PC6 oder nicht ist ja nicht Grunde des 
Problems. Die Schaltung funktioniert ja wenn die erste Hürde 
übersprungen ist.
Um genau zu sein, drücke ich nach dem herstellen der Stromversorgung 
denn Aus-Taster PinD1, dann passiert nichts. Ich kann Tasten drücken wie 
ich lustig bin. Nach einer willkürlichen Zeit jedoch, schalten die 
Ausgänge wie sie müssen und alles Läuft super. Ich hoffe es ist 
verständlich.

Holger: Würde ich es so verkaufen wollen, wäre ich kaum hier?
        Ich möchte einfach denn letzten Bug ausmerzen, also aus dem 
Windows
        ein Linux machen ;-)

von Holger P. (Gast)


Lesenswert?

Nun so wie dein Programm aussieht ist da mehr als ein Bug drinnen. Wie 
getippt schau mal was Du mit Deinen Interuptvektoren machst. Schau mal 
deine Stack inistlisierung an. Und kein reti aus dem Iterrupt macht die 
dein falsch instalierten Stack voll ohnen ende bis es knallt. Nur eine 
Frage der Zeit wie oft man da drücken kann.

Sorry wenn ich das so tippe aber so wie der Code da aussieht würde ich 
das schnell in die Tonne werfen mir mal grundlegent gedanken machen und 
ein Programmablauf schreiben und danach das Programm neu schreiben.

Bis jetzt ist es echte Glückssache das es überhaupt läuft.

von Stulle (Gast)


Lesenswert?

moin

Stackoverflow :-)

du darfst nicht so wie du das machst aus der Interuptroutine einfach mit 
rjmp irgendwo im Prog. weitermachen . Bei jedem Interupt wird die 
Rücksprungadresse auf den stack gelegt , du sammelst also 
rücksprungadressen bis der stack überläuft (ram ist voll).Du müsstest 
dir anstatt direckt ins Prog. zu verzweigen einen Merker basteln und in 
der mainloop darauf reagieren .
siehe AVR-Tutorial - Interupts
http://www.mikrocontroller.net/articles/AVR-Tutorial

mfg

von Peter (Gast)


Lesenswert?

@ Stulle
Danke klingt logisch, aber wieso tritt der Fehler nur beim ersten mal 
anstecken auf? Da ist doch an sich alles leer im Speicher?
Wie sollte das mit Merker - Mainloop usw aussehen?
Hast du da ein kurzes Beispiel?

von Holger P. (Gast)


Lesenswert?

Du glaubst mir nicht oder?

Schau Dir erst mal deine Interruptvektoren an. Wie das aussehen sollte 
tippte ich Dir am Anfang.

Und überlege dir mal was du so alles in

Loop:
     rjmp Loop


machen könntest.

von Stulle (Gast)


Lesenswert?

siehe
Einfache Tastenentprellung und Abfrage
http://www.mikrocontroller.net/articles/AVR-Tutorial:_Tasten

von Holger P. (Gast)


Lesenswert?

Nehmen wir nur mal ein Gedankengang.

Du hast einen Sprung zu Power1:
Dieser wird nur von dem Sprung unter Power2 aufgerufen.
Power2 wird wiederum nur nach einem vergleich am ende von Kurz1: 
aufgerufen.

Na klasse
1
Power1:  ldi r28,0
2
         
3
        ldi r27, 1
4
        rjmp timer
5
6
7
Power2:   rjmp Power1
8
9
10
11
12
Kurz1:   
13
      ...
14
      ...
15
      ...
16
      ...
17
     tst r28
18
     brne Power2
19
     rjmp Start

Da frage ich mich warum nicht so?
1
Kurz1:   
2
      ...
3
      ...
4
      ...
5
      ...
6
     tst r28     
7
     breq Start
8
     ldi  r28,0
9
     ldi  r27,1
10
     rjmp timer

Was ich damit aufzeigen möchte ist das dein Code total verwirrt und 
verzweigt und und und. Mach einwenig struktur rein. Die Maschinen sollen 
doch von aussen auch fein aussehen und nicht zusammengewürfelt werden. 
Auch da wird systematisch gedacht. Wo hier. Wirkt mir einwenig nach hin 
und her flicken bis es eventuell passt.

Das war nur ein stück aus Deinem Code.
1
wait:     rjmp Timer
2
3
4
Flanke:   tst r25        ; Prüfe r25 auf null
5
          brne wait

warum nicht gleich
1
Flanke:   tst r25        ; Prüfe r25 auf null
2
          brne Timer

von Peter (Gast)


Lesenswert?

Jip hast ja recht, es ist halt aus einer Grundidee entstanden und immer 
weiter gewachsen. Werde morgen nochmal neu ran gehen.

von Holger P. (Gast)


Lesenswert?

Bevor Du neu ran gehst. Schau mal unter Interrupt nach und unter Stack.
Es ist immer hilfreich seine Programme zu kommentieren. eine Komentar 
wie

ldi r22,1    ; Lade r22 mit 1
ldi r19,4    ; Lade r19 mit 4

ist für die Katze. Das Du r22 mit 1 beschreibst steht doch in der Zeile. 
Warum machst Du das welch ein Gedankengang steckt dahinter.

FlussDiagramm zeichnen und danach Programmieren.

Was mir auch noch nicht klar ist. Warum deine Taster einmal gegen Masse 
und einmal gegen Plus schalten. Aber das ist etwas was die Schaltung 
angeht. Alles auf ein nenner da ist das Durchblicken nachher besser. 
Auch im Code sieht es besser aus das wen ein Tatser gedrückt wird immer 
das gleiche Passiert.. also immer High wenn gedrückt oder immer Low wenn 
gedrückt. Aber einaml so und einmal so.. Was steckt dahinter.

Wie getippt Ihr geht damit auf Menschen los un 9bar ist nicht wenig. So 
ein Ding sollte doch eigentlich sicher laufen und nicht zufällig und man 
weiß nicht warum.

Warum dafür einen Mega da tut es doch lange ein ATiny2313 ist billiger.. 
also mehr Gewinn für euch.

von oldmax (Gast)


Lesenswert?

Hi
Ok, da ist noch eine Menge Holz, was aufgearbeitet werden muß. Mir fällt 
auf, den Stack setzt du unter Timer und den springst du aus allen 
möglichen Ecken deines Programmes an. Ok, es gibt so ich es gesehen 
habe, keinen Call, aber vermutlich eine ISR ( Interrupt Service Routine 
) Die braucht den Stack unbedingt. Wenn du ihn mehrfach wieder neu 
setzt, macht dein Programm sowieso was es will. Mal zur Struktur:
Du beginnst mit derVariablenvereinbarung im DSeg. Im Codesegment (CSeg:) 
kommt ein Sprung zu deinem Programm, um über die IVT ( Interrupt 
Vektortabelle hinwegzukommen und nicht dort hineinzulaufen.
Das ist dein
Start:
Hier erfolgt als erstes ! die zuweisung für den Stack. In Folge die 
initialisierung von Timer, IO's, serieller Schnitstelle und die 
Vorbesetzung von Variablen und Registern.
Dazu, damit es schön übersichtlich wird, schreibst du separate Routinen, 
die du mit RCALL aufrufst und mit Ret abschließt. Vorteil: Hast du in 
einer Routine etwas vergessen oder mußt etwas ändern, kannst du gezielt 
nachsehen und mußt nicht das gesamte Prrogramm durchblättern. Außerdem 
ist es schön einfach, wenn man schon im Kopf einer solchen Routine 
Kommentarzeilen mit der Funktionsbeschreibung hinterlegt.
Etwas so:
1
;------------- Initialisieren der IO-Pins  -----------------
2
;*                Port B 0 - 5 sind Ausgänge               *
3
;*                Port B 6 bleibt Reset                    *
4
;*                usw.                                     *
5
;***********************************************************
6
Init_IO:
7
  ....
8
  ....
9
RET
Wenn du alle deine Unterprogramme so  kommentierst, dann ist es ein 
leichtes, den Überblick zu behalten.
Sind alle deine Initialisierungen abgeschlossen, dann kommen wir zu der 
Programmschleife. Auch hier arbeite mit Unterprogrammen !
1
Loop:
2
   RCALL Read_IO      ; Einlesen der Eingänge
3
   RCALL Set_Flanken  ; Flanken erfassen (0 nach 1 oder 1 nach 0)
4
   RCALL Do_Job_a     ; bearbeite Informationen
5
   RCALL Do_Job_n     ; dto
6
   RCALL Write_IO     ; Ausgabe an Peripherie
7
RJMP Loop
Nun folgen die Unterprogramme.
1
;------------- Initialisieren der IO-Pins  -----------------
2
;*                Port B 0 - 5 sind Ausgänge               *
3
;*                Port B 6 bleibt Reset                    *
4
;*                usw.                                     *
5
;***********************************************************
6
INIT_IO:
7
   ....
8
RET
9
10
;------------- Einlesen der Eingänge-----------------
11
;*    Port D Bit 2 = Taster "+"                     *
12
;*           Bit 3  = Taster "-"                    *
13
;*                usw.                              *
14
;* Rückgabe in Variable New_In                      *
15
;*            Bit 0 = Taster "+"                    *
16
;*                usw.                              *
17
;****************************************************
18
Read_IO:
19
   ...
20
RET
21
22
usw.
Wenn du deine Routinen kurz fasst, kannst du sie auf eine DIN A 4 Seite 
drucken und hast schnell den Zugriff um einmal nachzusehen. Bedenke 
auch, das Kommentarzeilen deinen Code nicht größer machen und je mehr du 
kommentierst, um so leichter ist die Fehlersuche.
Gruß oldmax

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.