Hallo, folgendes Problem. In der Schule haben wir vom BK Recklinghausen eine 8051er Schaltung nachgebaut. Sie arbeitet mit einem IO Warrior für USB und ich habe passend dafür einen Downloader, der mir mit beiligernder DLL datei den code auf den AT89S52 schreibt. Mein Problem ist die Programmiersoftware. Ich komme mit Keil absolut nicht klar. Ich habe eine neue Projekt datei angelegt und dann erstellt er mir automatisch eine STARTUP.A51. Vorher habe ich natürlich unter Atmel meinen Prozi ausgewählt. Naja... Jedenfalls will ich in C ein einfaches programm schreiben, welches ich dann als hex oder bin file rausbekomme. Daran haperts. Ich habe nämlich keine ahnung worauf ich dafür klicken muss... Achja, mein Code beispiel währe dazu: at 0x80 sbit led0; main { for (;;) led0=0; } } Damit wird eine der LEDs die auf dem Board sind angeschaltet. Es währ echt cool wenn mir einer hilft, weil schon allein bei meinem quellcode fehler angezeigt werden. Auch kommt oft die Nachricht cant read file. Naja, vielleicht kennt ihr ja ein einfacheres tool für meine programmierarbeit! Danke!
Ohne Keil zu kennen, sage ich da fehlt mindestens eine geschweifte Klammer und noch ein wenig mehr: at 0x80 sbit led0; // Keine Ahnung void main(void) { for (;;) { led0=0; } }
Wie wäre es vorher mit einem kleinen C-Kurs, bevor man die Leute auf uP-Programmierung losjagt? Ich schlage vor, eines oder zwei der Demo-Applikationen aus der Keil-Sammlung zu analysieren und daran zu lernen.
mein Name ist Gast wrote: > Wie wäre es vorher mit einem kleinen C-Kurs, > bevor man die Leute auf uP-Programmierung losjagt? > > Ich schlage vor, eines oder zwei der Demo-Applikationen > aus der Keil-Sammlung zu analysieren und daran zu lernen. Ja natürlich. Wie gut, dass auch bei den programmbeispielen der Lehrer dieser Fehler bei mir erscheint: Build target 'Target 1' compiling test3.C... TEST3.C(1): error C129: missing ';' before '0x80' Target not created Aber die Schüler sind natürlich immer schuld... Wie währs mal mit konstruktiver hilfe, warum dieser fehler erscheint und wie ich ein hex file erzeuge passend für meinen AT 89 S 51
Oliver D. wrote: > Mein Problem ist die Programmiersoftware. Ich komme mit Keil absolut > nicht klar. Um mal die Begriffe klar zu stellen: Keil ist der Compiler und der läuft rein auf der Kommandozeile. Was Du meinst, ist die IDE (µVision), die den einzelnen Programmen die entsprechenden Argumente beim Aufruf übergibt. Man kann entweder die Schalterzeichen direkt eingeben oder aus den Optionen auswählen. Und irgendwo in den Compilereinstellungen hast Du die Einstellung für das Ausgabeformat. Einfach mal durchklicken. Man kann sogar noch sein eigenes Programmiertool mit eintragen, wenn man es gleich nach dem Compilieren in den Chip brennen lassen will. Peter
Nein, Dein Problem fängt schon viel früher als bei dem Programmierwerkzeug an. Es fängt schon bei der Programmierung in C an, sonst wären Dir die grundlegenden Fehler, auf die man Dich oben hingewiesen hat, nicht unter- laufen. Noch wesentlich gravierender aber, dass der Lehrer Dich nicht ordentlich in die Nutzung des Werkzeuges einweist. Klingt so nach "da hast Du es, mach was draus". Man sollte er- warten können, dass der Lehrer wenigstens ein Beispielprogramm beherrscht und schon mal angesehen hat. So - jetzt aber zur Sache. ;-) Schau mal unter "Projekt" -> "Options for Target ..." -> "Output" nach und dort "Create HEX File" markieren.
mein Name ist Gast wrote: > Schau mal unter > "Projekt" -> "Options for Target ..." -> "Output" > nach und dort > "Create HEX File" markieren. Nützt in diesem Fall nichts, der Compiler sagt ja eindeutig: "Target not created" Peter
Danke schonmal für das Hex file :) Das hier ist ein Code beispiel: /* Quadrat.c: Ausgabe des Quadrats des an den DIP-Schaltern (Port 2) eingestellten Wertes auf den LEDs (Port 0) 11.2.07 E.Ofenbach */ at 0x80 sfr P0; // Adresslage von Port 0 at 0x80 sfr P2; // Adresslage von Port 2 void main() { code char quadrat[16]={0,1,4,9,16,25,36,49,64, // Konstante mit 16 Werten 81,100,121,144,169,196,225}; // im Codespeicher while(1) { P2=0xFF; // P2 vor Auslesen auf H-Pegel P0=~quadrat[P2%16]; // Auslesen der Tabelle mit den // untersten 4 Bits der DIP-Schalter } } So habe ich es erhalten und so soll es auch lauefn! Das Problem in uVision 3 ist aber, das er mir den fehler ausgibt, das er ein ";" vor der 0x80 erwartet.
Oliver D. wrote: > at 0x80 sfr P0; // Adresslage von Port 0 > at 0x80 sfr P2; // Adresslage von Port 2 > Das Problem in uVision 3 ist aber, das er mir den fehler ausgibt, das er > ein ";" vor der 0x80 erwartet. Da hatter recht, das ist keine standard C-Syntax. Warscheinlich ist das Programm für nen anderen Compiler geschrieben. Versuch mal statt dessen:
1 | #include<reg51.h> |
Dann kennt der Keil die Ports P0...P3 (und alle anderen SFRs). Peter
at 0x80 sfr P0; ????? habe ich noch nie versucht, schein mir aber etwas komisch formuliert zu sein. Ich arbeite seit Jahren mit Keil C51, schreibe aber immer sfr P0 = 0x80; Ich bin mir eigentlich sicher, dass dies die einzig richtige Schreibweise ist. mfg Horst
TEST.C(4): error C129: missing ';' before '0x80' Der fehler bleibt trotz der neuen weiter bestehen. Muss ich vielleicht noch irgendwo anders im Keil etwas umstellen? Einfache Programme wie z.b. Print f erkennt er ja einwandfrei. Nur ebenhalt das mit den special function registern nicht.
@Peter Die Sache mit dem Huhn und dem Ei. Ohne die Konfiguration gibt es auch mit fehlerfreiem Quelltext keinen Hex-Output. @Oliver: zum C-Code mit der LED... An welchem Port hängt die LED und ist sie gegen Masse oder gegen VCC verdrahtet? Port P0 ist eine nicht unbedingt glückliche Wahl. Wenn die LED z.B an Port P0 Bit 0 hängt, würde ich bei "gegen Masse" so codieren: #define LED0 = 0x01; void main(void) { for (;;) { P0 |= LED0; } } Wenn gegen VCC dann: P0 &= ~(LED0); Wobei P0 in der Device-include-Datei definiert ist.
sri, #define ... natürlich ohne das Semikolon am Ende ;-) bevor hier wieder Steine geworfen werden
Dieses "at sfr ..." solltest Du ersatzlos weglassen können, denn die Ports sind in der Regel in der Device-include-Datei vordefiniert. Was Du definieren musst, ist LED0. Entweder wie in meinem Beispiel mit #define und einer "Bitmaske" oder alternativ durch direkte Bit-Zuordnung mit sbit LED0 = P0^0; Dann aber dort wieder mit Semikolon am Ende. ;-) Die Variante mit "sbit" läuft meines Wissens nur bei bit-adressierbaren Registern. P0 ist bitaddresierbar. Dein Beispiel mit Quadrat.c legt die Variante mit Bitmaske - also #define LED0 = 0x01 - nahe.
Also folgenes. Die LEDs sind an Port 0 angeschlossen und liegen an VCC and und gehen über einen Widerstand an Port 0. Wie ich gerade beim lesen der Help function in Keil festgestellt habe, ist die schreibweise: at 0x80 sfr led0; wohl falsch zum definieren des ports. Das hier ist laut handbuch die richtige: sfr P0 = 0x80; (wie mir ja schon jemand anderes nettweise geschrieben hat :) ) Nun denn, mich würde interessieren wie denn ein Programm code auszusehen hat, der funktioniert und einfach an 0x80 eine 1 schreibt. Welches .h dateien muss ich per include laden? ansonsten ja: sfr P0 = 0x80; main (void) { for (;;) PO=0; } Wobei eigentlich das Void unsinn ist, denn auf dem MC ist kein betriebssystem oder anderes programm, an das rückgabewerte gegeben werden können. Ebenso muss das ganze laut meinem lehrer in eine schleife, weil wohl sonst immer der gesamte speicher durchlaufen wird uns mist rauskommt. Also, währ das code beispiel so ok? Achja, muss es P0 (Null) oder PO (Buchstabe O) heissen?
Es handelt sich um P "Null", also P0, P1, P2 usw. Um das Bit Null in Port PNull auf "1" zu setzen: P0 |= 0x01; Dein Beispiel setzt das komplette Port P0 auf "0". Es geht auch P0 = 0x01; Aber dann werden die restlichen 7 Bits des Ports auf "0" gesetzt. Die Variante oben manipuliert nur das Bit Null im Port Null.
Also grad blick ich garnicht mehr durch. Die LEDs sind am P0.0-P0.7 angeschlossen gegen VCC. So, nun will ich gerne mal ein komplettes Programmbeispiel haben. Laut lehrer ist es ein SFR und einzelne Bits sind mit sbit anzusprechen. Alle beispiele die ich bisher ausprobiert habe funktionierten nicht. Beim schreiben auf den MC brach die software immer ab, wobei programme ohne sfr funktionieren. Also mal bitte ein komplettes beispiel. Die adresse des SFR ist übrigens 0x80 bzw. 0x81, 0x82...
Für dieses Mini-Programm braucht Du keine Header-Datei. Auch ein include der sfr-Dateien des Prozessors ist nicht erforderlich, da Du den Prozessor-typ in der Projektumgebung schon festgelegt hast. In der STARTUP-Datei stehen die Prozessor-typischen Definitionen schon drin. Nach meinen Erfahrungen leider nicht immer fehlerfrei und auch nicht vollständig. So tief in die Materie dringt Dein Beispielprogramm jedoch nicht, dass man darauf ein Auge halten müsste.
Also sieht der code nur so aus : sbit led = 0x80; void main(void) { for (;;) { led=0; } } krass, es funktioniert. Kannst du mir vielleicht erklären, warum gerade lehrer, die alles sinvoll und einfach und verständlich gestalte sollen, so einen scheiss verzapfen? Das Programm funtkioniert gerade einwandfrei bei mir. Led 0 leuchtet freu Gibts vielleicht ne seite wo alles ordentlich erklärt ist, mit den aktuellen C standards und ohne fehler?
sfr P0 = 0x80; // kann eventuell entfallen main (void) { P0 = 0xFF; // alle I/Os an P0 auf high (= LEDs aus) for(;;) P0 = 0xFE; // P0.0 = low (= LED0 an) }
ja, Oliver - Deine Variante geht auch allerdings "floaten" die anderen 7 LEDs dann wegen der weak pullups an P0 daher vor dem "for(;;)" noch einfügen: P0 = 0xFF; // Port 0 auf Output
Ja, solche Lehrer habe ich auch "gefressen". Kennen das Werkzeug nicht, haben es nicht einmal vorher ausprobiert ob es läuft und sind aber in der Lage, die Arbeit dann zu bewerten... Trifft man mehr und mehr. Das Übel fing an mit der Umwandlung von Informatik-Kursen in Internet-Kurse; von sachkundigen Grundlagen in "bunte Bilder klicken".
Hmm, also mal ne andere frage, wieso schreibt ihr noch: P0 = 0xFF; // alle I/Os an P0 auf high (= LEDs aus) bzw. P0 = 0xFF; // Port 0 auf Output mit in den code? Bei mir gehts auch ohne das. Ich lege einfach nur sbit led0 = 0x80; void main(void) { for (;;) { led0=0; } } Und das Programm läuft. Könnt ihr mir das noch erklären ? Achja, zu den Lehrern...auf meiner Realschule hatte ich so einen "bunte bilder" klicken lehrer. Ausser Word und Excel lernt man da eigentlich garnix. Er wollte dann mit uns PHP anfangen, allerdings scheiterte dieses vollkommen ;)
Falls Du noch "spielen" willst, die Werte für die anderen LEDs sind 0x81, 0x82, 0x83, 0x84, 0x85, 0x86 und 0x87 Also die Basis-Adresse des Port P0 mit 0x80 plus den Werten 0x00..0x07 für die I/O-Anschlüsse des Port P0. Es ist eine kleine Übung, mit diesen Adressen in einer Schleife ein Lauflicht zu erzeugen.
Das mit dem P0 = 0xFF ist eine 8051-spezifische Sache. Die Ports bei den 8051-Prozessoren arbeiten i.d.R. in beide Richtungen. Für Eingangsignale haben sie intern einen "schwachen" Pull-Up-Widerstand. Will man die Ports für Ausgang nutzen, empfiehlt der Hersteller, mit 0xFF in den Port-I/Os einen "starken" Pull-Up- widerstand zu aktivieren. Ohne dieses 0xFF "lavieren" die Ausgangsspannungen der Ports. Zum Beispiel kann man dann die LEDs durch Finger-Berührung schon von außen zum Leuchten bekommen; mal so blind behauptet - ausprobiert habe ich es nicht und hängt wohl auch vom Prozessor ab. Mit jeder Zeile mehr riskiere ich, von den Anderen gesteinigt zu werden - es geht ein wenig rüde zu in diesem Forum. Daher soll das genügen. ;-)
mein Name ist Gast wrote: > Das mit dem P0 = 0xFF ist eine 8051-spezifische Sache. > Die Ports bei den 8051-Prozessoren arbeiten i.d.R. in > beide Richtungen. Für Eingangsignale haben sie intern > einen "schwachen" Pull-Up-Widerstand. Will man die > Ports für Ausgang nutzen, empfiehlt der Hersteller, > mit 0xFF in den Port-I/Os einen "starken" Pull-Up- > widerstand zu aktivieren. Nenn mir mal den Hersteller, der so einen Unsinn empfiehlt. Der P0 hat kein Pullups, der floatet immer, wenn er high ist. Und es gibt auch keine trinäre Logik im 8051, d.h. die Pullups an P1..P3 werden nicht "upper", wenn man nochmal 0xFF reinschreibt. Nach dem Reset sind alle Ports 0xFF und gut is. Peter
Hmm, werden denn die Ports wirklich als ausgang genutzt? Also messen will ich damit natürlich nix. Ich brauche nur eine logische 0 an den ports, wo es leuchten soll, damit von VCC über die LEds und den widerstand ein strom fliesst. Wenn ich also eine 1 am Port habe, dann leuchtet nix. (denn dann währe der potentialunterschied ja 0V) Egal, hauptsache ich bin schonmal soweit das sich was tut ;) Gibts denn irgend ne Seite wo das alles so beschrieben ist? Mit programmbeispielen? Oder irgend ein gutes buch?
Wo Peter Recht hat, hat er Recht. Ein starker Pull-Up wird nur bei einem 0-auf-1-Übergang für kurze Zeit zugeschaltet und das auch nur bei Ports wie P1, P2 und P3. Bei Port P0 - dass dieser ein Sonder- fall darstellt hatte ich schon angedeutet - werden mit Ausgabe 0xFF die Open-Drain-Ausgänge auf "floaten" geschaltet. Die Anweisung P0 = 0xFF ist entbehrlich. Es ist Geschmacksache - ich würde sie trotzdem einfügen, alleine, um bewusst Port P0 in einen definierten Zustand zu setzen (Kommentar "alle LEDs aus") und nicht auf Annahmen zu bauen. Profis brauchen solche Gedanken- stützen natürlich nicht; für Anfänger würde ich argumen- tieren "es schadet nicht". Es darf gemäkelt werden.
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.