Hallo, ich mache eine Projektarbeit mit dem AT89C51AC3 ATMEL Mikrokontroller. Dafür muss ich ein neues Projekt aus alten Dateien erstellen. Darunter sind Startup.A51, Init.A51 und viele H-/C-Dateien. Diese Dateien wurden unter Windows 3.11 mit dem C51 Compiler („und A51 Assembler“) kompiliert. Meine aktuelle Entwicklungsumgebung besteht aus „Code::Blocks“ und „SDCC“ Compiler. Problembeschreibung: 1. Im Keil C51 Assemblercode wird eine C-Funktion aus anderem Modul Aufgerufen. Vor dem Aufruf wird mit der „EXTRN“ Anweisung die Funktion bekanntgegeben. --> Gesucht: Wie kann man die „EXTRN“ Anweisung im SDCC ersetzen oder umgehen??? 2. Eine vollständige Assembler Datei (also nicht _asm ……….. _endasm; gemeint) in einer Kombination mit C- und H-Dateien kompilieren und linken mit SDCC und Code::Blocks. --> Gesucht: INIT.A51 (oder INIT.ASM) und STARTUP.A51 (oder STARTUP.ASM) Falls etwas unklar ist, oder Fragen einfach melden. *** *** ********* ***** * Nähere Informationen zu der Fragestellung: Bei kompilieren kommt es zu folgenden Fehlern (SDCC Compiler): ************************************************************************ 1. Fehler: in der Datei ZEIT_ASS.C ?ASxxxx-Error-<o> in line 608 of obj\Release\ZEIT_ASS.asm removing obj\Release\ZEIT_ASS.rel <o> .org in REL area or directive / mnemonic error In der Zeile 608 (ZEIT_ASS.asm) steht folgendes: EXTRN CODE (ZEITGEBER_DEK) Der SDCC Compiler kennt nicht den EXTRN Befehl. Gibt es eine Möglichkeit diesen durch einen anderen Befehl zu ersetzen? Die Funktion zeitgeber_dek() ist in der ZEITGEB.C deklariert, die Datei ZEITGEB.H ist in der Datei ZEIT_ASS.C eingebunden und besteht aus C Funktionen. Diese Datei besteht aus includes und zwei Funktionen: Alte Version (C51 Compiler) timer0 { #pragma ASM ... // Assemblercode ... #pragma ENDASM } Neue Version (SDCC Compiler) timer0 { _asm // Assemblercode … _endasm; } Alte Version (C51 Compiler) timer0 () interrupt{ #pragma ASM EXTRN CODE (ZEITGEBER_DEK) // Assemblercode … PUSH B … LCALL ZEITGEBER_DEK … POP B … #pragma ENDASM } Neue Version (SDCC Compiler) timer0 () interrupt{ _asm EXTRN CODE (ZEITGEBER_DEK) // Assemblercode … PUSH B … LCALL ZEITGEBER_DEK … POP B … _endasm; } Zusätzlich ein Ausschnitt aus dem altem make-file: // MACRO-Deklaration LAT37 = d:\LAT37\PROG C51OPTA = SRC SYMBOLS DEBUG OE OT(0,SIZE) RB(0) LARGE A51OPT = ERRORPRINT NOPRINT DEBUG SYMBOLS C51 = C51E ... $(LAT37)\zeit_ass.obj : $(LAT37)\zeit_ass.c $(C51) zeit_ass.c $(C51OPTA) >zeit_ass.err a51 zeit_ass.src $(A51OPT) ... Habe ich das richtig verstanden? Aus der ZEIT_ASS.C mit a51 wird eine Assembler-Source Datei (zeit_ass.src) erstellt, dann wieder dieselbe Datei mit dem C51 Compiler kompiliert und zusammen mit der zeit_ass.src eine Objektdatei ZEIT_ASS.obj erstellt. => 1. Frage: Wie kann ich das selbe mit Code::Blocks und SDCC realisieren? < = Mein Realisierungsversuch (Eigenschaften der zeit_ass.c Datei in Code::Blocks IDE) Siehe Bild ZEIT.ASS Einstellung ******************************************************************** Zu 2. Fehler: in der Datei INIT.ASM Diese Datei besteht aus folgenden Assembler Befehlen: NAME ?C_INIT EXTRN CODE (MAIN) PUBLIC ?C_START ?C_C51STARTUP SEGMENT CODE ;?C_INITSEG SEGMENT CODE ; Segment with Initializing Data ; RSEG ?C_INITSEG ; DB 0 ; Segment ist definiert, aber leer RSEG ?C_C51STARTUP ?C_START: LJMP MAIN END Sobald diese einzelne Datei kompiliert wird, kommt folgende Warnung und Kompiliervorgang bricht ab. (das gleiche passiert bei INIT.ASM) at 1: warning 119: don't know what to do with file 'INIT.A51'. file extension unsupported SDCC : mcs51/gbz80/z80/avr/ds390/pic16/pic14/TININative/xa51/ds400/hc08 2.9.0 #5416 (Mar 22 2009) (MINGW32) Usage : sdcc [options] filename Options :- Mein Realisierungsversuch (Eigenschaften der zeit_ass.c Datei in Code::Blocks IDE) Siehe Bild INIT.ASS Einstellung Ausschnitt haus altem make-file: // MACRO-Deklaration LAT37 = d:\LAT37\PROG A51OPT = ERRORPRINT NOPRINT DEBUG SYMBOLS … $(LAT37)\init.obj : $(LAT37)\init.a51 a51 init.a51 $(A51OPT) … = > 2. Frage: Wie kann ich das selbe mit Code::Blocks und SDCC realisieren? < = Vielen Dank im Voraus Denis
Du solltest dir einmal die SDCC Doku. durchlesen. Ich geh mal davon aus das die Startup.A51 von deinem Compiler erzeugt wurde... SDCC erzeugt ebenso einen Startupcode. Wenn du hier eigenen Code verwenden willst dann gilt: uint8_t _sdcc_external_startup () { // hier deinen Code einfügen. return 0; } Ansonsten gilt für deine Projekt Dateien... angenommen du hast 4 Dateien,
1 | sdcc -c --code-loc 0x0000 --model-small --opt-code-size --vc --verbose display.c |
2 | sdcc -c --code-loc 0x0000 --model-small --opt-code-size --vc --verbose adc.c |
3 | sdcc -c --code-loc 0x0000 --model-small --opt-code-size --vc --verbose eeprom.c |
4 | sdcc -c --code-loc 0x0000 --model-small --opt-code-size --vc --verbose RS232.c |
5 | sdcc -c --code-loc 0x0000 --model-small --opt-code-size --vc --verbose main.c |
6 | |
7 | sdcc --code-loc 0x0000 --model-small --opt-code-size --verbose --vc main.rel adc.rel display.rel eeprom.rel RS232.rel |
also wie gehabt. Compiler aufrufen, Linker aufrufen. Ich müßte dein Projekt vor der Nase haben und dann kann man es sicher für den SDCC umbauen. So mal eben kann ich das auch nicht.
Keil und SDCC sind nicht kompatibel, da braucht man angepasste prozessorspezifische include Dateien also C Quellen anpassen. Die Assembler sind komplett verschieden, d.h. an alle Assemblerteile muss man Hand anlegen siehe die Memonic errors. Vorsicht die Byteorder der Compiler ist verschieden SDCC low und Keil high Endrian. Ebenso ist die Übergabe von Variable an Funktionen anders, andere und weniger Register. Init und startup erzeugt SDCC in main selbst, da braucht man keine extra Dateien hinzu binden. Wird wohl einfacher sein die Keil Dateien zu vergessen und das Project in SDCC selbst aufzubauen sonst schleppt man permanent Rucksäcke durch die Gegend.
>> Wird wohl einfacher sein die Keil Dateien zu vergessen und das Project >> in SDCC selbst aufzubauen sonst schleppt man permanent Rucksäcke durch >> die Gegend. So ist es.
Zu schnell abgesendet :-) Ich habe das Gefühl hier sollen die Assembler Dateien vom Keil mit dem Linker des SDCC verwurstet werden... das geht nicht!!!
Bei so alten Projekten sollte man auch bei dem alten Compiler bleiben. Ansonsten ist viel Handarbeit erforderlich. Der Assembler a51.exe zu win 3.11 Zeiten lief noch ohne Dongle. Die alten C51 Keil-Versionen vom Anfang der 90er können heute vom Ergebnis her noch locker mit SDCC mithalten.
Hallo, vielen Dank für Ihre schnelle Antworten. Wolfgang R. schrieb: > Init und startup erzeugt SDCC in main selbst, da braucht man keine extra > Dateien hinzu binden. muss ich die INIT.A51 und die STARTUP.A51 ganz rauslassen? oder muss ich für SDCC eine neue Datei erstellen? falls ja, darf diese neue Datei im C geschrieben werden oder nur in Assembler? Wie soll es ungefähr aussehen? Für Keil C51 Compiler gibt es Homepage mit allen Befehlen und Fehlermeldungen, gibt es sowass für den SDCC Compiler auch? Gibt es einen HW Debugger für AT89C51AC3 der mit anderem Compiler außer Keil C51 sicher läuft und guten Support anbietet(Dokus, Forum). Können Sie einen außer Keil empfehlen. Vielleicht gibt es ein low cost Compiler bei dem man den Keil C51 code nicht anpassen muss? Matthias schrieb: > Bei so alten Projekten sollte man auch bei dem alten Compiler bleiben. Ja würde ich gerne, aber den alten Compiler (C51 v4.01) kriege ich nicht zum Laufen. Vielleicht liegt es an dem Windows? Wo kriegt man raus ob es mit dem 7 oder XP kompatibel ist? Gruß Denis ********************************************************************** STARTUP.A51 ********************************************************************** ;Timer2 - Spezialregister T2 BIT 090H.0 T2IE BIT 0C8H.5 T2IP BIT 0C8H.6 RCAP2H DATA 0CBH T2EX BIT 090H.1 RCAP2L DATA 0CAH C_T2 BIT 0C8H.1 CP_RL2 BIT 0C8H.0 ET2 BIT 0A8H.5 TF2 BIT 0C8H.7 TH2 DATA 0CDH TL2 DATA 0CCH PT2 BIT 0B8H.5 TR2 BIT 0C8H.2 T2CON DATA 0C8H T2RSE BIT 0C8H.4 ; Modulname NAME ?C_STARTUP ; Segmentdefinitionen ?C_C51STARTUP SEGMENT CODE ?STACK SEGMENT IDATA RSEG ?STACK DS 1 EXTRN CODE (?C_START) PUBLIC ?C_STARTUP CSEG AT 0 SERIE_47: ?C_STARTUP: LJMP STARTUP1 RSEG ?C_C51STARTUP STARTUP1: ; Programmteil ; Initialisierung des Stapelzeigers MOV SP,#?STACK-1 ; Initialisierung der Ausgaenge MOV P1,#0FFH MOV P3,#0FFH ; XDATA-Speichertest ; externer Speicher mit AA fuellen MOV A,#0AAH MOV B,A MOV R0,#00H MOV R1,#08H ; 2KByte = #0800H XDATA_SEITE_AA: ;CALL DN_WATCHDOG DEC R1 MOV P2,R1 ; Seitenadresse XDATA_AA: MOVX @R0,A DJNZ R0,XDATA_AA CJNE R1,#00H,XDATA_SEITE_AA ; AA ueberpruefen MOV R0,#00H MOV R1,#08H ; 2KByte = #0800H XDATA_SEITE_AA_C: ;CALL DN_WATCHDOG DEC R1 MOV P2,R1 ; Seitenadresse XDATA_AA_C: MOVX A,@R0 XRL A,B JNZ XDATA_AA_FAIL DJNZ R0,XDATA_AA_C CJNE R1,#00H,XDATA_SEITE_AA_C JMP XDATA_AA_C_E XDATA_AA_FAIL: MOV A,#11H JMP CHECK_FAIL XDATA_AA_C_E: ; externer Speicher mit 55 fuellen MOV A,#055H MOV B,A MOV R0,#00H MOV R1,#08H ; 2KByte = #0800H XDATA_SEITE_55: ;CALL DN_WATCHDOG DEC R1 MOV P2,R1 ; Seitenadresse XDATA_55: MOVX @R0,A DJNZ R0,XDATA_55 CJNE R1,#00H,XDATA_SEITE_55 ; AA ueberpruefen MOV R0,#00H MOV R1,#08H ; 2KByte = #0800H XDATA_SEITE_55_C: ;CALL DN_WATCHDOG DEC R1 MOV P2,R1 ; Seitenadresse XDATA_55_C: MOVX A,@R0 XRL A,B JNZ XDATA_55_FAIL DJNZ R0,XDATA_55_C CJNE R1,#00H,XDATA_SEITE_55_C JMP XDATA_55_C_E XDATA_55_FAIL: MOV A,#11H JMP CHECK_FAIL XDATA_55_C_E: ; Fehlerbehandlung JMP CHECK_FAIL_E CHECK_FAIL: ;CALL DN_WATCHDOG CHECK_FAIL_SEND: ;CALL DN_WATCHDOG JMP CHECK_FAIL_SEND CHECK_FAIL_E: ; Programmstart ; interner Speicher mit 00 fuellen, Initialisierung ;CALL DN_WATCHDOG MOV R0,#7FH CLR A IDATA_00: MOV @R0,A DJNZ R0,IDATA_00 LJMP ?C_START ; MAIN wird ueber INIT aufgerufen END ************************************************************************ *
>Ja würde ich gerne, aber den alten Compiler (C51 v4.01) kriege ich nicht >zum Laufen. Vielleicht liegt es an dem Windows? Wo kriegt man raus ob es >mit dem 7 oder XP kompatibel ist? Richte Dir Win98/95/Dos in einer VM (Virtual PC 2007) unter XP (Win7) ein. Damit klappt die Dongle-Erkennung problemlos. Direkt unter XP oder Win7 laufen die alten C51 Versionen nicht, da der Zugriff auf die parallele Schnittstelle nicht durchkommt. Eine komplette Dokumentation ist bei SDCC übrigens mit dabei, siehe im Installations-Ordner. Die C-Befehle bedürfen keiner Beschreibung, da ANSI-kompatibel. Alles spezifische ist dort aber dokumentiert.
> Richte Dir Win98/95/Dos in einer VM (Virtual PC 2007) unter XP (Win7) > ein. Damit klappt die Dongle-Erkennung problemlos. Direkt unter XP oder > Win7 laufen die alten C51 Versionen nicht, da der Zugriff auf die > parallele Schnittstelle nicht durchkommt. > Das ist wahrscheinlich der einzige Weg zum Erfolg, da wie mir scheint grundsätzliches Wissen wie das ein Compiler und Linker so macht fehlt. Wie gesagt init und startup finden sich später in main.asm automatisch wieder bei SDCC. > Eine komplette Dokumentation ist bei SDCC übrigens mit dabei, siehe im > Installations-Ordner. Die C-Befehle bedürfen keiner Beschreibung, da > ANSI-kompatibel. Alles spezifische ist dort aber dokumentiert. Na ja der Assembler ist sehr schwach dokumentiert.
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.