Forum: Mikrocontroller und Digitale Elektronik Bits seriell einlesen und in Variable speichern.


von JB (Gast)


Angehängte Dateien:

Lesenswert?

Hallo!

Ich sag schonmal im Voraus, dass ich Anfänger bei Programmieren bin. 
Dies lässt sich natürlich am Anblick meiner Codes nicht verheimlichen.
Ich steh gerade vor einem Problem. Und zwar möchte ich Bits die seriell 
an einem Port meines Atmega32 einlesen und diese in einer 
Integervariable speichern. Das Bitmuster ist 8Bit lang. Z.B 11010110 und 
jedes Bit liegt etwa 500ms am Pin des Controllers an. Die Zeit ist noch 
nicht festgelegt wird sich aber in diesem Bereich befinden.
Ich weis nicht wie ich da anfangen soll. Ich hab mal was ganz verwirrtes 
ausprobiert, aber recht funktionieren tut es nicht und es ist auch sehr 
umständlich.
Gibt da irgendwelche Tricks bzw. bewährte Vorgehensweisen?
Ich hab im AVR Tutorial was zu Schieberegistern gelesen und da müsste es 
ja in die Richtung "Eingänge mit Schiebergister" gehen. Leider ist 
dieser Teil nur in Assembler und ich programmier in C (bzw. versuch in C 
zu programmieren).
Code müsste im Anhang sein.

Gruß
JB

von Peter D. (peda)


Lesenswert?

JB schrieb:
> jedes Bit liegt etwa 500ms am Pin des Controllers an.

Mit "etwa" wirst Du keinen Blumentopf gewinnen. Du wirst irgendeine 
Synchronisation (Taktflanke) benötigen.

Man muß nicht jedes Bit umständlich speichern. Man kann ganz profan die 
Variable um 1 schieben und das neue Bit oben (bzw. unten) hineinodern.

Schau mal nach SW-SPI.

von A. H. (ah8)


Lesenswert?

Schon mal nicht schlecht, aber deutlich verbesserungsfähig :-)

1. In C trägt das erste Element eines Feldes immer den Index 0.
2. Deine Feldinitialisierung initialisiert nur das erste Element des 
Feldes, welches Du dann aber gar nicht mehr benutzt.
3. Ohne guten Grund schreibt niemand 8x den gleichen Code, dafür gibt es 
Schleifen:
1
while(1)  //Endless loop
2
{
3
  _delay_ms(1000);
4
  for ( int i=0; i<8; ++i ) {
5
    bit =(PIND & 0x40) ? 1:0;  //PIND6 abfragen
6
    Telegramm[i]=bit;
7
    Telegramm[i]= Telegramm[i] << i;
8
    _delay_ms(500);
9
  }
10
}

4. Es gibt keinen Grund, alle Zwischenergebnisse in (extra) Variablen 
abzuspeichern:
1
for ( int i=0; i<8; ++i ) {
2
  Telegramm[i] = (PIND & 0x40 ? 0x01: 0x00 ) << i;
3
  _delay_ms(500);
4
}

5. Es gibt keinen Grund, die Bits einzeln in ein Feld zu speichern:
1
Daten = 0;
2
for ( int i=0; i<8; ++i ) {
3
  Daten |= (PIND & 0x40 ? 0x01: 0x00 ) << i;
4
  _delay_ms(500);
5
}

Das ist vielleicht noch keine optimale Lösung, soll aber erst mal 
genügen. Wozu Du die Endlosschleife brauchst, wenn Du ein Byte einlesen 
willst, verstehe ich noch nicht, auch nicht, warum Dein Feld Telgramm 
16 Element hat, warum die Variable Daten zu 0b01010101 initialisiert 
wird und wie die Eingabe überhaupt getriggert werden soll? (Will sagen: 
Woher weiß das Programm, wann es mit dem Einlesen beginnen soll?)

Vielleicht machst Du ja erst noch einige Programmierübungen am 
heimischen PC, bevor Du auf eine MC gehst. Bei Letzterem hast neben dem 
sicheren beherrschen der Sprachmittel noch einige andere Probleme zu 
bedenken.

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.