Forum: Mikrocontroller und Digitale Elektronik shift_left()?


von Helmut K. (Gast)


Lesenswert?

Hallo ich hab da ei kleines Problem ich benutze den C18 Compiler und 
beötige eine funktion vom CCS-Compiler.

Ich komme irgendwie nicht alleine daruf??

shift_left(address,bytes,wert);

Die Funktion verschiebt ein Bit in einem Array oder Struktur nach links. 
address kann ein Array oder eine Adresse zu einer Struktur (z.B. wie 
&data). bytes gibt an, mit wievielen Bytes gearbeitet. wert gibt den 
Inhalt des Bits an, entweder 0 oder 1.

Hier noch ein Beispiel zur Anwendung:

byte buffer[3];
for (i=0;i<=24;++i) {
// Wait for clock high
while (!input(PIN_A2));
shift_left(buffer,3,INPUT(PIN_A3));
// Wait for clock low
while (input(PIN_A2));
}
// reads 24 bits from pin A3, each
// bit is read on a low to high on pin // A2

Kann mir jemand die Funktionsbeschreibung geben??

Besten Dank im vorraus
MfG Helmut

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Also ich weiß nicht wie man das in C macht das man das Carry 
reinschiebt.
Aber im Prinzip wird hier nur buffer einmal nach Links geschoben (jedes 
byte einmal deshalb die 3) und beim ersten byte eine 1 oder 0 
reingeschoben.

Ich würde das einfach so umschreiben:
1
int buffer = 0;
2
for (i=0;i<=24;++i) {
3
 // Wait for clock high
4
 while (!input(PIN_A2));
5
 buffer = (buffer << 1) | INPUT(PIN_A3));
6
 // Wait for clock low
7
 while (input(PIN_A2));
8
}
ggf könnte man auch ne Union nutzen wenn man auf die einzelnen bytes 
zugreifen will.

von Karl H. (kbuchegg)


Lesenswert?

Da du in C an das Carry Bit des Prozessors so nicht
vernünftig ran kommst, muss man das in Software simulieren
1
void shift_left( byte* address, size_t bytes, byte wert )
2
{
3
  size_t i;
4
  byte Carry;
5
  byte PrevCarry = ( Wert != 0 );
6
7
  for( i = 0; i < bytes; ++i )
8
    Carry = adress[i] & 0x80;    // dieses Bit wird rausfallen, also
9
                                 // sichern, damit es beim nächsthöheren
10
                                 // Byte eingesetzt werden kann
11
    adress[i] <<= 1;
12
    adress[i] |= PrevCarry;
13
14
    PrevCarry = ( Carry != 0 );
15
  }
16
}

Eine andere Möglichkeit wäre beim Höchstwertigen Byte mit der
Schieberei anzufangen. Hier sind 2 Fälle zu unterscheiden:
Das höchstwertige Byte wird einfach nur geschoben. Was links rausfällt,
fällt raus. Bei allen anderen Bytes wird das Bit 7 in das nächsthöhere
Byte übertragen.
1
void shift_left( byte* address, size_t bytes, byte wert )
2
{
3
  size_t i;
4
5
  adress[ bytes - 1 ] <<= 1;    // Höchstwertige Byte schieben
6
7
  for( i = bytes - 1; bytes > 0; --i ) {
8
                                // muss eine 1 vom Bit7 zum Bit0 eine
9
                                // Stelle höher übertragen werden?
10
    if( adress[ i - 1 ] & 0x80 != 0 )
11
      adress[ i ] |= 0x01;
12
13
                                // dieses Byte jetzt um 1 Position schieben
14
    adress[ i - 1 ] <<= 1;
15
  }
16
17
  if( wert )
18
    adress[0] |= 0x01;
19
}


Disclaimer: Ich habe keine der Funktionen getestet. Sie sollten aber
zumindest keine gravierenden Fehler aufweisen.

von Simon K. (simon) Benutzerseite


Lesenswert?

In dem ersten Code fehlt eine geschweifte geöffnete Klammer nach <for>

von Karl H. (kbuchegg)


Lesenswert?

Simon K. wrote:
> In dem ersten Code fehlt eine geschweifte geöffnete Klammer nach <for>

Merci.
Hätte es doch durch den Compiler laufen lassen sollen :-)

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.