Forum: Mikrocontroller und Digitale Elektronik Ports beschreiben und wieder auslesen


von Andreas Strobel (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe da folgendes Problem. Ich möchte einen Port auf der UDR
ausgeben.

Also: ich schalte PortA auf Eingang und möchte das auf die UDR
ausgeben.
(Müßte 0x00 sein)
Danach schalte ich den Port wieder auf Ausgang und übergebe den Wert
0x80.
Danach möchte ich den Port wieder einlesen (Eingang geschaltet).
(Müßte ja 0x80 sein)
Wenn ich nun (im Codevision) den Chip resete, sehe ich auch die
Triggerung an PortA.7 mit einem Oszi. geht von low auf high. Aber auf
der UDR kommt bei beiden ausgaben die 0x80. Halte ich den Oszi an den
Pin, dann bekomme ich auch an der UDR das gewünschte Ergebniss: einmal
0x00 und danach 0x80.

Weiß jemand woran das liegt? Timing, Wiederstände?
An den Ausgängen sind überall 4,7k angeschlossen. Mit der ganzen
Schaltung wird ein anderer Chip gesteuert (oder so solls mal sein ;))

Vielen Dank schonmal
Andreas

von Rahul (Gast)


Lesenswert?

und was soll der Controller machen, wenn er mit Lesen und Schreiben
fertig ist?
Da fehlt noch ein "for(;;);" in der main.

von Andreas Strobel (Gast)


Lesenswert?

Hallo Rahul,

hab ich grad eingefügt, hat aber trotzdem nichts gebracht. Wie
gesagt,wenn ich reset drücke, müßte doch alles wieder von vorne
beginnen und alles abarbeiten. es ist am oszi auch ganz deutlich zu
sehen, dass der pegel von 0volt auf 5volt geht am porta.7. nur an der
udr kommt immer das was ich als letztes geschrieben habe (nämlich die
0x80). mit der oszi spitze am pin krieg ich die 0x00 ausgegeben.

noch n paar ratschläge?

von Rahul (Gast)


Lesenswert?

Vielleicht solltest du dir Beispiele suchen, die sich mit der seriellen
Kommunikation beschäftigen...
Im Datenblatt gibt es in der Regel grundlegende Funktionsbeispiele zu
Themen wie diesen.
Übrigens lesen sich Programme besser, wenn man Makros benutzt. Auch
dazu gibt es hier im Forum Beiträge. Einfach mal nach "Codevision"
suchen.

von Andreas Strobel (Gast)


Lesenswert?

nunja, ich gehe eigentlich davon aus, dass ich schon weiß wie ich im
großen und ganzen ports beschalte.

zum einlesen vom chip: DDRA=0x00; UDR=PINA;
zum schreiben: DDRA=0xFF; PORTA=0x55; (zum Beispiel)

trotzdem tritt oben benannter effekt auf. vielleicht hat ja noch jemand
vorschläge. das datenblatt hab ich gelesen und weiß nich wirklich was
ich falsch gemacht haben könnte.

Andreas

von Karl H. (kbuchegg)


Lesenswert?

Seh ich das richtig:

Wenn Du das Oszi an den Pin haelts funktioniert alles
wie gewuenscht? Wenn das Oszi aber nicht da ist, gehts nicht?

Wie hast Du denn die 4,7k Widerstaende angeschlossen?

von Andreas Strobel (Gast)


Lesenswert?

hallo,

ja genau so ist es!nun wie habe ich den widerstand angeschlossen: also
das eine beinchen an den Atmega16 Pin und das andere beinchen an den
Pin von dem chip mit dem ich kommunizieren will.

z.B.: PortA.0 -> Widerstand -> D0

und das halt 7mal für jede einzelne Datenleitung.

Es liegen wie gesagt genau die Pegel an die ich erwarte, nur wird mir
das nicht an der UDR ausgegeben. Die funktioniert aber, kann da alles
ausgeben wie ich lustig bin. Wenn ich selbst die Ports setze (also auf
ausgang schalte und irgendwas angebe) dann liest er immer wieder das
wenn ich PINx auslesen will, obwohl eindeutig etwas anderes anliegt.

von Karl H. (kbuchegg)


Lesenswert?

> z.B.: PortA.0 -> Widerstand -> D0

Das dachte ich mir.
Und was gedenkst Du zu tun um den Pin, wenn er auf
Eingang geschaltet ist, am rumfloaten zu hindern?

Dein Code ist so dermassen kunfus, dass ich nicht
rausgefunden habe, ob die die internen Pull-Ups
aktiviert hast oder nicht. Ich tippe aber mal auf: nicht.

D.h. Der Eingang haengt mehr oder weniger in der Luft, je
nachdem was Dein nachgeschalteter Chip mit der Leitung
macht, oder eben das Oszi.

Was willst Du da eigentlich machen?

von Karl H. (kbuchegg)


Lesenswert?

> Danach schalte ich den Port wieder auf Ausgang und übergebe
> den Wert 0x80.
> Danach möchte ich den Port wieder einlesen (Eingang geschaltet).
> (Müßte ja 0x80 sein)

Nein. Warum sollte er?

Was Du an einem PORT rausschreibst, hat absolut gar nichts damit
zu tun was Du von selben PIN einliest. Das sind getrennte Pfade.

von Andreas Strobel (Gast)


Lesenswert?

also ich möchte diesen zweiten chip initialisieren. laut datenblatt muss
ich den seine datenleitungen an der adresse 1 auslesen, bis er von
seiner "anlaufphase" (0x3F an den Datenleitungen die an PORTA bei mir
hängen) in den Idle Mode (0x00) übergeht. Wenn das geschehen ist, soll
man eine 0x80 an die Adresse 0 schicken. Die wird über 3
Adressleitungen eingestellt (bei mir an PORTC.0...2). Danach soll man
wieder die Adresse 1 (wie am Anfang)auslesen. Die sollte aber weiterhin
auf 0x00 stehen. Und ich kriege nun immer wieder meine 0x80 gelesen.

Ich hoffe ich hab mich verständlich ausgedrückt ;) Der Code (die
Initialisierung) wurde automatisch von codevision erstellt. aber der
Rest is auf meinem Mist gewachsen ....

von Karl H. (kbuchegg)


Lesenswert?

zb. fehlt mir in deinem Code in der Funktion lesen die
Umschaltung des PORT-A auf lesen.

Ob das Anlegen der Adresse mit vorhergehendem WRITE auf
0, dann Adresse anlegen, dann WRITE auf 1 so richtig ist,
wage ich mal kraeftig zu bezweifeln. Ueblich ist:
man legr die Signale an, und wackelt erst dann mit dem
WRITE oder READ Bit.  Das ist alles mehr als dubios, was
Du da verbrichen hast.

von Karl H. (kbuchegg)


Lesenswert?

Die 'schreiben' Funktion schaut plausibel aus
(was nicht heissen muss, dass sie richtig ist. Sieht
nur plausibel aus).

Aber die lesen

void lesen(unsigned char Adresse)
  {
  char l;

  DDRA=0x00;      // Port A komplett auf Eingang schalten

  A2=(Adresse&0x04)>>2;
  A1=(Adresse&0x02)>>1;
  A0=(Adresse&0x01);

  NCS=0;              //NCS auf Low ziehen
  READ=0;             //Read auf low ziehen (NRD) lese zyklus beginnen
  #asm( "nop" );
  READ=1;             //Read auf high setzen; lese zyklus beenden
  l=PINA;                   //Signal an PortA in Variable
  NCS=1;                     //NCS auf High setzen
  UDR=l;                    //Variable von PortA auf UDR ausgeben
  if (l!=0x00)
    {
    PORTB.3=1;              //LED an

    }
  }

Was sagt das Datenblatt zum Chip. Wann liegen die Daten
an:
  * nachdem die READ wieder auf 1 gewechselt hat
    Dann kannst Du das obige mal versuchen

  * Oder kurze Zeit, nachdem READ auf 0 gegangen ist
    (Dann kommt die PIN Abfrage vor den READ=1)

von Andreas Strobel (Gast)


Lesenswert?

aber das ist doch schonmal ein anhaltspunkt.;)
aber ist wenigstens das richtig?:
ich lesen PAx indem ich DDRA=0x00 eingebe und UDR=PINA verwende?
und wenn ich dann schreiben will mache ich:
DDRA=0xFF und PORTA=0x80?
Dann wieder lesen. DDRA=0x00 und UDR=PINA?
Geht das so?

Dazu das mit dem READ und WRITE wackeln.

von Andreas Strobel (Gast)


Lesenswert?

Hallo kbuchegg,

hab eben nochmal in das Datenblatt geschaut.
Also zunächst muss die Adresse angelegt werden. Danach (min 30ns
später) muss READ oder Write und das NCS auf Low gezogen werden. Dann
werden maximal 35ns später die Daten angelegt. Nachdem der READ/Write
und NCS Impuls beendet ist, müssen die Daten noch mindestens 8ns
anliegen. Der READ/WRITE Puls dauert mindestens 65ns.. Zwischen einem
READ und Write Zyklus müssen min. 150ns liegen.

Andreas

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.