Daniel S. schrieb:
> hab den alten Code kopiert -.-
Ja.
Aber du hast zu hastig gearbeitet. Mehr Sorgfalt!
Du musst mehr oder weniger bei jeder Anweisung überlegen, ob ein int
(also 16 Bit) dafür ausreicht.
> void ioinit(void);
> void output_led_state(unsigned long long int __led_state);
tu dir selbst einen Gefallen und schreibt uint64_t und nicht unsigned
long long.
Zum einen ist das kürzer zu schreiben zum einen kann dann ein Blinder
aus 3 Meter Entfernung erkennen, dass du auf einen Dtaentyp mit 64 Bit
aus bist.
> for (int i=35;i>=0;i--)
Wenn du nett zu deinem µC sein möchtest, dann passe die Datentypen auf
den Wertebereich an. Je kleiner desto besser.
Für einen int, der nur Werte von 0 bis 35 annehmen kann, tuns auch 8
Bit. Das muss dann kein voll ausgewachsener int mit 16 Bit (auf einem
AVR) sein.
for (int8_t i = 35; i >= 0; i-- )
> void output_led_state(unsigned long long int __led_state)
> {
...
> if ((_BV(i) & __led_state) == _BV64(i)) //bit_is_set doesn’t work
> on unsigned int so we do this instead
Und das erste _BV kann dir keine Überläufe erzeugen, wenn i größer als
15 ist?
Im Übrigen solltest du dir solche Abfragen gleich wieder abgewöhnen. Die
Denkweise in C ist: Entweder etwas ist 0, dann ist es logisch FALSE.
Oder es ist nicht 0, dann ist es logisch TRUE
if( __led_stat & _BV64(i) )
macht genau das gleiche, ist aber einfacher zu schreiben und weniger
fehleranfällig, weil du nicht aufpassen musst, was links vom ==
heruaskommt um die rechte Seite korrekt zu formulieren.
Und noch was:
Variablennamen lässt man nicht mit __ beginnen.
Alle Namen, die mit
_ und einem Grossbuchstaben
oder __
sind nämlich für den Compiler und dessen System-Header Files reserviert.
Für dich als Anwendungsprogrammierer bleiben da noch genug andere
Möglichkeiten übrig, dir Schemata für Variablennamen auszudenken. Es
muss nicht wirklich ein Beginn mit __ sein.