mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Schieberegister in C ansteuern


Autor: seacrash (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ein Hallo an alle,

Ich habe ein Problem mit folgendem Code Vision Code.



do{
          SR_counter++;
          SR = SR_counter / 8;
          SR_bit = SR_counter % 8;

          set_clk;

          clr_clk;

 } while(!((1<<SR_bit ) & (SR_array[SR])));


Diese do while Schleife soll in einem Schieberegister ( der Reihe nach
) genau dort  eine "1" schreiben, wo im SR_array eine "1" steht. Da
es sehr viele Schieberegister sind und nur eine "1" immer
durchgeschoben werden soll, verzichte ich auf ein vollständiges Update
und schiebe diese "1" nur durch.
Funktioniert auch soweit.
Jetzt das Problem:
Beim Ausführen des Codes wird jedoch genau an der Stelle (SR_array[SR])
das erste untere Halb Byte des Schieberegisters überschrieben.(Aus
zB.0b11110111 wird 0b11110000) Woher weiß ich das?
Wenn ich (SR_array[SR]) ersetzte mit z.B. 0b01010100 bleibt der Wert im
array erhalten, der vorher drin stand.
Bin ratlos und würde mich über eine Idee über die mögliche Fehler -
Ursache freuen.

Bis dahin Gruß

Autor: peter dannegger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"verzichte ich auf ein vollständiges Update  und schiebe diese "1"
nur durch."

Das geht nicht !

Wenn Du in der Schlange vorm Stones-Konzert stehst, darfst Du Dich ja
auch nicht vordrängeln.

Ein Schieberegister schiebt oder schiebt nicht. Was es schiebt, ist ihm
wurscht (Bits mit VIP-Ausweis gibt es nicht).


Hier mal ein einfaches SPI-Beispiel mit WINAVR:
#include <io.h>

#define SPI_PORT        PORTB
#define SPI_SCK         PB0
#define SPI_DOUT        PB1


void spi_out( unsigned char dat )
{
  unsigned char i;

  for( i = 8; i; i-- ){
    SPI_PORT &= ~(1<<SPI_DOUT);
    if( dat & 1 )
      SPI_PORT |= 1<<SPI_DOUT;
    dat >>= 1;
    SPI_PORT |= 1<<SPI_SCK;
    SPI_PORT &= ~(1<<SPI_SCK);
  }
}

Peter

Autor: seacrash (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Peter,

Danke für deine Antwort.

Vielleicht hab ich mich etwas undeutlich ausgedrückt. Natürlich schiebe
ich die "1" durch jedes Register, aber nur wenn eine 1 im Array steht,
wird es mit dem "store" clock an den Registerausgang durchgegeben.
Nach der von mir geposteten Schleife findet immer ein "store" statt.

Gruß

Autor: peter dannegger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"Vielleicht hab ich mich etwas undeutlich ausgedrückt."

Das ist aber stark untertrieben.


Schau Dir meinen Code an, der ist compilierbar.

Und nun schau Dir Deine paar Fitzelchen an, da ist überhaupt nichts mit
anzufangen.

Es kann doch keiner in Deinen Kopf gucken.


Peter

Autor: Profi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich verstehe auch nicht ganz, was Du willst (was bedeutet z.B.
"vollständiges Update").

Es geht auch etwas kompakter (hier mit 16 Bits):
  unsigned int i;
  for(i=0x8000;i;i&data?printf("1"):printf("0"),i/=2);
oder
  i=0x8000;do i&data?printf("1"):printf("0");while(i/=2);

oder andersherum schieben (hier mit 8 Bits):
  unsigned char i;
  for(i=1;i;i&data?printf("1"):printf("0"),i*=2);
oder
  i=1;do i&data?printf("1"):printf("0");while(i*=2);

Der Clou ist, dass i sowohl Bitmaske als auch Bit-"Zähler" ist.
Die Ende-Bedingung ist, dass das Bit "herausfällt", i also 0 und
damit false wird.
while(i*=2)  bewirkt sowohl das Schieben der Maske als auch die Prüfung
des Ergebnisses der Schiebung auf die Ende-Bedingung.

Ich liebe "high-density Code"...

@Peter:
Wwarum setzt Du das Port zuerst mal auf 0, um es dann bedingt wieder zu
setzen? wäre nicht besser:
    if( dat & 1 )
      SPI_PORT |= 1<<SPI_DOUT;
    else
      SPI_PORT &= ~(1<<SPI_DOUT);

-> Weniger unnötige Aktivität auf der Datenleitung
-> weniger Störungen
-> weniger Stromverbrauch durch Umladen

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.