Forum: Mikrocontroller und Digitale Elektronik Bei 8Bit Erkennung von 2Bit wechsel.


von Nacho (Gast)


Lesenswert?

Hallo,

ich stehe vor folgendem Problem...

Ich habe 24Bit die ich ab intr X polle (4x 8Bit ATMEGA16 PORTA,B,C) und 
möchte bei jedem der 8Bit einen wechsel von 2Bit feststellen können.

Meine Kenntnisse in C reichen leider nicht sehr weit für eine "elegante" 
Lösung und würde es bisher wie folgt versuchen...

int ME_Alert (int leg1_sav, int leg2_sav, usw...)
{
int i;
i=0;
  while (PD2 == 0 & i<=2)
  {
  if (LEG1_STATUS = leg1_sav) {}
    else{i++}
  if (LEG2_STATUS = leg2_sav) {}
    else{i++}
  if (LEG3_STATUS = leg3_sav) {}
    else{i++}
  if (LEG4_STATUS = leg4_sav) {}
    else{i++}
  }
return i;
}

wobei
#define LEG1_STATUS  (PINA & 0xFC)
#define LEG2_STATUS  ((PINA & 0x03) | (PINB & 0x0F))
#define LEG3_STATUS  ((PINB & 0xF0) | (PINC & 0xC0))
#define LEG4_STATUS  (PINC & 0x3F)

Danke vorab für Eure hilfe!!!

Gruß Nacho

von LordZiu (Gast)


Lesenswert?

1) Code Tags benutzen!
2) if(a = b) ist an dieser Stelle falsch, da es eine Zuweisung ist. (a 
== b) ist hier richtig.
3)
1
 if (LEG1_STATUS = leg1_sav) {}
2
    else{i++}
3
4
// besser, schneller, übersichtlicher ist
5
if(LEG1_STATUS != leg1_sav) 
6
{
7
    i++;
8
}

4) So richtig verstehe ich nicht, was du erreichen willst. Willst du 
LEG1_STATUS mit einem anderen Bitmuster prüfen?

von LordZiu (Gast)


Lesenswert?

Hab ich eben noch übersehen:
1
while ((PD2 == 0) && (i<=2))

Ein &-Zeichen ist eine binäre Verknüfpung. Zwei &-Zeichen ist eine 
logische Verknüpfung.

von Rolf Magnus (Gast)


Lesenswert?

> Hab ich eben noch übersehen:
> while ((PD2 == 0) && (i<=2))
>
>
> Ein &-Zeichen ist eine binäre Verknüfpung. Zwei &-Zeichen ist eine
> logische Verknüpfung.

Außerdem ist PD2 eine Konstante, die den Wert 2 hat, wird also sowieso 
niemals gleich 0 sein.

von Nacho (Gast)


Lesenswert?

Zunächst mal danke für die Hinweise Lordziu...

Zu deiner Frage wo ich hin möchte...

Ich frage vor dem pollen einmalig den Status meiner DIs ab. Der Wert 
wird in legx_sav abgelegt. jedes "leg" soll nun nachher mit seiner 
legx_sav verglichen werden.
Beim pollen möchte ich feststellen, ob bei legx_status gegnüber legx_sav 
kein, ein, zwei oder mehrere Bits geflippt sind...

Wenn zwei oder mehr Bits pro legx ihren wert geändert haben soll wird 
Funktion Y ausgeführt werden...

Mein Hauptproblem ist wie gesagt das feststellen wieviele bits gegenüber 
dem abgesicherten wert geflippt sind...

Als Bsp.:
angenommen logx_sav = 0b00010100

1. Abfrage ergibt:
logx_status = 0b01010100    //1Bit... Ohne Auswirkungen

2. Abfrage ergibt:
logx_status = 0b01010101    //2Bit... Funktion Y ausführen

Verständlicher? :)

Gruß Nacho

von spess53 (Gast)


Lesenswert?

Hi

Exclusive-Or. Und dann Bits Zählen. In Assembler kein Problem.

MfG Spess

von LordZiu (Gast)


Lesenswert?

spess53 schrieb:
> In Assembler kein Problem.

In C auch nicht ^^ (nur halt ein bisschen langsamer)

von Drachenbändiger (Gast)


Lesenswert?

>> In Assembler kein Problem.
>
> In C auch nicht ^^ (nur halt ein bisschen langsamer)
Ja, vielleicht so  ;-))
1
#include <inttypes.h>
2
3
// bla...bla..code..code
4
5
uint8_t number=ui8; // Byte, von dem wir wissen wollen,
6
                        // wie viele Bits gesetzt sind
7
uint8_t count=0;    // Anzahl der Bits in "ui8"
8
9
/* dann irgenwo: */
10
    asm volatile ( 
11
                    "ldi r16,8              \n\t"
12
                    "mov __tmp_reg__, %1    \n\t"
13
                    "clr %0                 \n\t"
14
                    "L_0:" "rol __tmp_reg__ \n\t"
15
                    "brcc L_1               \n\t"
16
                    "inc %0                 \n\t"
17
                    "L_1:""dec r16          \n\t"
18
                    "brne L_0               \n\t" 
19
                    :"=&r" (count)
20
                    :"r" (number)
21
                    :"r16"
22
                );

Natürlich ohne Gewähr. Ginge vielleicht auch unter Umgehung der 
"mov"-Zeile, aber ich habe mit dem Inlne-Assembler wenig Übung und bin 
da eher vorsichtig.

von Martin V. (oldmax)


Lesenswert?

Hi
Da ich kein C kann, ( noooch niicht) mal kurz, wie's gehen sollte
Wert_alt XOR Wert_Neu -> Ergebnis gewechselte Bits
Wert_alt AND Gewechselte Bits -> Flanke nach 0 / zwar nicht gefragt
Wert_Neu AND  Gewechselte Bits -> Flanke nach 1/ dto
Gewechselte Bits schieben und Carry-Flag abfragen, bei Carry Zähler 
Incrementen..
Sollte in jeder Sprache umsetzbar sein.
Gruß oldmax

von Drachenbändiger (Gast)


Lesenswert?

> Wert_alt XOR Wert_Neu -> Ergebnis gewechselte Bits
... nicht nötig
> Gewechselte Bits schieben und Carry-Flag abfragen, bei Carry Zähler
> Incrementen..
Letzteres ist genau, was mein Inline-Assembler-Programm (s.o.) macht.

von Drachenbändiger (Gast)


Lesenswert?

War vielleicht unklar: Das "nicht nötig" oben bezog sich auf die 
Schritte 2 und 3 im Ablauf, den oldmax vorgeschlagen hatte.

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.