Forum: Mikrocontroller und Digitale Elektronik SDCC Char in BIT


von Marek Swierzy (Gast)


Lesenswert?

Hallo zusammen,
ich programmiere 8051 µC und bin jetzt von ASM auf C umgestiegen.
Nun zu meinem Problem.

Ich möchte einen Wert in ein Schieberegister schreiben um später eine 7
- Segment LED anzusteueren.

mom. mache ich es auf die Folgende art :

   P2_4=0;   //CLK 0
   P2_3=0;   //BIT0
   P2_4=1;   //CLK 1

   P2_4=0;   //CLK 0
   P2_3=0;   //BIT1
   P2_4=1;   //CLK 1
    .....
   P2_4=0;   //CLK 0
   P2_3=0;   //BIT7
   P2_4=1;   //CLK 1

Mein Wunschdenken wäre ein folgender Code :

int count;  //Zähler
char wert;
wert = 01010101B ; //Ein Binärer Wert der Als char abgelegt wird
count=0;
while(count<8)
{
 P2_4=0;
 P2_3=wert[count]; //Das entsprechende Bit aus dem Wert
 P2_4=1;
}


Kann mir jemand bei diesem Problem helfen?
Ist dies realisierbar.
THX und MFG  + Guten Rutsch

Marek Swierzy

von Matthias (Gast)


Lesenswert?

Hi

unsigend char i;  //Zähler
unsigend char wert = 0x55;

for(i=0;i<8;i++)
{
   P2_4=0;
   if(wert&1) P2_3=1;
   else P2_3=0;
   P2_4=1;
   wert>>=1;
}

So geht das hardwareunabhängig. Je nach Compiler kann man aber evtl.
noch was optimieren um die if-Abfrage zu vermeiden.

Matthias

von Rufus T. Firefly (Gast)


Lesenswert?

unsigned char i;  //Zähler
unsigned char wert = 0x55;

for (i = 0; i < 8; i++)
{
   P2_4 = 0;
   P2_3 = (wert & (1 << i)) ? 1 : 0;
   P2_4 = 1;
}

So wird "wert" nicht zerstört, compilerabhängig ist's auch nicht.

von Matthias (Gast)


Lesenswert?

Hi

(1 << i) ist aber ein Ausdruck den man lieber nicht zur Laufzeit
auswerten will. Übliche 8 bitter haben keinen Barrel-Shifter was diesen
Ausdruck dann doch etwas langsam macht. Dann lieber eine zusätzliche
Variable anlegen in die man wert vorher reinkopiert.

Matthias

von Rufus T. Firefly (Gast)


Lesenswert?

"Übliche 8-Bitter"? Welche?

Im AVR-Befehlssatz (jedenfalls des Mega128) gibt es die Befehle LSR und
LSL - beide benötigen einen Taktzyklus.

Der MCS51 hat zwar keinen Shift-, dafür aber einen Rotate-Befehl, und
der benötigt 12 Takte, was einem "Instruction Cycle" dieses
hocheffizienten Prozessorkerns entspricht.

Der von mir früher verwendete 6809 kann sowas natürlich auch, aber der
ist - wenn auch mit dem HC11 nah verwandt - kein Microcontroller.

Dennoch kann ich das Argument der Langsamkeit nicht nachvollziehen.

von Matthias (Gast)


Lesenswert?

Hi

die 1 wird bei jedem Schleifendurchlauf um einen anderen Wert
geshiftet. Zuerst 0 dann 1 usw. D.h. beim letzten Schleifendurchlauf
muß die 1 erst 7 mal geshiftet werden. Das ist alles aber nicht
effektiv.

Mit einem Barrel-Shifter meine ich keineswegs die simplen
Rotations/Shift-Befehle der üblichen 8-Bitter sondern eben einen
Barrel-Shifter der solche Verschiebungen effektiv in einem Takt (egal
ob 1, 4 oder 7 Stellen) erledigt.

Matthias

von Rufus T. Firefly (Gast)


Lesenswert?

Ah, Du hast recht. Das ist sowohl beim MCS51 als auch dem AVR in der Tat
so. Wie primitiv.

Der letzte Prozessor, den ich gewissermaßen im Schlaf in Assembler
programmiert habe, ist der von mir hochgeschätzte 6809, der kann in
einem Befehl ein 8-Bit-Register um mehr als ein Bit verschieben und
braucht dafür je nach Adressierungsart zwei oder mehr Taktzyklen.

Naja, das Gute setzt sich bekanntlich nicht durch, sonst hätte es
x86-PCs nie gegeben - und der 6809, der immerhin 1979 auf den Markt
kam, wäre mehr Leuten bekannt.

Ich würde nun - gerade als C-Anfänger - aber sowieso davon Abstand
halten, AVRs in C zu programmieren (Harvard-Architektur mit getrennten
RAM- und ROM-Adressräumen, was vom C-Compiler kaum unterstützt wird).

von Marek Swierzy (Gast)


Lesenswert?

Eine direkte Umwandlung von Bit nach CHAR ist nicht möglich ?
Wäre nice wenn dies gehen würde, oder ist dass nur über ein Strukt
realisierbar ?

von Rufus T. Firefly (Gast)


Lesenswert?

Es geht ja gar nicht um eine Umwandlung von Bit nach Char, sondern
darum, eine Art Software-SPI zu realisieren.

In Assembler ist das natürlich kein Problem, und ein brauchbarer
C-Compiler wird das möglicherweise auch anständig hinoptimieren können,
wobei die von Mathias angeratene Variante (Wert kopieren und dann darauf
den ursprünglichen Algorithmus anwenden, der die Kopie zerstört) vom
Compiler am besten interpretiert werden dürfte.

von Marko B. (Gast)


Lesenswert?

Hmm ... weiß jemand, unter welchen Umständen ein C Compiler
Rotate-Instruktionen benutzt, bzw. wie man ihn dazu bringt, es zu tun?

Zur Not kann man natürlich auch Inline Assembler ins Programm einbauen.
Aber bei einer 7-Segment Ansteuerung ist es auch wurscht, ob die Routine
100 oder 150 Takte braucht, denn sie wird ja höchstens (ein 4-stelliges
Display vorausgesetzt) alle 2,5ms aufgerufen.

Übrigens würde ich nicht "einfach so" C einsetzen. Bei kleineren
Sachen ohne komplexe Funktionen/Berechnungen, wo nur mit ein paar Bits
jongliert wird, ist Assembler oft die bessere Wahl.

von Marek Swierzy (Gast)


Lesenswert?

Das ist mir schon aufgefallen.
Ich Programmmiere seid 3 Jahren C/C++ aber diese Routinen sind mir
nicht  bekannt wo findet man informationen darüber ?

von Rufus T. Firefly (Gast)


Lesenswert?

@Marek: Was magst Du mit "diese Routinen" meinen?
In der Diskussion ging es um die Umsetzung von C-Konstrukten in
Maschinenbefehle verschiedener Prozessoren, die - je nach Typ - das
eine oder andere nicht können, so daß es aufwendig mit mehreren
Befehlen implementiert werden muss.
Hilfreich beim Verständnis ist daher Wissen über den
Assemblerbefehlssatz des verwendeten Prozessors.

von DerMax (Gast)


Lesenswert?

Grundsatzdikussion olé! :)

>Übrigens würde ich nicht "einfach so" C einsetzen. Bei kleineren
>Sachen ohne komplexe Funktionen/Berechnungen, wo nur mit ein paar
Bits
>jongliert wird, ist Assembler oft die bessere Wahl.

Warum? Eine LED blinken lassen kann man auch in C. Der einzige für mich
nachvollziehbare Grund ASM zu verwenden ist die größere Performance,
bzw. die wesentlich effizientere Speichernutzung. So lange man genug
Flash-Kapazität und CPU-Power zur Verfügung hat ist C sicherlich nich
schlecht als Assembler.
Jeder wie er kann und will halt :)

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.