PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Portbeschaltung nach Timing Diagram HILFE!



Actron
18.02.2008, 16:03
Hallo Leute!

Ich soll mit C über einen 8bit Port einen RCT Chip ansteuern habe aber schon mit der Initialisation so Probleme. :cry: Portbeschaltung is mir an sich klar, macht man PortA = Hexwert und dann läuft das aber bisher waren die Schaltungen ziemlich billig (Led Leiste oder so). Mit dem Timing Diagram vom RCT komm ich jetzt gar nicht klar, hoffe ihr könnt da helfen.

Erster Schritt im Dateblatt ist das hier
https://www.roboternetz.de/phpBB2/files/fluss.jpg

Beschaltung ist bei uns so;

PortA0: Adr0, Dat0
PortA1: Adr1, Dat1
PortA2: Adr2, Dat2
PortA3: Adr3, Dat3
PortA4: ChipSel0
PortA5: ALE (??)
PortA6: Reat
PortA7: Write

Als Beipiel hier die Registers:
https://www.roboternetz.de/phpBB2/files/regs.jpg

Hab mit das etwa so gedacht in Pseudocode:


1111 an PA0 bis PA3 legen (-> Reg. F wählen)
speicher die Addresse
0100 an PA0 bis PA3 legen (-> Reg setzen)

1110 an PA0 bis PA3 legen (-> Reg E wählen)
speicher die Addresse
0110 an PA0 bis PA3 legen (-> Reg setzen)

.....

Das Speichern versteh ich aber nicht also ich muss ja irgendwie umschalten und dem Controller sagen "nimm die Addresse" und "schreibe da dabb die und die Daten hin". :( Wie mache ich das??

Hier das Timing Diagram aber da versteh ich gar nix von:
https://www.roboternetz.de/phpBB2/files/timing_787.jpg

Das muss ja auch alles über den Port nur wie und wann?? Da ist ja alles gleichzeitig und mal so verstetzt und mal so.

Fals es nötig ist hier auch noch ein Schaltbild:
https://www.roboternetz.de/phpBB2/files/schalt_677.jpg

Das Proggen in C ist so kein Prob. nur das mit dem Timing versteh ich nicht. Kann mir vielleicht wer sagen wie der 1. Schritt in C aussehen müsste? Das Doofe ist dass ich erst alles coden muss bevor ich das richtig testen kann. :-(

Hoffe mir kann wer helfen. Wär echt cool!

mfg
Mika

_werwurm_
19.02.2008, 04:25
grüße!

ich kann dir zwar nicht das konkrete programm in c schreiben .. aber mit timingdiagrammen kann ich dir vielleicht helfen. die dinger lesen sich eigentlich fast wie von selbst .. man schaut sie von links nach rechts an. beschrieben ist, welche datenleitungen sich in welcher zeitlichen reihenfolge ändern müssen um den chip richtig anzusprechen. normalerweise werden diese chips direkt an den adress+datenbus angeschlossen - so wie das bei dir klingt gibt es den bei deiner schaltung nicht und du willst den chip direkt an einen port eines (zB) AVR hängen.

dadurch mußt du die einzelnen chipsignale eben explizit in deinem programm selber erzeugen. du legst also erst an

1111 0011 ( Register F - CS0=0, ALE=0, /RD=1, /WR=1 )

dadurch hast du die adresse schon anliegen und die anderen chipsignale sind noch so, daß der chip sich nicht angesprochen fühlt. danach dann

1111 1011 ( Register F - CS=1, ALE=0, /RD=1, /WR=1 )

das sagt dem chip das er gemeint ist (normal hängt der ja mit x anderen an einem gemeinsamen bus und darf ja nur dann reagieren wenn sein register F gemeint ist und nicht das vom chip daneben ;) )
anschließend dann

1111 1111 ( Register F - CS=1, ALE=1, /RD=1, /WR=1 )

und gleich danach

1111 1011 ( Register F - CS=1, ALE=0, /RD=1, /WR=1 )

du hast also bei ALE einen positiven impuls herausgegeben und der chip übernimmt dadurch aus den ersten 4 bit die adresse des registers in einen internen zwischenspeicher..

jetzt kommt es drauf an, ob du das register lesen oder schreiben willst. falls lesen, dann ist dies der perfekte zeitpunkt um die ersten vier bit des ports auf eingang zu schalten - sonst hast du da noch die adresse vom register F anliegen und der chip gibt die daten auf deine ausgänge -> kurzschluß!

zzzz 1001 ( ersten vier bit auf eingang! - CS=1, ALE=0, /RD=0, /WR=1 )

nach der zeit "t pzv (R-Q)" liegen die gültigen daten an und du kannst sie aus den ersten vier bit des registers lesen..

=> zzzz einlesen

danach wird der lesezyklus abgeschlossen durch

zzzz 1011 ( Register F - CS=1, ALE=0, /RD=1, /WR=1 )

und weiter mit

zzzz 0011 ( wieder die ausgangssituation - ersten vier bit stehen jedoch noch auf eingang... )

0000 0011 ( ersten vier bit dürfen erst jetzt wieder auf ausgang geschaltet werden da jetzt erst die gefahr eines kurzschlusses vorbei ist )

das ganze funktioniert dann unter der voraussetzung, daß die zeiten aus dem diagramm eingehalten werden - also das die leitung ALE mindestens die zeit "tW (ALE)" lang auf high bleibt und so weiter... bei einer ansteuerung über software ist das VERMUTLICH nicht so kritisch - falls doch muß noch das ein oder andere NOP eingefügt werden.

so, dafür habe ich jetzt aber einen kaffee verdient! :P

_werwurm_
19.02.2008, 04:31
PortA5: ALE (??)

das signal steht für "Address Latch Enable" und bewirkt, daß die daten auf dem gemultiplexten adressen/datenbus als adressen erkannt und gespeichert werden.. dadurch braucht man weniger leitungen da sich adressen und daten den bus teilen können. bei 4 datenleitungen ist das noch nicht so dramatisch - bei acht oder sechzehn macht das bei der anzahl der pins an so einem gehäuse schon einen unterschied!

das nur so nebenher da das ganze gemultiplexe vermutlich der grund für deine verwirrung war schätze ich...

Actron
27.02.2008, 22:48
Hallo werwurm!

Echt super erklärt, so ist das mir schon einiges klarer. Paar Fragen hab ich aber doch noch. Also mein Code ist dann erstmal so:


/* PA0 bis PA7 auf Ausgang schalten */

PortA = 0b11110011; /* Adresse fuer Register F anlegen */
PortA = 0b11111011; /* Chip selektieren */
PortA = 0b11111111; /* Impuls Anfang: Adresse in int. Buffer uebernehmen */
PortA = 0b11111011; /* Impuls Ende */

/* Hier zum Lesen jetzt PA0 bis PA4 auf Eingang umschalten!!! */
...

PortA = 0b11111001; /* Read auf Low, warten bis Daten anliegen (siehe Diagram) */

/* Dann die Daten von PA0 bis PA3 auslesen */
daten = PortA; /* ersten vier Bit weiter isolieren... */

PortA = 0b11111011; /* Lesen abschliessen */
PortA = 0b11110011; /* Chip Select loesen */

/* Jetzt erst PA0 bis PA4 wieder auf Ausgang schalten */
PortA = 0b00000011;

Wie ist das mit dem zzzz aber gemeint?? PA0-PA3 auf Eingang ist mir klar aber bei dem Zuweisen an PortA kann ich ja nicht 0bzzzz0000 oder so machen. Muss das dann alles auf 1 oder 0 oder wie? Schätz ma 0 oder?

Und eigentlich muss ich erstmal in die Registers schreiben und nicht lesen, aber das versuch ich mir mal selbst herzuleiten und poste es noch mal hier. Muss ich dann wieder ein Impuls auf ALE geben zum Übernehmen der Daten? Also Addresse anlegen, ALE up + down, Daten anlegen und dann Write auf 0 nehm ich mal an (-> Diagramm). Also das Anlegen der Daten überschreibt die Adresse nicht irgendwie?


das nur so nebenher da das ganze gemultiplexe vermutlich der grund für deine verwirrung war schätze ich...
Ja genau das mit dem ALE und Adresse und Daten am selben Pin war bissl komisch. Glaub aber jetzt hab ichs verstanden wenn das mit dem zzzz noch mal wer erläutern kann.

Danke noch mal, meld mich mit dem Schreiben dann wieder.

mfg
Mika



ps: Zu den Timings ist noch diese Tabelle im Datenblatt. Mein Mikro hat 500 ns Taktzyklus dann ist nur das Chip Select kritisch oder? Also muss ich da dann ein delay einbauen, right?

_werwurm_
01.03.2008, 22:32
mit "zzzz" war nur gemeint, daß diese bits als eingang geschaltet sind (beim lesen sein MÜSSEN) und damit hochohmig ( high Z ). es spielt also in dem falle keine rolle was in das ausgangsregister an diesen bitstellen geschrieben wird da sie dann eh nur als eingang funktionieren. ich hätte quasi auch xxxx schreiben können = egal-da-eingang. ersetze sie einfach gedanklich durch nullen.. ;)

das schreiben der register ist in sofern einfacher, als das man dabei nicht auf eingang umschalten muß - es soll ja ausgegeben werden. das lesen schien mir wichtiger weil halt die gefahr besteht, daß man vergißt auf eingang zu schalten und damit der chip schaden nimmt. beim schreiben muß man nur zzzz durch registerdaten bzw. inhalt der in das register geschrieben werden soll ersetzen und natürlich darauf achten, daß man das bit für /RD auf LOW setzt und nicht das für /WR.

der impuls auf ALE ist nur nach dem anlegen der registeradresse nötig (beim lesen und beim schreiben - es muß ja das register so oder so ausgewählt werden). mit diesem impuls teilst du dem chip mit, daß an den ersten vier ausgängen gerade die registeradresse anliegt.

edit: wg. des timings - ich sage mal: ein NOP hier und da hat noch nie geschadet - wenn es nix lebenserhaltendes werden soll dann würde ich es einfach ausprobieren - wenn das timing zu knapp ist dann funktioniert es entweder unzuverlässig oder gar nicht mehr

Actron
13.03.2008, 00:02
Hallo!

Dachte ich habs verstanden aber komme doch nicht weiter. Hab mir zwei Funktionen read und write gemacht, damit ich die nur aufrufen brauch.


Erstmal der Code:

void write(unsigned char adr, unsigned char dat)
{
/* PortA ganz auf Ausgang */
(...)

/* Bits nach links hochschieben */
adr <<= 4;
dat <<= 4;

/* Adresse anlegen */
PortA = B00000011 | adr;

/* Chip Select */
PortA = B00001011 | adr;

/* ALE Impuls -> Adresse uebernehmen */
PortA = B00001111 | adr;
PortA = B00001011 | adr;

/* WR auf Low, Daten schreiben */
PortA = B00001010 | dat;

/* Schreiben abschliessen */
PortA = B00001011 | dat;

/* Chip Deselect */
PortA = B00000011 | adr;

/* alles auf Anfang */
PortA = B00000011;
}


Und Lesen:

unsigned char read(unsigned char adr)
{
unsigned char dat;

/* PortA ganz auf Ausgang */
(...)

/* Bits nach links hochschieben */
adr <<= 4;

/* Adresse anlegen */
PortA = B00000011 | adr;

/* Chip Select */
PortA = B00001011 | adr;

/* ALE Impuls -> Adresse uebernehmen */
PortA = B00001111 | adr;
PortA = B00001011 | adr;

/* WICHTIG: linken 4 Bits auf Eingang */
(...)

/* RD auf Low, Daten lesen */
PortA = B00001001 | adr;
dat = PortA >> 4;

/* Lesen abschliessen */
PortA = B00001011 | adr;

/* Chip Deselect */
PortA = B00000011 | adr;

/* PortA wieder ganz auf Ausgang */
(...)

/* alles auf Anfang */
PortA = B00000011;

return dat;
}

Also laufen tuts aber funktioniert leider nicht. :-( Und weil man nicht in den Chip reingucken kann, weis ich nicht so wirklich wo der Fehler sein könnte. Wär das so prinzipiell richtig?

mfg
Mika

_werwurm_
13.03.2008, 02:04
hmm sieht für mich erst mal ganz OK aus. ich vermute da steckt der teufel irgendwo im detail. wichtig: /CS0 des chips muß auf masse liegen (ist ein zweites chipselect).

man könnte jetzt ein paar NOPs einfügen - vielleicht ist der avr zu schnell. evtl muß man auch noch die pull-ups von port a einschalten?

wird denn immer das gleiche eingelesen? oder zufälliger "datenmüll"?

(ich habe noch nie einen avr programmiert - eine zweite meinung wäre also zu empfehlen ;) .. evtl. ist es etwas speziell mit dem avr oder port-a? ist port-a irgendwie doppelt belegt mit analogen sachen? AD-wandler oder comparator oder sowas?)

Actron
13.03.2008, 11:22
Hallo!


/CS0 des chips muß auf masse liegen (ist ein zweites chipselect).
Dh? Das board ist ja fertig, also muss es so gehen. Ist übrigens kein AVR sondern nen Freescale. Am PortA ist sonst nichts mit AD-Wanler oder so.

Also das Proggi hängt immer beim Lesen des Busy-Bit und da werden write/read aufgerufen. read gibt immer 0x0f zurück, glaub fast das Umschalten auf Eingang geht schief.

Das Datenrichtungreg. und das Datenreg. werden beide über PortA angesprochen man muss vorher im Controlreg. nur umschatlen. Für zzzz1011 oder so geb ich dann 0x0f auf den Port zum Umschalten auf Eingang. Das Rückschalten klappt dann wohl nicht so.

mfg
Mika

_werwurm_
16.03.2008, 00:02
hmm .. dann bin ich bissl ratlos. evtl. noch mal schauen ob 0x0f auch wirklich die oberen bits auf eingang und die unteren auf ausgang schaltet und nicht umgekehrt. ein oszilloskop wäre jetzt praktisch um zu schauen was sich an den eingängen tut. schau aber trotzdem noch mal wo der pin /CS0 des realtimeclock chips hinführt - vielleicht ist da noch ein portpin mit von der partie? oder ein jumper muß noch gesteckt werden oder sowas... ?!

edit:
wenn das ein fertiges board war gibt es ja vielleicht vom hersteller schon ein beispielprogramm? da könnte man schauen wie das gelöst ist...

Actron
19.03.2008, 21:24
Hallo! Läuft getz, ChipSel0 muss 0 sein nicht 1. Auf dem Diagram ist CS0 Quer (also mit diesem Strich drüber), also genau umgekehrt.


Noch mal DANKE für die Hilfe!!

mfg
Mika