89C51 Anfängerfehler?

Gast #469839
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
Gast #469853
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.
#469858
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...
#469919
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
Gast #469981
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.
Gast #469985
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
Gast #470002
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.
Gast #470014
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.
Gast #470034
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
Gast #470048
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
Gast #470050
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.
Gast #470055
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
Gast #470076
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
Gast #470077
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.
Gast #470085
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.
Gast #470092
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
Gast #470096
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.
Gast #470105
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ß
#470255
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.
#470271
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
Gast #470274
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 ?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren