Forum: Mikrocontroller und Digitale Elektronik 89C51 Anfängerfehler?


von Johannes (Gast)


Lesenswert?

Hallo,

Ich möchte einen Mikrocontroller Typ AT89c51 (24PC) mit nem Galep 4 
Programmiern alderdings macht der Microcontroler nicht das was ich will 
:-(
sondern die ausgänge sind nach dem Reset mal high mal low

Die beschaltung des Microcontroller ist dass Port 2 und 3 als Ausgänge 
(Led's) beschalten sind und so noch VCC, Ground, und Reset und natürlich 
der x-tal2 mit einem oszillator verbunden sind.


Das Programm:

  mov p3, #10101010b
  mov P2, #10101010b

end


was ist falsch oder hab ich vergessen?

ach ja nicht zu vergessen ich bin blutiger Anfänger!!

wär nett wenn mir jemand helfen kann!

Mit freundlichem Gruß

Johannes

von Monarch35 (Gast)


Lesenswert?

Ich kenne den AT89c51 speziell nicht, kann dir also nicht sagen, ob die 
port-befehle so richtig sind. Ich würde dir aber dazu raten, dein 
Programm in einer endlosschleife enden zu lassen. Du weisst ja nicht, 
was nach deinem Code im speicher steht.

von Simon H. (simi)


Lesenswert?

Ausserdem solltest Du vermutlich noch die Ports als Ausgänge definieren. 
Meinen letzten 8032 habe ich allerdings vor etwa einem Jahrhundert 
programmiert... kann mich also auch nicht mehr so recht erinnern, wie.

Bist Du sicher, dass die mal high mal low sind? Ich würde eher auf 
hochohmig tippen...

von Peter D. (peda)


Lesenswert?

Nach dem Reset müssen alle Ausgänge high bzw. P0 hochohmig sein.

/EA muß an VCC sein (vergessen Anfänger häufig).


Fürs Entwickeln rate ich zum AT89C51ED2, dann mußt Du ihn nicht immer 
ins Programmiergerät stecken.


Peter

von Peter D. (peda)


Lesenswert?

Simon Huwyler wrote:

> Meinen letzten 8032 habe ich allerdings vor etwa einem Jahrhundert
> programmiert... kann mich also auch nicht mehr so recht erinnern, wie.

Ne, den gibts ja erst seit 1982.

Meinen Glückwunsch, als über 100-jähriger noch mit MCs zu basteln.


Peter

von Johannes (Gast)


Lesenswert?

Hallo peter

>>
/EA muß an VCC sein (vergessen Anfänger häufig).

ja ich habs vergessen!

zum Glück gehts nicht nur mir so! :-)

mal schaun was sich tut!


Johannes


von Johannes (Gast)


Lesenswert?

Leider funkionierts immer noch nicht

von Joe (Gast)


Lesenswert?

EA an + (VCC), Quarz z.B. 12 MHz, 2x 33 pF, Kapazitäten am Oscillator 
werden auch häufig falsch gewählt.

>> mov p3, #10101010b
>> mov P2, #10101010b

>> end

org bzw. CSEG fehlt, und am Ende ein ljmp $. Ansonsten führt der MC 
Zufallscode aus.

Erklärung folgt wenns dann geht.

von Matti (Gast)


Lesenswert?

Ich kram mal zusammen, was mir aus meiner 8051 Zeit noch dazu einfällt:

Alles, was meine Vorgänger geschrieben haben ist schon richtig und 
sinnvoll. Zusätzlich würde ich mir natürlich noch den Reset-Pin ansehen, 
da brauchte der 8051 einen 1uF Kondensator (und ein 10k Pullup kann 
nicht schaden, obwohl er im Prinzip im Atmel schon eingebaut ist).

Input/Output muß man beim 8051 nicht definieren, der hat nach Masse nur 
einen N-Kanal Fet und nach VCC einen Pullup. Wenn man ihn als Input 
verwenden will, dann schreibt man vorher eine 1 raus.

Ich habe hier noch eine alte Testroutine (die einfach nur einen Rechteck 
auf P3.0 ausgibt):

        CPU     8051
        INCLUDE stddef51.inc
        org     0000h
        nop
loop    mov     R3,#0
        setb    P3.0
l1      djnz    R3,ll
        clr     R3.0
l2      djnz    R3,l2
        jmp     loop

von markus (Gast)


Lesenswert?

hmmm

mein vorschlag ist das hier :

org 0000h

mov P3, #080h
mov P2, #010h

loop:
      sjmp loop

end

von ab-cd (Gast)


Lesenswert?

pull-up's ?

von Joe (Gast)


Lesenswert?

>> pull up's

Ja, für Port 0

>> loop: sjmp loop

entspricht ljmp $

Vielleicht gibt Johannes noch ein Feedback.

von Johannes (Gast)


Lesenswert?

ja da ist das feedback
es funktioniert immer noch nicht

also meine hex schaut dann folgendermaßen aus
75 b0 80 75 a0 10 80 fe 80 fe
der rest ist ff

vllt ist da ja auch ein fehler drin

von Joe (Gast)


Lesenswert?

Nein, der Fehler steckt in der Hardware.

Wenn du
org 0000h
mov p1,#01010101b
ljmp $

programmierst so schreibt der 8x51 den Wert 01010101b in den Port 1.

Das ljmp $ läßt ihn auf der Stelle springen (Endlosschleife). Auf einem 
MC ist kein Betriebssystem zu dem ein ausgeführtes Programm zurückkehren 
könnte. Daher mußt du am Ende irgendeine Endlos Schleife bauen.

Das org 0000h ist ebenso sehr wichtig, nach einem RESET führt der MC 
seinen ersten Befehl von Adresse 0000h aus.

von xyz (Gast)


Lesenswert?

Dann fertige doch bitte einen Schaltplan an - speziell auch der LED.....

von Joe (Gast)


Angehängte Dateien:

Lesenswert?

Anbei mal das .hex zum Beispiel.

von Joe (Gast)


Lesenswert?

:060000007590550200039B
:00000001FF

Das kommt dabei heraus.

von xyz (Gast)


Lesenswert?

Muss nicht ab .org 0000 erst mal eine Vektortabelle stehen ?????

von Joe (Gast)


Lesenswert?

Nein, hört mal auf nur Unsicherheiten zu streuen.

Interrupts kommt später dran ;-)) Wo kein Interrupt, da braucht es auch 
keine Einsprungadressen (zu berücksichtigen).

von Matti (Gast)


Lesenswert?

@johannes:
Hast Du denn mal nachgesehen, was Dein Reset-Pin macht? Nicht, dass Du 
den aus Versehen auf low gelegt hast? Der muss am Anfang einmal kurz auf 
low und dann auf high.

@xyz
Vektortabelle ist nicht zwingend notwendig, weil beim 51 beim Start alle 
Interrupts abgeschaltet sind.

von xyz (Gast)


Lesenswert?

ja aber er führt doch nicht den Befehl aus, sondern interpretiert ihn 
als reset - Vektor ins "nirvana"

von Joe (Gast)


Lesenswert?

>>ja aber er führt doch nicht den Befehl aus, sondern interpretiert ihn
>>als reset - Vektor ins "nirvana"

Blödsinn

von xyz (Gast)


Lesenswert?

und was ist das:

 CSEG
                      86
0000                  87                     ORG     0000H           ; 
power on/reset vector
0000 020080           88                     jmp     on_reset
                      89
0003                  90                     ORG     0003H           ; 
external interrupt 0 vector
0003 32               91                     reti                    ; 
undefined
                      92
000B                  93                     ORG     000BH           ; 
timer 0 overflow vector
000B 32               94                     reti                    ; 
undefined
                      95
0013                  96                     ORG     0013H           ; 
external interrupt 1 vector
0013 32               97                     reti                    ; 
undefined
                      98
001B                  99                     ORG     001BH           ; 
timer 1 overflow vector
001B 32              100                     reti                    ; 
undefined
                     101
0023                 102                     ORG     0023H           ; 
serial I/O interrupt vector
0023 32              103                     reti                    ; 
undefined
                     104
0080                 105                     ORG     0080H           ; 
begin code space

von xyz (Gast)


Lesenswert?

Und das ist aus: his collection of routines allows an AT89Cx051 
microcontroller to read.......

von Joe (Gast)


Lesenswert?

Das was du nicht verstehst.

Wenn kein Interrupt => keine Vektortabelle. Wo ist bei genannten 
Beispiel ein Interrupt ?

von xyz (Gast)


Lesenswert?

Du musst in Adresse 0000 (=Reset-Vektor) die Adresse eintragen, wo Dein 
Code beginnt....

von Johannes (Gast)


Lesenswert?

Matti
also was den resett betrifft!

ich hab meine schaltung geändert anfang low und danach high

bringt auch nix

und aus dem datenblatt ist zu entnehmen

"RST
Reset input. A high on this pinfor two machine cycles while the 
oscillator is running reset the device"

und du erzählt mir dass das low signal den reset auslößt
- naja nen versuch wars wert

@Joe und xyz - die programme- bzw hex von oben haun auch nicht hin

gruß

Johannes

von Joe (Gast)


Lesenswert?

org 0000h
mov p1,#01010101b
ljmp $

Habe nichts anderes behauptet. Aber wenn du keinen Interrupt verwendest 
dann steht der Programmspeicherplatz für andere Dinge doch zur Verfügung 
und das Programm beginnt @ 0000H.

Mal Hand aufs Herz, du bist scheinens auch ein Anfänger !

Eröffne doch einen eigenen Thread zum Thema 8x51 Interrupts.

von xyz (Gast)


Lesenswert?

Hallo Johannes,

Du musst eine Vektortabelle anlegen, sonst läuft es nicht....

die sieht so aus:

    CSEG

    ORG  0000H    ; power on/reset vector
    jmp  on_reset

    ORG  0003H    ; external interrupt 0 vector
    reti      ; undefined

    ORG  000BH    ; timer 0 overflow vector
    reti      ; undefined

    ORG  0013H    ; external interrupt 1 vector
    reti      ; undefined

    ORG  001BH    ; timer 1 overflow vector
    reti      ; undefined

    ORG  0023H    ; serial I/O interrupt vector
    reti      ; undefined

    ORG  0080H    ; begin code space
    USING  0    ; register bank zero
on_reset:
    mov  sp, #(stack-1)  ; initialize stack pointer

von Joe (Gast)


Lesenswert?

Johannes, mal einen Schaltplan, poste dein Programm, welchen Compiler 
verwendest du ?

von xyz (Gast)


Lesenswert?

und ab on_reset kommt "Dein Programm"....

von Joe (Gast)


Lesenswert?

@ XYZ, wo hast du bloß den Blödsinn her ???

von xyz (Gast)


Lesenswert?

ja, ich bin auch ein Anfänger gewesen vor über 30 Jahren

von Joe (Gast)


Lesenswert?

I give up,

30 Jahre und kann es immer noch nicht ;-((

von xyz (Gast)


Lesenswert?

@joe - es geht um einen "AT89c51" und das ist ein "8031 - Derivat"
Wenn Du da keinen "Keil" oder was auch immer "Monitor" drin hast, der 
das für Dich managed, musst Du es zu Fuss machen.....

von Johannes (Gast)


Lesenswert?

Der compiler ist as51 V4
und ich lad die daten über das programm galep32 vom galep 4 auf den Mc

schaltpaln muss das sein? ich hab doch schon alles oben beschrieben

Die beschaltung der Ports p2,p3 vcc-330ohm-led-port

5V+ liegen an vcc und am EA Port
0V liegen an GND port

XTAL1 ist mit dem oszillator(12MHz) ausgang verbunden

sonst ist nix angeschlossen

von Joe (Gast)


Lesenswert?

Wir kennen die Umgebung von Johannes nicht, deshalb habe ich gefragt.

So wie ich es verstehe verwendet er ein Programmiergerät.

Deine 30 Jahre überzeugen mich nicht ;-)) wie gesagt, kein Interrupt, 
dann auch keine ISR Einsprungadressen. Wenn wir um ne Kiste Bier wetten, 
dann hört sie mir.

Angebot steht.

von Johannes (Gast)


Lesenswert?

achso den reset hab ich natürlcih auch angeschlossen bin aber etz total 
verwirrt wie ich den anschließen soll erst low und dann high oder 
anderst rum

von xyz (Gast)


Lesenswert?

es geht nicht um die Interrupts es geht NUR um den Reset-Vektor!!!!

Wenn Du keine Interrupts verwendest kannst Du den Reset-Vektor evtl. auf 
die Adresse des 1. Interrupt-Vektors legen, aber was soll das ?

Sobald Johannes richtig loslegt, wird es Interrupts geben.....

Und wozu wetten - Johannes kann die Tabelle eintippen oder reinkopiern, 
ausprobieren und das Thema wäre vom Tisch.

von Joe (Gast)


Lesenswert?

Reset 10 uF nach VCC, 8k2 nach Masse.

von Joe (Gast)


Lesenswert?

@ XYZ, letzte Versuch, habe ich org 0000h geschrieben ? ist das RESET ?

von xyz (Gast)


Lesenswert?

@Joe, letzter Versuch, an .org 0000h muss der Reser-Vektor liegen !

von Joe (Gast)


Lesenswert?

Johannes, was für einen Oscillator verwendest du, hast du einen Osci und 
kannst den Pegel an XTAL messen ?

von Joe (Gast)


Lesenswert?

@ XYZ,

org 0000h
mov p1,#01010101b
ljmp $

tut er doch (grrrrr)

von Johannes (Gast)


Lesenswert?

na also es funktioniert doch irgentwie-
jetzt aber mit dem at89c52

@ matti
der reset ist angang high und dann low

fragt mich aber bitte nicht warum
und achso dass programm in hex ist jetz: 75 b0 55 75 a0 55 80 fe 80

danke an alle

was war jetz genau die diskussion wegen den interrups

von Joe (Gast)


Lesenswert?

Jetzt müßte uns XYZ erklären warum es geht ;-)) Die Kiste Bier ist mir.

Also, es gibt eine Reihe von Interrupts und wenn du einen auslößt dann 
mußt du an den genannten Adressen (von XYZ) einen Sprungbefehl setzen 
der in eine Interrupt Routine verzweigt.

von xyz (Gast)


Lesenswert?

Das Du dann die Vektortabelle mit "reti" (=return from interrupt) 
brauchst

von xyz (Gast)


Lesenswert?

Jetzt liegt da Dein Code anstelle der "reti" und falls ein Interrupt 
kommt, "schmiert" der Controller dann ab.....

von Joe (Gast)


Lesenswert?

Johannes, XYZ kapierts nicht,

http://www.batronix.com/elektronik/know-how/mikrocontroller-technik.shtml

Wenn du keinen Interrupt verwendest dann brauchst du auch keine 
Einsprungadressen zu berücksichtigen.

von Johannes (Gast)


Lesenswert?

was genau soll ich etz ausprobeiern (welchen interrupt usw)?

von Johannes (Gast)


Lesenswert?

>>Wenn du keinen Interrupt verwendest dann brauchst du auch keine
Einsprungadressen zu berücksichtigen.

klingt auf jeden fall logisch

von Joe (Gast)


Lesenswert?

Probier worauf du lust hast, bevor du dich mit Interrupts beschäftigst, 
programmier mal ein Lauflicht, ein Display etc. etc. oder nimm dir ein 
Projekt vor und beschreib wo du hin willst.

Viel Spaß

von Johannes (Gast)


Lesenswert?

ja also noch mal ein DICKES DANKE an ALLE die mir geholfen haben

Johannes

von Niels H. (monarch35)


Lesenswert?

@xyz:

ich habe auch vor 15Jahren das erste mal mit 80c32, 80c535 und 80c52AH 
programmiert und ich muss Joe beipflichten:

Du brauchst keine Vectortabelle, wenn keine Interrupts benutzt werden.
Ab 000h steht im Speicher der erste CODE (keine ADRESSE), der ausgeführt 
wird. Danach folgen im Speicher eine ganze Reihe von CODES (keine 
Adressen), die ausgeführt werden, WENN ein Interrupt zur Ausführung 
kommt.

Wird verraussichtlich keine Interrupts benötigt, muss man auch keine 
Vectortabelle anlegen und der Speicher kann sofort mit dem Hauptprogramm 
anfangen.

von Peter D. (peda)


Lesenswert?

Es gibt Architekturen, die haben ne Vektortabelle.

Der 8051 und auch AVR haben aber feste Einsprungvektoren und ab 0x0000 
erfolgt  die sofortige Codeausführung ab Reset (wenn nicht zum 
Bootvektor verbogen).

Wenn nun Interrupts gebraucht werden, kann man diese direkt am 
jeweiligen Einsprung ausführen oder wenn der Platz nicht ausreicht, eben 
woanders hin springen.


Daß es sich beim xyz-Beispiel nicht um eine Vektortabelle handelt, sieht 
man ja sofort daran, daß dort keine Vektoren (DW-Anweisungen) stehen, 
sondern Befehle (jmp, reti). Demzufolge sind auch sämtliche anderen 
Befehle erlaubt.

Der Abstand von 8 zwischen den Einsprungadressen beim 8051 hat den 
Grund, daß man kleine Handler direkt ohne Sprung einfügen kann.

Z.B. um einen 16Bit Timer auf 24Bit zu erweitern, schreibt man einfach 
"inc 7fh" + "reti", sind nur 3 Byte, paßt also ohne Sprung rein.


Es ist gängige Praxis, daß kleinere Programme ohne Interrupts direkt ab 
0x0000 stehen. Wozu unnütz Flash verschwenden ?


Ein "org 0000h" ist nur dann notwendig, wenn der Code nicht in 
aufsteigender Reihenfolge geschrieben wurde (z.B. durch Includes).
Der Assembler setzt zu Beginn immer alle Adreß-Counter auf 0 (code, 
data, xdata).


Peter

von Joe (Gast)


Lesenswert?

>> der reset ist angang high und dann low fragt mich aber bitte nicht warum

War reichlich spät. Noch die Antwort zu dem RESET.

C nach VCC, ein Kondensator verhält sich im Einschaltmoment wie ein 
elektrischer Kurzschluß, er will ja geladen werden. Somit für eine kurze 
Zeit VCC an RESET. Ist der Kondensator aufgeladen dann liegt der RESET 
PIN über 8k2 an GND.

Alles klar ?

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
Noch kein Account? Hier anmelden.