Forum: Mikrocontroller und Digitale Elektronik Assembler: Benötige Hilfe


von Flo (Gast)


Lesenswert?

Hallo,

ich habe folgende Funktion (geklaut von 
https://github.com/strawberryhacker/led-strip-driver - unnötige 
"#if"-Teile entfernt, damit das hier nicht zu lang wird.
1
void __attribute__((noinline)) update_led_strip(color* colors, uint16_t number_of_leds)
2
{  
3
  LED_PORT.DIRSET = (1 << LED_PIN);
4
  uint8_t* led_strip_port_pointer;
5
  led_strip_port_pointer = (uint8_t*)(&LED_PORT);
6
  
7
  uint8_t pin = (1 << LED_PIN);
8
9
  cli();
10
  while(number_of_leds--)
11
  {
12
    asm volatile(
13
    
14
    //send red component
15
    "ld    __tmp_reg__,  %a0+    \n\t"
16
    "ld    __tmp_reg__,  %a0      \n\t"
17
    "rcall  send_byte%=          \n\t"
18
    
19
    //send green component
20
    "ld    __tmp_reg__,  -%a0    \n\t"
21
    "rcall  send_byte%=          \n\t"
22
    
23
    //send blue component
24
    "ld    __tmp_reg__,  %a0+    \n\t"
25
    "ld    __tmp_reg__,  %a0+    \n\t"
26
    "ld    __tmp_reg__,  %a0+    \n\t"
27
    "rcall  send_byte%=          \n\t"
28
    "rjmp  asm_end%=          \n\t"
29
30
    //send byte subroutine
31
    "send_byte%=:            \n\t"
32
    "rcall  send_bit%=          \n\t"
33
    "rcall  send_bit%=          \n\t"
34
    "rcall  send_bit%=          \n\t"
35
    "rcall  send_bit%=          \n\t"
36
    "rcall  send_bit%=          \n\t"
37
    "rcall  send_bit%=          \n\t"
38
    "rcall  send_bit%=          \n\t"
39
    "rcall  send_bit%=          \n\t"
40
    "ret                \n\t"
41
42
    //send bit subroutine
43
    "send_bit%=:            \n\t"
44
    
45
    "rol  __tmp_reg__          \n\t"
46
    //set outout high
47
    "std  Y+5,  %[led_strip_pin]  \n\t"
48
    "brcs  .+2              \n\t"
49
    //set outout low
50
    "std  Y+6,  %[led_strip_pin]  \n\t"
51
    "nop                \n\t"
52
    "nop                \n\t"
53
    "brcc  .+2              \n\t"
54
    //set outout low
55
    "std  Y+6,  %[led_strip_pin]  \n\t"
56
    
57
    "ret                \n"
58
    "asm_end%=:"
59
    
60
    //constraints
61
    : "=b" (colors)                                //output operands
62
    : "0" (colors), [led_strip_pin] "r" (pin), "y" (led_strip_port_pointer));  //input operands
63
  }
64
  
65
  //enable interrupt
66
  sei();
67
  
68
  //send reset pulse
69
  _delay_us(80);
70
}

Da ich nur eine einzige LED ansteuern möchte, hätte ich die Funktion 
gerne geändert. Ungefähr so: "update_led(uint8_t red, uint8_t green, 
uint8_t blue)"

Ich habs jetzt schon ne Weile versucht, aber ich bekomme es einfach 
nicht hin. Kenne mich mit Assembler leider überhaupt nicht aus.
Klar könnte ich die Funktion auch mit number_of_leds=1 aufrufen. Aber 
ich würd ja gern wissen WIE das funktioniert :)

Ich hoffe mir kann jemand helfen. 😊

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Also entweder übergibst du als 'number of leds' einfach immer eine 1 und 
änderst sonst gar nix oder du entfernst die while schleife und rennst 
nur einmal durch die Funktion.

Flo schrieb:
> Aber
> ich würd ja gern wissen WIE das funktioniert :)

Ist einfach nur die while Schleife. Der Rest ist bit schieben in ASM. 
Aber das ist für dich eigentlich uninteressant.

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


Lesenswert?

Flo schrieb:
> Ich habs jetzt schon ne Weile versucht, aber ich bekomme es einfach
> nicht hin.
Wo klemmt es denn? Für welchen Rechner soll das sein? Was soll der Code 
tun und was tut er stattdessen? Wie stellst du das fest?

von Flo (Gast)


Lesenswert?

Matthias S. schrieb:
> Also entweder übergibst du als 'number of leds' einfach immer eine 1 und
> änderst sonst gar nix oder du entfernst die while schleife und rennst
> nur einmal durch die Funktion.

Ich würde aber auch gerne das "struct color"-Zeug loswerden.
Und außerdem - wie gesagt: Verstehen wie so was funktioniert ;)

Lothar M. schrieb:
> Wo klemmt es denn? Für welchen Rechner soll das sein? Was soll der Code
> tun und was tut er stattdessen? Wie stellst du das fest?

Der Code ist für einen ATXmega und soll WS2812B-LEDs ansteuern. Das tut 
er auch ;)
Aber ich würde halt gerne die RGB-Werte direkt als uint8 (oder was auch 
immer) direkt an den Assembler-Teil übergeben. Ohne den Umweg über die 
color-struct 😅

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Flo schrieb:
> Ohne den Umweg über die
> color-struct 😅

Wie du im ASM Teil siehst, ist das gar kein Umweg. Es reicht ein 
einfaches hoch- und runterzählen von a0, um aufs struct zuzugreifen.

von Zeno (Gast)


Lesenswert?

Matthias S. schrieb:
> Flo schrieb:
>> Ohne den Umweg über die
>> color-struct 😅
>
> Wie du im ASM Teil siehst, ist das gar kein Umweg. Es reicht ein
> einfaches hoch- und runterzählen von a0, um aufs struct zuzugreifen.
Er hat sich halt Code aus dem Netz geholt und versteht ihn nicht. Da 
gibt es jetzt eigentlich nur 3 Wege die zum Ziel führen:
1. Er denkt sich selbst was aus
2. Er setzt sich auf Hosenboden, nimmt sich ein schlaues Buch und 
arbeitet den Quellcode Schritt für Schritt durch. Ja das ist sehr 
mühsam, aber es bildet durchaus.
3. Er bemüht die Suchmaschine seines Vertrauens, um anderen Code für 
sein Problem bzw. der sein Problem besser abbildet zu finden. Ich denke 
da wird man durchaus fündig.

Den Code den ein anderer gemacht hat zu verstehen, ist nicht immer ganz 
einfach, da muß man ab und an schon viele bittere Pillen schlucken. 
Gerade für einen Anfänger, wie der TO einer zu sein scheint, ist das oft 
schwierig, weil der Profi die Probleme anders löst als ein Anfänger tun 
würde.

von Flo (Gast)


Lesenswert?

OK.... Ich habe jetzt nochmal ein bisschen rumgespielt - jetzt 
kompiliert er wenigstens mal ohne Fehler 😅
Kann aber leider gerade nicht ausprobieren, ob's auch läuft.

Sieht jetzt so aus:
1
  asm volatile(
2
    "mov  __tmp_reg__,  %[RED]    \n\t"
3
    "rcall  send_byte%=          \n\t"
4
    "mov  __tmp_reg__,  %[GREEN]  \n\t"
5
    "rcall  send_byte%=          \n\t"
6
    "mov  __tmp_reg__,  %[BLUE]    \n\t"
7
    "rcall  send_byte%=          \n\t"
8
    "rjmp  asm_end%=          \n\t"
9
  
10
.....(bla bla bla).....
11
12
    :: [RED] "r" (r), [GREEN] "r" (g), [BLUE] "r" (b), [led_strip_pin] "r" (pin), "y" (led_strip_port_pointer)
13
    
14
  );

Passt das so? 🤔

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.