Ich habe hier diesen Schaltplan gemacht.
Ich nenne das mal einen Bus-Koppler bis mir ein besserer Name einfält.
Mit dem 74HC245 kann ich ein Byte vom ATmega8 auf den rechten Bus
transportieren. (Write_Bus)
Mit dem 74HC574 kann ich von dem rechten Bus ein Byte zum ATmega8
transportieren. (Read_Bus)
Die CPU auf dem rechten Bus ist der Master, er steuert alle Funktionen.
Der ATmega8 ist nur der Slave.
Ich brauche von dem ATmega8 PD0(RxD) und PD1(TxD) für eine RS232
Schnittstelle. PB6 und PB7 brauche ich für den Quarz.
Deshalb sind die Bits der Bytes schön auf Port B, C und D verteilt.
Im Platinen-Layout sieht das aber ganz gut aus ;-)
Wie kann ich in C die beiden Funktionen
Eine andere Antwort: Nimm Dir als erstes nicht Eleganz zum Ziel sondern
die Funktion. Hauptsache Du verstehst wie es funktioniert und es geht.
Die "Eleganz", wie immer man das definiert, kommt dann mit den Jahren.
Huch schrieb:> Nimm Dir als erstes nicht Eleganz zum Ziel sondern> die Funktion.
Um die Wahrheit zu sagen, ich kriege die Bitpopelei überhaupt nicht hin.
Ich geh jetzt und sauf mich zu!
Huch schrieb:> Eine andere Antwort: Nimm Dir als erstes nicht Eleganz zum Ziel sondern> die Funktion. Hauptsache Du verstehst wie es funktioniert und es geht.> Die "Eleganz", wie immer man das definiert, kommt dann mit den Jahren.
Sehr richtig, zumal C gerade für "Bitpopeleien" sehr gut geeignet ist.
(Das heisst aber nicht dass C nur für solche Sachen gut ist! (Nur
dass jetzt keiner ankommt...))
Warum du die Daten nicht einfach in den USART deines Host-Controllers
schreibst, will ich jetzt gar nicht wissen.
Aber das, was du da bauen willst, wird so nie funktionieren. Denn woher
soll der Client wissen, daß gültige Daten am Port anliegen?
Woher soll der Host wissen, daß der Client Daten für ihn hat?
Ein Bus benötigt immer Steuerleitungen. In deinem Fall Strobe und
Busy/Acknowledge für jeweils beide Busse.
Um nochmal auf meinen ersten Satz zurückzukommen: Lass' den Quatsch und
nimm den USART vom Host. Ist wesentlich weniger aufwendig und schneller.
mfg.
So geht das nicht.
Schau Dir mal den 74HC646 an, der ist dafür gedacht.
Ich würde allerdings keine 2 MCs so koppeln. Reichen denn die 4 UARTs
des ATmega2560 nicht?
Peter
Warum nicht mit Port C und B direkt auf den Bus gehen?
Oder einer sonstigen Kombination aus den Ports, um dann INT0 und INT1
freizuhalten, welche dann als ¬READ und ¬WRITE fungieren.
Oder einen Mega48/88/168 hernehmen, der beherrscht Pinchange-Interrupts
auf allen Pins. Oder sind 20MHz bzw. die entsprechenden Zeiten, um in
die Interruptroutine zu springen, zu langsam?
Fragen nebenher:
Wieviele Takte braucht man zum Program Counter ablegen und Sprung?
Nach wievielen Takten bin ich in der Routine drin?
mfg mf
PS: Bitpopelei sehr gut im AVR-GCC-Tutorial beschrieben.
[IRONIE]
Danke für die Hilfe.
[/IRONIE]
Ich baue für ein über 20 Jahre altes Gerät ein nicht mehr lieferbares
Interface quasi nach.
Ich hatte gehofft, das man statt Bitpopelei da was in der Art
Zerspannungsmechaniker schrieb:> Ich brauche von dem ATmega8 PD0(RxD) und PD1(TxD) für eine RS232> Schnittstelle. PB6 und PB7 brauche ich für den Quarz.> Deshalb sind die Bits der Bytes schön auf Port B, C und D verteilt.
Ja klar. Ein bisschen nachschauen was man eigentlich braucht und man
würde z.B. einen mega16 nehmen. Der hat mehrere komplette (!)
8-Bit-Ports. Das würde sich die ganze Bitschieberei auf Null reduzieren.
Wo ist das Problem???
Bitmanipulation in diesem Ausmaß ist selbst in Assembler Kinderkram.
uint8/16/32, ein paar Shifts, UND, ODER, ggf. noch XOR und NOT, fertig.
> mit einer struct machen könnte.
ist genauso Bitpopelei
Wo liegt den das Problem.
Schreib dir deine Ausgangslage hin
PD3 PD2 PC5 PC4 PC3 PC2 PC1 PC0
und überleg dir welche Bitblöcke du beim Einlesen wie schieben musst,
damit genau diese Bitfolge rauskommt. Ist doch kein wirkliches Problem.
Du liest von PIND ein, dann hast du
PD7 PD6 PD5 PD4 PD3 PD2 PD1 PD0
interessiert (in Ergebnis nachsehen) bist du an PD3 und PD2. Also setzt
du gezielt erst mal alle anderen Bits auf 0. Dann hast du
0 0 0 0 PD3 PD2 0 0
Jetzt schaust du wieder aufs Ergebnis und vergleichst. Wenn du dein
0-gesetztes Zwischenergebnis um 4 Stellen nach links schiebst, sind die
beiden Bits dort wo sie sein sollen.
PD3 PD2 0 0 0 0 0 0
und sind fertig um ins Ergebnis übernommen zu werden.
Und jetzt im ganzen C-Satz:
uint8_t bitsD = PIND;
bitsD &= ~( 1 << PD3 | 1 << PD2 ); // auf 0 setzen
bitsD <<= 4;
fertig zum Zusammenführen mit den Bits vom C-Port.
Beim Schreiben genau anders rum. Du hast 8 Bit und musst du nach diesem
Schema auf die Portbits verteilen. Auch da gibt es wieder Bitblöcke die
gemeinsam behandelt werden können.
Zerspannungsmechaniker schrieb:> Ich baue für ein über 20 Jahre altes Gerät ein nicht mehr lieferbares> Interface quasi nach.
Bevor Du anfängst zu programmieren, denke erstmal über das Timing nach.
Wenn der AVR memory mapped dran hängt, muß er ja die Lese- und
Schreibzeiten einhalten können. Es könnte also ein CPLD oder FPGA
notwendig werden.
Vermutlich brauchst Du auch noch einige Adreßleitungen, d.h. es wird
knapp mit den Pins des ATmega8.
Peter
Nur, weil der Thread sowieso von 'Eleganz' handelt:
Dein Schaltplan wäre wesentlich eleganter, wenn du für die beiden HC574
die Funktionen Rotate und Mirror benutzt hättest.
Karl heinz Buchegger schrieb:> bitsD &= ~( 1 << PD3 | 1 << PD2 ); // auf 0 setzen
Wenn die Bits PD3 und PD2 interessieren, dann sollte man die lieber
nicht auf 0 setzen. Also ist das Komplement zu viel.