www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Wie programmier ich das elegant in C


Autor: Zerspannungsmechaniker (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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
unsigned char Read_Bus(void);
void         Write_Bus(unsigned char);
ohne viel Bitpopelei elegant schreiben?

Autor: Huch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> ... ohne viel Bitpopelei elegant schreiben?

Ich sags mal so: In dem Du weniger als viel Bitpopelei verwendest aber 
gerade soviel das es reicht. :-)

Autor: Huch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Zerspannungsmechaniker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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!

Autor: doch Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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...))

Autor: ... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja dann: Prost!

Autor: doch Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ahh, jetzt hab ich kapiert. Da will mal wieder jemand dass wir die 
Arbeit machen. So geht's natürlich auch.

Autor: Thomas Eckmann (Firma: Thomas Eckmann Informationst.) (thomase)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Joachim K. (minifloat)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Zerspannungsmechaniker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
[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
struct status {
  unsigned char b0:1;
  unsigned char b1:1;
  unsigned char b2:1;
  unsigned char b3:1;
  unsigned char b4:1;
  unsigned char b5:1;
  unsigned char b6:1;
  unsigned char b7:1;
};
mit einer struct machen könnte.

Autor: Floh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: doch Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zerspannungsmechaniker schrieb:

> Ich hatte gehofft, das man statt Bitpopelei da was in der Art
>
> struct status {
>   unsigned char b0:1;
>   unsigned char b1:1;
>   unsigned char b2:1;
>   unsigned char b3:1;
>   unsigned char b4:1;
>   unsigned char b5:1;
>   unsigned char b6:1;
>   unsigned char b7:1;
> };
> 
> 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.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Ästhet (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Stephan Henning (stephan-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wäre ein Bidi Treiber 245 nicht besser geeignet.

Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.
bitsD &= ((1 << PD3) | (1 << PD2));

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.