Forum: Mikrocontroller und Digitale Elektronik Array konvertierung in C


von Johannes M. (jojo20)


Lesenswert?

guten abend,

ich möchte in einem AVR in GCC programmiert eine Lampenmatrix aus 8x8 
ansteuern.

Dazu habe ich das Array uint_8t Kette[8] definiert.

nun möchte ich mit einer Funktion bequem einzelne Lampen ansteuern und 
habe mir dazu folgende Funktion geschrieben:

void lampe_ein(uint8_t lampennummer)
{
  uint8_t puffer[2]={0};
  puffer[1] = lampennummer % 100 / 10;
  puffer[0] = lampennummer % 10;


  kette[puffer[1]] |= (1 << puffer[0]);

}

Ich möchte also z.b. als Lampennummer 74 übergeben und die funktion soll 
in Kette[7] Bit 4 setzen bzw. die gegenteilige Funtion das Bit löschen.

Leider funktioniert die Funktion nicht wie erwartet. Es wird die falsche 
bitnummer geschrieben und es wird wohl das ganze Byte bearbeitet, obwohl 
ja nur ein Bit gesetzt werden soll.

Was habe ich hier falsch gemacht? Ich komme nicht drauf.

Beitrag #6467924 wurde vom Autor gelöscht.
von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Johannes M. schrieb:
> Ich möchte also z.b. als Lampennummer 74 übergeben
Von woher? Über welche Schnittstelle? Binär oder ASCII?
> und die funktion soll
> in Kette[7] Bit 4 setzen bzw. die gegenteilige Funtion das Bit löschen.
Ein Gendanke dazu: du musst dein Programm nur 1 mal ausdenken und 
schreiben.
Der µC muss es hinterher laufend immer wieder wiederholen und sehr oft 
ausführen. Wenn man sich das überlegt, dann könnte man auf die Idee 
kommen, es dem µC möglichst einfach zu machen.

Nun hast du zwar 10 Finger und findest dich deshalb in der Welt der 
Zehnerpotenzen super zurecht. Ein Mikrocontroller ist aber ein zutiefst 
binäres Bauteil und fühlt sich in Zweierpotenzen super wohl.
Wenn du dir dann also ein Format ausdenkst, das es dem µC leicht macht, 
dann dankt er es dir mit schneller Programmausführung...  ;-)

Johannes M. schrieb:
> puffer[1] = lampennummer % 100 / 10;
> puffer[0] = lampennummer % 10;
Divisionen und Modulo-Operationen sind aber eben nicht gerade bekannt 
dafür, dass sie dem µC Arbeit abnehmen. Und du bauchst diese Operationen 
hier nur, weil du da ein ungeeignetes Format hast.
Ich würde da z.B. statt dezimal 74 einfach binär 0x74 übergeben und 
dann sähe meine Zuweisung so aus:
puffer[1] = lampennummer >> 4;
puffer[0] = lampennummer & 0xf;
Hübsche, pfeilschnelle binäre Operationen allein durch die Wahl eines 
µC-geeigneten Formats.

Johannes M. schrieb:
> Es wird die falsche bitnummer geschrieben und es wird wohl das ganze
> Byte bearbeitet, obwohl ja nur ein Bit gesetzt werden soll.
Woran siehst du das?

: Bearbeitet durch Moderator
von (prx) A. K. (prx)


Lesenswert?

Bei 8x8 könnte man glatt auf die Idee kommen, Oktal statt Hex zu 
verwenden.

von OR (Gast)


Lesenswert?

Johannes M. schrieb:
> und es wird wohl das ganze Byte bearbeitet, obwohl
> ja nur ein Bit gesetzt werden soll

Natürlich werden da alle Bits mit der Bitmaske verodert.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Johannes M. schrieb:
> Was habe ich hier falsch gemacht?
Da stimmt irgendwas anderes nicht, denn da gehts:
https://onlinegdb.com/Hy483DEtP
Bit 4 im letzten Byte 7 ist gesetzt.

Und hier dann noch meine Version mit dem flotten 0x74:
https://onlinegdb.com/BJ64pw4tD
Selbes Ergebnis...

: Bearbeitet durch Moderator
von Johannes M. (jojo20)


Lesenswert?

Danke schonmal für eure Hilfe, hier mal das volle Programm so konnte ich 
mit dem Tipp des online Compilers den Fehler finden aber noch nicht 
lösen.

Es sollen im Wechsel 2 Lampen geschaltet werden (je nach Status von 
"flankesekunde", aber das funktioniert noch nicht. Das abschalten 
scheint "dominant" zu sein.

https://onlinegdb.com/BJMvhKrFD

Habt ihr evtl. nochmal einen Tipp für mich?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Johannes M. schrieb:
> Das abschalten scheint "dominant" zu sein.
Du solltest vorneweg den Merker für den "alten" Zustand speichernd 
machen, sonst kannst du keine Flanke erkennen:
static uint8_t flanke_temp=0;

> Das abschalten scheint "dominant" zu sein.
Wie meinst du das?
Was möchtest du sehen und was siehst du stattdessen?

von Johannes M. (jojo20)


Lesenswert?

Der zustand von flankesekunde ändert sich bei mir sekündlich erzeugt 
durch ein Interrupt im UC.

Die While Schleife ist im echten Programm dauerhaft bis eine Taste 
gedrückt wurde.

Also sollte das Byte 7 von 0b00010000 auf 0b00100000 sekündlich 
wechseln.

Tut es aber nicht.

Selbst online erhalte ich entweder 0x10 oder 0x00 je nach Zustand von 
flankesekunde. Also scheint es so, das Lampe aus nicht nur das Bit im 
Byte löscht das beabsichtigt ist, sondern alle?!

von Johannes M. (jojo20)


Lesenswert?

Kommand zurück, ich habe den Fehler gefunden. Ich habe einen Watchdog 
(Fehlt im Beispielprogramm) an der falsche stelle getriggert. Dadurch 
wurde die Ausgabe gesperrt.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Johannes M. schrieb:
> hier mal das volle Programm
Johannes M. schrieb:
> im echten Programm
Johannes M. schrieb:
> einen Watchdog (Fehlt im Beispielprogramm)
Johannes M. schrieb:
> Habt ihr evtl. nochmal einen Tipp für mich?
Ja, einen hab ich noch: poste fürderhin genau den Code, der den Fehler 
macht.
Kontrolliere vor dem Absenden, ob genau dieser Code auch genau diesen 
Fehler macht.

: Bearbeitet durch Moderator
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.