Moin @ll
für Zeitkritische Funktionen schreibe ich gewisse Parts in ASM.
uA bezieht es sich auf Befehle wie SBI, CBI.
im Normalfall schaut eine Zeile für einen ATMega328p-pu wie folgt aus.
Da ich für ein Projekt allerdings 12 WS2812 - Lines verwende hab ich mit
dem Gedanken gespielt mir ein Const nach folgendem Schema aufzubauen,
womit ich in anderen Projekte sehr gute Erfahrung gesammelt habe.
1 | const
| 2 | WS2812 : record
| 3 | Line, Port, Pin : array[0..11] of uint8;
| 4 | end = (Line: ( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
| 5 | {$if defined (ATMega328p)}
| 6 | Port: ( 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9);
| 7 | {$endif}
| 8 | Pin: ( 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2));
|
von meiner Logik her sollte ja die Befehlsänderung von *sbi 8, LED_01*
in 1 | Port := WS2812.Port[Line];
| 2 | Pin := WS2812.Pin[Line];
| 3 | sbi Port, Pin
|
den seben Effekt haben, jedoch zeigt mir Lazarus den Mittelfinger.
Kennt jemand einen sauberen Weg um dies zu bewerkstelligen, da ich
ungern die Nominelle Funktion 1 | procedure LineRgbShiftOut(Line: uint8);
| 2 | var
| 3 | p : ^byte;
| 4 | byteCount : uint16;
| 5 | bitCount, RGBdata, Port,
| 6 | Pin : uint8;
| 7 | label
| 8 | TH, TL, T0L, T1L, Loop;
| 9 | begin
| 10 | p := @Rgb_Line[Line];
| 11 | asm CLI end;
| 12 | for byteCount := 0 to sizeof(Rgb_Line[Line]) - 1 do begin
| 13 | RGBdata := p^;
| 14 | inc(p[1]);
| 15 | for bitCount := 0 to 7 do
| 16 | if RGBdata and $80 > 0 then begin
| 17 | asm
| 18 | {$if defined (ATTiny25) or defined (ATTiny85)}
| 19 | SBI 24, 2 // 24 = PORTB
| 20 | nop
| 21 | nop
| 22 | {$endif}
| 23 | // {$if defined (ATMega16)}SBI 21, LED // 21 = PORTC
| 24 | // ldi r16, 13
| 25 | // {$endif}
| 26 | {$if defined (ATMega328p)}
| 27 | sbi 8, LED_01 // 8 = PortC (ATMega328p)
| 28 | sbi 8, LED_02
| 29 | // sbi 8, LED_03
| 30 | {$endif}
| 31 | nop
| 32 | {$if defined (ATTiny25) or defined (ATTiny85)}
| 33 | CBI 24, LED
| 34 | {$endif}
| 35 | {$if defined (ATMega328p)}
| 36 | cbi 8, LED_01
| 37 | cbi 8, LED_02
| 38 | // cbi 8, LED_03
| 39 | {$endif}
| 40 | // {$if defined (ATMega16)}CBI 21, LED
| 41 | // ldi r16, 7
| 42 | // {$endif}
| 43 | // nop
| 44 | end;
| 45 | RGBdata := RGBdata shl 1;
| 46 | end else begin
| 47 | asm
| 48 | {$if defined (ATTiny25) or defined (ATTiny85)}
| 49 | SBI 24, LED
| 50 | nop
| 51 | {$endif}
| 52 | {$if defined (ATMega328p)}
| 53 | sbi 8, LED_01
| 54 | sbi 8, LED_02
| 55 | // sbi 8, LED_03
| 56 | {$endif}
| 57 | // {$if defined (ATMega16)}SBI 21, LED
| 58 | // ldi r16, 7
| 59 | // TL:
| 60 | // dec r16
| 61 | // brne TL{$endif}
| 62 | {$if defined (ATTiny25) or defined (ATTiny85)}
| 63 | CBI 24, LED
| 64 | {$endif}
| 65 | {$if defined (ATMega328p)}
| 66 | cbi 8, LED_01
| 67 | cbi 8, LED_02
| 68 | // cbi 8, LED_03
| 69 | {$endif}
| 70 | // {$if defined (ATMega16)}CBI 21, LED
| 71 | // ldi r16, 13
| 72 | // T0L:
| 73 | // dec R16
| 74 | // brne T0L
| 75 | // {$endif}
| 76 | end;
| 77 | RGBdata := RGBdata shl 1;
| 78 | end;
| 79 | end;
| 80 | asm SEI end;
| 81 | end;
|
12 mal schreiben will...
Gruß und schönen Sonntag
Maik
Port und Pin werden bei SBI im Opcode gespeichert und können deswegen
nicht aus Variablen kommen.
Mario M. schrieb:
> Port und Pin werden bei SBI im Opcode gespeichert und können deswegen
> nicht aus Variablen kommen.
Also bleibt nur die Option die selbe Funktion 12 mal zu schreiben...
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
|