In der Initialisierungsphase wird vor dem Programmteil des Fehlers der Interrupt freigegeben, weil in diesem Programmteil Wartezeiten auftreten, die zwar jetzt noch Softwarewartezeiten sind, aber später auf Hardwarewartezeiten umgestellt werden sollen. Die verfrühte Freigabe dürfte aber keine Fehler verursachen. Als Ergebnis wird 00Inf ausgegeben. Interrupts und andere Ausgaben erfolgen nicht, obwohl dies so sein müßte. Nun erstmal die wichtigen Code-Brocken: w002us: cli ; 7 Zyklen: ; +9 takte =16 Takte ldi R17, $02 ; warte 6 Zyklen WLOOP0: dec R17 brne WLOOP0 nop ; warte 1 Zyklus sei ret Ist das so richtig, daß ich in den Wartezeiten den Interrupt sperre und diese im Unterprogramm liegen? DSinfo: rcall rssend ret Hier passiert noch nichts, ist nur eine Umlenkung auf evtl. andere Ausgabegeräte. Bei RSSEND wird in den Pufferspeicher RS232 geschrieben, das ist einwandfrei. sea910: ldi r19,0 ;Busnummer=0 setzen sensor: ldi zl,low (senstb) ldi zh,high(senstb) ;Zeiger auf Sensortabelle ldi r18,maxsen ;16 Werte durchsuchen ldi r17,'0' ;Sensorzähler=0 setzen (ASCII) sen100: ld r16,z+ ;Wert aus Tabelle lesen cp r16,r19 ;Sensor am aktuellen Bus? brne sen200 ;nein -> weiter inc r17 ;sonst Sensorzähler erhöhen sen200: dec r18 ;alle Tabellenplätze gelesen? brne sen100 ;nein -> Schleife cpi r17,'9'+1 ;mehr als 9 Sensoren am Bus? brcs sen210 ;nein -> weiter ldi r16,7 ;sonst Zahl in Buchstaben add r17,r16 ;wandeln: 10..16 -> A..G sen210: mov temp,r17 rcall DSinfo ;Sensoranzahl speichern inc r19 ;nächsten Bus testen cpi r19,maxbus ;alle Busse getestet? brne sensor ;nein -> Schleife ; Informationen ausgeben ldi temp,'I' rcall DSinfo ldi temp,'n' rcall DSinfo ldi temp,'f' rcall DSinfo ldi temp,'o' rcall DSinfo ldi zl,low (senstb) ; Sensortabelle ausgeben ldi zh,high(senstb) ldi r17,0 W21: ld temp,z+ rcall DSinfo inc r17 cpi r17,maxsen brne W21 ldi temp,cr rcall DSinfo ldi zl,low (sensid) ; ROM-ID von allen Sensoren ausgeben ldi zh,high(sensid) ldi r18,0 W23: ldi r17,0 W22: ld temp,z+ rcall DSinfo inc r17 cpi r17,8 brne W22 call craus inc r18 cpi r18,maxsen brne W23 ; --- Initialisierung Ende ----------------------- Ich habe mich hier etwas festgebissen, weil der Ablauf bis zur Informationsausgabe vermutlich richtig ist, da die 00 dort richtigerweise ausgegeben wird, auch das Inf wird noch richtig ausgegeben, aber das o und die nachfolgenden Ausgaben erfolgen nicht mehr. Auch eine Endlosschleife kann ich hier nicht erkennen. Da im Mainprogramm Daten ohne Interrupt ausgegeben werden, liegt die Vermutung nahe, daß das Programm hier nicht drüber wegkommt. Doppelt vergebene Register können gerade an dieser Stelle nicht auftreten, weil das Ergebnis vorher beendet wurde und danach nur noch diese tlw. RAM Ausgaben zur Information erfolgen. Ist ja nur geradlinig angehängt. Da waren mir eben die Timer eingefallen, darum nachfolgende Infos: ; Interrupt-Vektoren für ATmega 32 ; .org 0 rjmp start ;Programm-Start .org INT0addr reti ;External Interrupt Request 0 .org INT1addr reti ;External Interrupt Request 1 .org INT2addr reti ;External Interrupt Request 2 nicht in ATMega 8 .org OC2addr rjmp oc2int ;Timer/Counter2 Compare Match 8ms, Funkuhr .org OVF2addr reti ;Timer/Counter2 Overflow .org ICP1addr reti ;Timer/Counter1 Capture Event .org OC1Aaddr reti ;ocr1a ;Timer/Counter1 Compare Match A, frei .org OC1Baddr reti ;ocr1b ;Timer/Counter1 Compare Match B, Warte .org OVF1addr reti ;Timer/Counter1 Overflow .org OC0addr rjmp oc0int ;Timer/Counter0 Compare Match, ZMD nicht in ATMega 8 .org OVF0addr reti ;Timer/Counter0 Overflow .org SPIaddr reti ;SPI, STC Serial Transfer Complete .org URXCaddr rjmp UART_Rx_C ;RXC USART, Rx Complete .org UDREaddr rjmp UART_Empty ;UDRE USART Data Register Empty .org UTXCaddr reti ;TXC USART, Tx Complete .org ADCCaddr reti ;ADC Conversion Complete .org ERDYaddr reti ;EEPROM Ready .org ACIaddr reti ;Analog Comparator .org TWIaddr reti ;Two-wire Serial Interface .org SPMRaddr reti ;Store Program Memory Ready ; Timer0 48 khz, CTC, Vorteiler wird wegen ausreich. Genauigkeit nicht resettet. für ZMD Sensor ldi temp, (1<< ctc0)|(1<<cs01) ; CTC-Modus, Vorteiler = 8 out TCCR0,temp ; Timer2, ctc, Vorteiler/256, oc=250, 8 Mhz ---- 125 OV = 1 sek. 150=1,2 sek. DCF-Uhr ldi temp, (1<< ctc2)|(1<<cs21)|(1<<cs22); CTC-Modus, Vorteiler = 256, resetbar out TCCR2,temp ldi temp, ( 250 - 1 ) ; Compare Wert setzen auf 8ms (clock/Vorteiler *32µs) out OCR2, temp ldi temp, (1<<OCIE1B)|(1<<OCIE2); Compare Interrupt für Timer 1B,2 aktivieren out TIMSK,temp Timer1 hat noch keinen Interrupt, kann also nicht stören. Timer2 hat einen Compare wert von 8ms, dürfte daher auch nicht in Betracht kommen. Timer0 hat noch keinen comparewert, wird erst in der Anwendung gesetzt. Wie der Timer0 abläuft, würde mich jetzt interessieren, vielleicht liegt da die Störung. Bleibt ja fast nichts mehr übrig. Der Vorteiler wird nicht resettet. mfg
der Stack ist in Ordnung. Sind auch noch 29 KB dafür frei. Ohne das kontrolliert zu haben, sollte das auch reichen. mfg
der Stack ist in Ordnung. Sind auch noch 1300 Bytes dafür frei. Ohne das kontrolliert zu haben, sollte das auch reichen. mfg hab mich eben vertan. War ein Irrtum
Wolfram Quehl wrote: > der Stack ist in Ordnung. Sind auch noch 29 KB dafür frei. Öhhh, wo nimmst Du beim Mega32 29 KB RAM her? EDIT: > hab mich eben vertan. War ein Irrtum Aha...
BTW: Wär schön, wenn Du den Code beim nächsten Mal formatiert schicken könntest (mit "[avrasm]"...). Die Zeilenumbrüche bei den Kommentaren sind etwas lästig. Das nur am Rande...
in meinem Notepad ist das alles schön formatiert. Hab das nur kopiert. Beim Kopieren nach Wordpad gibt es ähnliche Probleme, aber nur mit den Tabs. Wie könnte ich das überhaupt erreichen, daß der Kommentat hier nicht in die nächste Zeile kommt. Wenn ich mir das so ansehe, kann ich nur den Kommentar verkürzen. Soll ich also Kommentare verkürzen? mfg
Hab ich doch oben geschrieben wie's geht: <eckigeKlammerauf>avrasm<eckigeKlammerzu> Dein Code <eckigeKlammerauf>/avrasm<eckigeKlammerzu> Steht unten bei "Formatierung"!
muß ich gleich mal probieren.
1 | ; Timer0 48 khz, CTC, Vorteiler wird wegen ausreich. Genauigkeit |
2 | nicht resettet. für ZMD Sensor |
3 | ldi temp, (1<< ctc0)|(1<<cs01) ; CTC-Modus, Vorteiler = 8 |
4 | out TCCR0,temp |
5 | ; Timer2, ctc, Vorteiler/256, oc=250, 8 Mhz ---- 125 OV = 1 sek. |
6 | 150=1,2 sek. DCF-Uhr |
7 | ldi temp, (1<< ctc2)|(1<<cs21)|(1<<cs22); CTC-Modus, Vorteiler = 256, |
8 | resetbar |
9 | out TCCR2,temp |
10 | ldi temp, ( 250 - 1 ) ; Compare Wert setzen auf 8ms (clock/Vorteiler |
11 | *32µs) |
12 | out OCR2, temp |
13 | ldi temp, (1<<OCIE1B)|(1<<OCIE2); Compare Interrupt für Timer 1B,2 |
14 | aktivieren |
15 | out TIMSK,temp |
mal sehen, ob das klappt.
> mal sehen, ob das klappt.
Dafür gibts die Vorschau-Option...
OK, die Zeilenumbrüche müsstest Du dann von Hand entfernen...
1 | ; Timer0 48 khz, CTC, Vorteiler wird wegen ausreich. Genauigkeit nicht resettet. für ZMD Sensor |
2 | ldi temp, (1<< ctc0)|(1<<cs01) ; CTC-Modus, Vorteiler = 8 |
3 | out TCCR0,temp |
4 | ; Timer2, ctc, Vorteiler/256, oc=250, 8 Mhz ---- 125 OV = 1 sek. 150=1,2 sek. DCF-Uhr |
5 | ldi temp, (1<< ctc2)|(1<<cs21)|(1<<cs22); CTC-Modus, Vorteiler = 256, resetbar |
6 | out TCCR2,temp |
7 | ldi temp, ( 250 - 1 ) ; Compare Wert setzen auf 8ms (clock/Vorteiler *32µs) |
8 | out OCR2, temp |
9 | ldi temp, (1<<OCIE1B)|(1<<OCIE2); Compare Interrupt für Timer 1B,2 aktivieren |
10 | out TIMSK,temp |
war nicht so einfach, weil man das Löschen der Zeilenumbrüche nicht sieht, erst in der Vorschau. Hab jetzt auch gesehen, daß ich den Compare von Timer 0 nicht freigegeben habe. Daher kann der Fehler dann da auch nicht liegen. mfg das Editieren hat nicht funktioniert
Also was mir aufgefallen ist, das du deine Flags nicht sicherst. Ich nehme dafür immer eines der unteren Register (R2 oder R3). Mit den ganzen Rechen- und Vergleichsbefehlen zerschießt man sich ruckzuck die Flags. Und dadurch zählt ein Zähler dann mal schnell falsch. (mit Zähler meine ich keinen Hardwarecounter, sondern eine Softwareschleife be der ein Register oder ein Registerpaar hochgezählt wird) Weiterhin wenn so ein Interrupt zwischen einem Vergleich (cpi, cpc, dec) und dem Sprungbefehl landet dann geht das üblicherweise auch in die Hose.
1 | w002us: |
2 | in R2,SREG |
3 | cli |
4 | ; 7 Zyklen: ; +9 takte =16 Takte |
5 | ldi R17, 0x02 ; warte 6 Zyklen |
6 | WLOOP0: dec R17 |
7 | brne WLOOP0 |
8 | nop ; warte 1 Zyklus |
9 | out SREG,R2 |
10 | ret |
bis dann Hauke
Hauke Sattler wrote: > Also was mir aufgefallen ist, das du deine Flags nicht sicherst. > Ich nehme dafür immer eines der unteren Register (R2 oder R3). > Mit den ganzen Rechen- und Vergleichsbefehlen zerschießt man sich > ruckzuck die Flags. Und dadurch zählt ein Zähler dann mal schnell > falsch. Solange es kein Interrupt-Handler ist, ist es wurscht. Nur in Interrupt-Handlern muss man das SREG sichern (und das eigentlich auch nur dann, wenn im Interrupt Handler Flags verändert werden), weil man bei einem Interrupt keine Kontrolle darüber hat, wann er auftritt. Wer allerdings zwischen eine flagrelevante Operation und die nachfolgende Auswertung einen (r)call setzt, ist selbst Schuld...
danke, hat ich zwar schon mal daran gedacht, auch die Register zu sichern, hab das wieder aus den Augen verloren, weil ja bei einer Wartezeit nach Rückkehr keine Flags abgefragt werden. Und genaugenommen ist das nur bei Interrupts notwendig. Hier aber sicherlich zweckmäßig, weil man sonst alle Wartezeiten daraufhin kontrollieren müßte. Erklärt aber noch nicht, warum das gerade an dieser Stelle nicht mehr funktioniert. Dann müßte der vorhergehende Ablauf schon durcheinandergeraten sein und rein zufällig die richtigen Ergebnisse rauskommen. Das mag ja noch sein, aber nach dem Inf werden keine Wartezeiten aufgerufen. Erst wieder in der Mainloop. mfg
Ich hab mal weitergeschaut. Dein Zählen in ASCII-Zahlen ist "sagen wir mal" gewöhnungsbedürftig. Weiterhin ist deine Schleifengeometrie etwas verwirrend. Aber jeder hat seinen eigenen Stil. Was ich vermute ist, das der AVR bei der Ausgabe der Werte aus dem Z-Pointer abschmiert. (Also erst nach dem 'o') Das 'o' ist schon im Zwischenbuffer des USART aber worde noch nicht ausgegeben. Evt. fischt dir dein Pointer ein "nicht-ASCII-Zeichen" raus. Probier mal folgenden Code
1 | Informationen ausgeben |
2 | ldi temp,'I' |
3 | rcall DSinfo |
4 | ldi temp,'n' |
5 | rcall DSinfo |
6 | ldi temp,'f' |
7 | rcall DSinfo |
8 | ldi temp,'o' |
9 | rcall DSinfo |
10 | ldi zl,low(senstb) ; Sensortabelle ausgeben |
11 | ldi zh,high(senstb) |
12 | ldi r17,0 |
13 | W21: |
14 | ld temp,z |
15 | swap temp |
16 | andi temp,0b00001111 |
17 | subi temp,-6 |
18 | sbrc temp,3 |
19 | subi temp,'6'-'A' |
20 | subi temp,6-'0' |
21 | rcall DSinfo |
22 | |
23 | ld temp,z+ |
24 | andi temp,0b00001111 |
25 | subi temp,-6 |
26 | sbrc temp,3 |
27 | subi temp,'6'-'A' |
28 | subi temp,6-'0' |
29 | rcall DSinfo |
30 | |
31 | nirvana: |
32 | nop |
33 | rjmp nirvana |
Dadurch wird das Zeichen aus dem Pointer als Hexzahl ausgegeben. Danach landet das dingen in einer Endlosschleife. Mal schauen was dabei rauskommt. cu Hauke P.S. Die Hexzahlausgabe mag umständlich sein, aber ich vermeide gerne Sprünge. Weiterhin baue ich mir immer irgendwelche Marker ein, um zu schauen wie weit er denn wirklich gekommen ist.
danke, die Ausgabe wird sicherlich irgendeine Hexzahl zwischen 0x00 und 0xFF sein. Wahrscheinlich 0x00 oder 0xFF. Aber das kann nicht das Problem sein. An anderer Stelle habe ich die A/D Wandlung mit 03FF ausgegeben. Da gab es keine Probleme. Das Programm vor der Informationsausgabe habe ich nicht selber programmiert, darum wollte ich ja auch mal sehen, was da rauskommt bei diesem Programmteil. Die Ausgabe von 00 habe ich noch dazwischen gebracht. das mit dem o im Puffer klingt logisch. Das er das aber nicht mehr sendet, kann eigentlich nur mit einem abgeschalteten Interrupt zu tun haben. Oder mit einer Endlosschleife. Da müßte ich mal sehen, wie die Pufferzeiger stehen. Jetzt könnte ich wohl echt ein Simulationsprogramm gebrauchen. Ob mir das jemand simulieren kann, das Gesamtprogramm würde ich dann per Email zusenden. Quehl ett gmx punkt de
Für Simulationen nehm ich VMLAB. Leider wird das nicht mehr weitergepflegt. Ist ideal um bis zu zwei AVR mitsamt Peripherie zu simulieren. Das Dickste was ich bisher durchsimuliert habe, war eine Kombination aus einem Mega8, einem Mega32 und diversen TWI Busbausteinen. War ein Logger(Mega8), welcher über einen Terminalserver(Mega32) konfiguriert und ausgelesen wurde. Das Mega32 Programm war hinterher über 19kB groß und bestand aus fast 11.000 Zeilen Assemblercode. Wenn du mir den Code schickst dann kann ich den ja mal durchlaufen lassen. cu Hauke P.S. die elektrische Postadresse ist hsattler(at)uni-potsdam.de
ich hab im Augenblick erst mal einen Verdacht. Nachdem das o in den Pufferspeicher gekommen ist, wird dieses erst ca. 270µs später abgesandt. (Baud 38400). In der Zeit sind die nachfolgenden Ausgaben auch in den Pufferspeicher gelangt und das Programm läuft in der Mainloop weiter, wo der mögliche Fehler in der Warteschleife auftritt, aber wahrscheinlich Register in den verschiedenen Aufgaben doppelt belegt sind und daher einen Absturz verursachen. Dazu hätte ich die Frage, wie ich die Register der einzelnen Aufgaben sichern kann. Innerhalb der Aufgabe ist das kein Problem. Diese können von der nächsten Aufgabe wieder benutzt werden. Aber wenn die Register über die Mainloop erhalten bleiben müssen, dann weiß ich nicht, wie ich das machen soll. Mit Push und Pop in jeder Aufgabe wird das wohl nicht funktionieren. Muß man diese Register dann vielleicht im RAM speichern? Wäre ja bei einer Abfrage der Flags ziemlich umständlich. Danke, mfg
Sicher funktioniert das mit push und pop. Man muß sich bloß vorher ansehen welche Register von der Sub-Routine verändert werden. Mit in Ram Speichern kannst du vergessen. Das dauert im Prinzip genauso lang wie push und pop. cu bis dann Hauke
Nunja, globale und statische Variablen sollte man schon im RAM halten. ...
.... Es sollten beim Einsprung in Interruptservicroutinen alle in dieser Routine benutzten Register durch push gesichert werden und vor dem Rücksprung mit pop restauriert werden. Globale Variablen gehören ins sRAM. Bei lokalen Variablen welche nur in Registern aufbewahrt werden ist es wichtig diese auf dem Stack zu sichern, wenn z.B. innerhalb einer Routine eine weitere Routine aufgerufen wird, welche die selben Register benutzt. Nach der Rückkehr aus dem Unterprogramm sind diese zu lokalen Variablen zu restaurieren. noch ein paar Tips Ein Speicherplan erleichtert den Überblick über globale Variablen ebenso hilft es beim pushen und poppen den Stackpointer im Auge zu behalten. D.h er muss beim Verlassen einer Routine den gleichen Stand aufweisen wie beim Eintritt in dieselbe, und es wird in umgekehrter Reihenfolge gepoppt, in welcher gepusht wurde. Ausnahmen bilden Parameterübergaben via Stack. Hier ist die übernehmende Routine für die Bereinigung des Stacks verantwortlich. In solchen Fällen empfiehlt sich die Anzahl der übergeben Bytes als ersten Parameter zu übergeben. In jedem Fall sollte man sich ein eineheitliches Protokoll für Variablenübergaben und Registernutzung zu eigen machen. Dies erleichtert die Übersicht über den Programmablauf bei strukturierten ASM-Programmen erheblich und wirkt der Verspaghettierung entgegen, welche bei ASM bedeutend grafierendere Knoten und Nestys (bis zu Abstürzen)bedingt als z.B. in einem unstrukturierten Basicprogramm.
danke, die Behandlung bei Interrupts war sowieso klar. Bei Unterprogrammen hatte ich das zunächst nicht gepusht, hab dann aber gemerkt, daß es die Programmierung vereinfacht. Mach ich also auch. Muß noch nachsehen, ob ich das konsequent gemacht habe. Da rutscht dann schon leicht mal was durch. Worum es hier ging, waren die verschieden Aufgaben, verschiedene Sensorenbearbeitung in einem Chip, die hier im Forum jeweils als getrenntes Programm in unterschiedl. Chips behandelt werden. Diese Aufgaben sind unabhängig und habe ich auch unabhängig programmiert. Auch wenn jede Aufgabe für sich unabhängig funktioniert, so ist das in einem Chip nicht unbedingt der Fall. Die Aufgaben laufen nacheinander in einer Loop ab. Dabei müssen Variablen tlw. bis zum nächsten Durchgang aufbewahrt werden. Z.B. Flags, wo abgefragt wird, ob ein Interrupt fertig ist. Ich habe schon öfter überlegt, vor und nach jeder Aufgabe die benutzten Register zu pushen und poppen. Dies wird aber nur bei 2 Aufgaben funktionieren, wobei eine ungepusht bleibt. Bei mehr Aufgaben wird das wohl nicht mehr gehen. Ich dachte, ich hätte über die Register Überblick, aber der Überblick bezieht sich nur jeweils auf eine Aufgabe. Jetzt werde ich erst mal eine Register Übersicht machen und die globalen Register von den lokalen Registern unterscheiden. Ist "globale" Register überhaupt das richtige Wort? Global heißt doch, daß verschiedene Aufgaben die gleichen Variablen verwenden. Das ist hier aber nicht der Fall. Die Variablen werden von der gleichen Aufgabe verwendet, müssen aber bis zur nächsten Runde gerettet werden. mfg
Wolfram Quehl wrote: > Ist "globale" Register überhaupt das richtige > Wort? Global heißt doch, daß verschiedene Aufgaben die gleichen > Variablen verwenden. Ich verstehe unter "globale Variable" Variablen, deren Inhalt einem bestimmten Zweck zugeordnet sind und auf die von verschiedenen Routinen aus zugegriffen werden kann. > Das ist hier aber nicht der Fall. Die Variablen > werden von der gleichen Aufgabe verwendet, müssen aber bis zur nächsten > Runde gerettet werden. Dann sind es (für mich) lokale "statische Variable", sie dienen einem speziellen Zweck, werden aber nur von einer Routine verwendet. Im Gegenzug dazu gibt es lokale temporäre Variable, deren Wert bis zur "nächsten Runde" verloren geht. Diese werden nur in Registern gehalten. Bei Registermangel (der bei Deinem sehr großen Projekt ja besteht) hält man nur die Variablen in Registern, auf die sehr häufig und zeitkritisch zugegriffen wird, alles Andere hält man im RAM. Da man im RAM nicht rechnen und operieren kann, müssen die Werte bei Bearbeitung in Register kopiert werden. Globale Variable im RAM: Register (falls nötig) freimachen (push), Wert in Register laden, verarbeiten, geänderten Wert ins RAM zurück, Register wiederherstellen (pop). Statische lokale Variable im RAM: Register freimachen, Wert in Register laden, verarbeiten, bei Änderung ins RAM zurück, Register wiederherstellen. Lokale Variablen (temporär): Register freimachen (push), verarbeiten, Register wiederherstellen (pop). > > mfg ...
ich hab jetzt folgendes System rausgefunden: Interrupts: verwendete Register vorrangig nach R2 und R3, sonst Push und pop. Unterroutinen, die eine Funktion enthalten, push und pop, weil diese von verschiedenen Stellen aufgerufen werden können. Unterroutinen, die nur zur Programmverkürzung erstellt wurden, benötigen keine Sicherung, da diese in einer Programmfunktion zusammengefaßt sind. Aufgaben, deren Register am Ende nicht mehr benötigt werden, bekommen ein Push-Pop. Register, die am Ende nicht mehr benötigt werden und in allen Aufgaben diese Funktion erfüllen, benötigen kein Push-Pop. Aufgaben, deren Register am Ende weiter benötigt werden, kommen ins RAM. das sind 6 verschiedene Möglichkeiten und nicht nur global und lokal. Jetzt noch eine Frage zur Sourcenreihenfolge: Bisher habe ich die folgende Reihenfolge verwendet: Definitionen (.def und .equ) Datensegment Programmsegment Interrupts Flashprogrammierungszähler Initialisierung Mainloop Aufgabe1 Aufgabe2 u.s.w. Interruptprogramme Funktionale Unterprogramme Ich neige jetzt dazu, folgende Änderungen vorzunehmen. Mainloop Aufgabe1 Definitionen Hauptprogramm zugehörige Unterprogramme Interruptprogramm zu Aufgabe1 Aufgabe2 Definitionen Hauptprogramm zugehörige Unterprogramme Interruptprogramm zu Aufgabe u.s.w. Funktionale Unterprogramme, die von mehreren Aufgaben verwendet werden kleiner Nachteil wäre hier, daß von einer Aufgabe zur nächsten mit RJMP gesprungen werden muß, was jetzt nicht der Fall ist. Der Vorteil wäre, daß fast alles, was zu einer Aufgabe gehört, zusammensteht. Man hat eine bessere Übersicht, was eine Aufgabe betrifft. Ob man auch die Initialisierung in die Aufgabe selbst bringen kann, weiß ich noch nicht. Zumindest Register und Ports wären denkbar. Möglicherweise auch die Peripherie. Es wäre dann eine zusätzliche Programmierung erforderlich. Wie sind jetzt Eure Meinungen dazu? mfg
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.