www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik 8051er und Keil


Autor: Oliver D. (smasher)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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!

Autor: Eddy Current (chrisi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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;
  }
}

Autor: mein Name ist Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Oliver D. (smasher)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: mein Name ist Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Oliver D. (smasher)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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:
#include<reg51.h>

Dann kennt der Keil die Ports P0...P3 (und alle anderen SFRs).


Peter

Autor: Horst Gschwandtner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Oliver D. (smasher)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Horst Gschwandtner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
bei sbit funktioniert es wie folgt:

sbit LED_XY = P1^1;

Autor: mein Name ist Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@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.

Autor: mein Name ist Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sri, #define ... natürlich ohne das Semikolon am Ende ;-)
bevor hier wieder Steine geworfen werden

Autor: mein Name ist Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Oliver D. (smasher)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: mein Name ist Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Oliver D. (smasher)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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...

Autor: mein Name ist Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Oliver D. (smasher)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: mein Name ist Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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)
}

Autor: mein Name ist Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: mein Name ist Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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".

Autor: Oliver D. (smasher)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 ;)

Autor: mein Name ist Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: mein Name ist Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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. ;-)

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Oliver D. (smasher)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: mein Name ist Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.