Hallo zusammen, ich habe mir in asm ein Programm geschrieben, das für ein 16x2 Display sämtliche Routinen enthält. Wie kann ich dieses Programm in mein eigentliches Hauptprogramm einfügen? Habe es so versucht: mein Hauptprogramm heißt messung.asm, dort habe ich an den Anfang .include "LCD_routins.asm" geschrieben, so heißt mein Programm für die LCD Routinen. Das Programm Messung habe ich im AVR Studio als entry file markiert. wenn ich das Ganze nun im Debugger laufen lasse beginnt das Programm mit dem abarbeiten des LCD_routins.asm und das obwohl es nicht als entry file gekennzeichnet ist. das wiederum bringt den Fehler dass der Stack überläuft, da dieser im messung.asm initialisiert wird und nicht im Messung.asm. Wenn ich nun beide Programme zusammen in ein Fenster schreibe läuft es im Debugger sowie auf meinem ATMEGA8 problemlos. Also, wie mache ich das wenn ich mehrere Programme zu einem großen zusammenbauen möchte ohne alles in ein Fenster zu schreiben? Gruß Moschder
Hi Die Include-Anweisung muss ans Ende vom Hauptprogramm. An den Anfang kann man nur Include-Dateien setzen, die KEINEN Programmcode enthalten. MfG Spess
besten Dank :), nun funktionierts. Du hast mir den Weg zu größerem Code geöffnet.
Hi Noch ein Hinweis: Include-Dateien sollten keine .org-Anweisungen haben. MfG Spess
Man kann die ASM anweisungen und die includes mischen. Ich hab zuerst die Interrupt tabelle, und dann kommen gleich die Includes. Und dann die Makros.
ok, ist bei mir nicht der Fall, habe überhaupt keine org Anweisungen drin, wie setzte ich die denn sinnvollerweise ein?
Hi .org-Anweisungen bewirken, das der nachfolgende Programmcode (in cseg) bzw. die Speicherstellen (dseg/eseg) an der Adresse beginnen, die in der Org-Anweisung steht. Noch mal zur Include-Anweisung: Beim Assemblieren wird der Code,der in der Include-Datei steht, an dieser Stelle eingefügt. Das geht an jeder Stelle (hat 6641 natürlich Recht), wo das nicht stört. Ich bevorzuge das Ende des Hauptprogramms. Erläuterungen findest du auch in der AVR-Studio-Hilfe: Assembler->Directives MfG Spess
wenn ich nun an der ersten möglichen Speicherstelle mit meinem Code beginnen will, wie muß dann dir org anweisung lauten? Und wann macht es sinn eben nicht an der ersten Stelle zu beginnen? Gruß Moschder
Wo man die Includes einfuegt haengt natuerlich sehr mit deren Inhalt zusammen. Der ASM ist ein Einpass Assembler. Daher kann man nichts baruchen was nicht voerher deklariert wurde. Wenn man nun library funktionalitaet zur Verfuegung stellen will, die spaeter gebraucht werden kann, dann fuegt man die oben ein, zB HexToByte, ByteToHex, Einen generischen Algorithmus, der vorher parametrisiert wird, kommt am Ende hin. Ich hab das main() jeweils unten.
Hi Der Assembler beginnt automatisch an der Speicherstelle 0. Dort muss der Sprung zum Anfang des Programms stehen. Der µC fängt nämlich nach jedem Reset an dieser Stelle an. Zu deiner Frage: '.org 0'. Schadet zwar nicht, ist aber unnötig. MfG Spess
Ein Bootloader beginnt zB nicht an der Stelle Null. Mit ORG kann man auch Variablen an eine Adresse setzen. Sei das nun im RAM oder im EEPROM.
Hi >Wo man die Includes einfuegt haengt natuerlich sehr mit deren Inhalt >zusammen. Der ASM ist ein Einpass Assembler. Daher kann man nichts >baruchen was nicht voerher deklariert wurde. Wenn man nun library... Über diese Brücke würde ich nicht gehen. Man kann problemlos auf Unterprogramme zugreifen, die hinter dem Aufruf stehen. Der AVR-Assembler (mit Sicherheit KEIN Ein-Pass-Assembler) benötigt keine Forward-Deklarationen. Und eine main() kennt er schon gar nicht. Ich glaube da bringst du etwas durcheinander. MfG Spess
Hallo, @6641: >Der ASM ist ein Einpass Assembler. Das bezweifle ich. Ansonsten: Der Assembler beginnt mit Programmspeicheradresse 0, wenn man ihm nicht mit .org was anderes sagt. Der AVR beginnt beim Reset an Adresse 0. Dort steht üblicherweise ein Sprung zum eigentliche Programmbeginn. Das ist sinnvoll, weil danach unmittelbar die IRQ-Vektoren kommen und wenn die nutzen will, muß man sie sozusagen freilassen. Eine (bei AVR) für mich allgemeingültige Methode:
1 | ; ATiny2313 |
2 | |
3 | ; 09.03.2008 M'Soft Berlin |
4 | |
5 | .include "tn2313def.inc" ; erstmal die Prozessordefinition includen |
6 | |
7 | .include "Definitionen.inc" ; jetzt meine Definitionen, Konstanten, Registernamen, Bitnamen usw. usw |
8 | |
9 | ;**** Verktor-Liste ******** |
10 | |
11 | .CSEG ; Begin Codesegment, Adresse ist 0 für den Assembler, weil nichts anderes angegebn |
12 | rjmp reset ; Sprung zum Programmbegin |
13 | |
14 | .org OVF1addr ; benutzter IRQ-Vector |
15 | rjmp irq_overflow |
16 | |
17 | .org OC0Aaddr |
18 | rjmp irq_timer |
19 | |
20 | ;***** Programm-Beginn ****** |
21 | |
22 | ;**************************** |
23 | ; Initialisierungsroutine |
24 | ;**************************** |
25 | |
26 | ; Hardware initialisieren |
27 | |
28 | .org INT_VECTORS_SIZE ; ist in allen AVR-Definitionen definiert und zeigt auf die erste Adresse hinter der IRQ-Vectorliste |
29 | |
30 | reset: |
31 | ldi TEMP_0,low(RAMEND) ; Stack an das interne Ram-Ende |
32 | out SPL,TEMP_0 |
33 | |
34 | ; Port B ********************* nur als Beispiel!!! |
35 | |
36 | ldi TEMP_0,(1<<KEY_MODE)|(1<<KEY_CAL) ; PullUp ein Tasten |
37 | out PORTB,TEMP_0 |
38 | ldi TEMP_0,(1<<LCD_RS)|(1<<LCD_E)|(1<<LCD_D4)|(1<<LCD_D5)|(1<<LCD_D6)|(1<<LCD_D7) |
39 | out DDRB,TEMP_0 ; LCD Ausgang |
40 | |
41 | usw. usw. |
42 | |
43 | ;************************ |
44 | ; Software initialisieren |
45 | |
46 | clr MENU |
47 | clr FLAGS |
48 | |
49 | usw. usw |
50 | |
51 | sei |
52 | |
53 | ;************************ |
54 | ; Main-Loop |
55 | ;************************ |
56 | main: |
57 | tst KEY_CODE ; Taste? |
58 | breq main_end ; nein |
59 | |
60 | usw. usw |
61 | |
62 | ;************************ |
63 | ; Main-End |
64 | ;************************ |
65 | |
66 | .include "IRQ.inc" |
67 | .include "LCD.inc" |
68 | .include "Subroutinen.inc" |
69 | .include "Funktionen.inc" |
70 | |
71 | .include "Tabellen.inc" |
Die leere Struktur benutze ich eigentlich für jedes Programm, die Reihenfolge der Includes ist egal, die Tabellen (Texte im Flash usw) lasse ich an Ende. Es kann nur passieren, daß beim Assemblieren die Meckermeldung kommt, daß die Sprungweite eines RCALL überschritten wurde, Erste Lösung ist dann für mich, die Reihenfolge der Includes umzusortieren, der Abstand hängt ja nur davon ab, welche Routine aus welchem Includen was aufruft. Oft reicht das schon oder umsortieren der Funktionen innerhalb der Includes hilft. Das sind dann alles nur reine Copy-Paste mit etwas überlegung, das kostet nichtmal Zeit. Vielleicht hilft das ja jemandem. Gruß aus Berlin Michael
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.