- LiTime Speicher und Akkus         
Seite 2 von 3 ErsteErste 123 LetzteLetzte
Ergebnis 11 bis 20 von 24

Thema: XC8 inline Assembler

  1. #11
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076
    Anzeige

    Praxistest und DIY Projekte
    Hallo zusammen,
    ich wollte "mal wieder" etwas Assembler in meinen XC8 Code bringen,
    dafür wollte ich aber keinen neuen Thread öffnen, daher führe ich das mal hier weiter:

    Der XC8 inline Assembler scheint irgendwie überhaupt nicht mit dem XC8-Compiler zu harmonieren.
    Ich kann weder auf Variablen noch auf Konstanten zugreifen, es gibt ständig nur Fehlermeldungen.

    Hier mal ein Auschnitt des Screenshoots: ich hab mal den Fehlermeldungen daneben geschrieben

    Klicke auf die Grafik für eine größere Ansicht

Name:	xc8_inline_2.jpg
Hits:	8
Größe:	60,8 KB
ID:	33294

    Hier ein Ausschnitt des inline Codes:
    Code:
    #define LED_COUNT 24
    unsigned char LedArray[LED_COUNT];
    unsigned char byteCount;
    unsigned char bitCount;
    
    void LedShiftOut(void)
    {
      asm("BANKSEL LedArray");
      asm("LFSR FSR0,LedArray");
    
      asm("BANKSELECT byteCount");
      asm("movlw LED_COUNT");
      asm("movwf byteCount");
    
    asm("ByteLoop:");
      asm("movlw 8");
      asm("movwf bitCount");
      asm("movwi fsr0++");
    
    asm("BitLoop:");
      asm("RRF WREG,F");
      asm("btfss STATUS,Z");
      asm("goto isOne");
    
    asm("isZero:");
      asm("bcf LATA,5"); 
      asm("NOP");
      asm("NOP");  
      asm("goto BitLoop");
      
    asm("isOne:");
      asm("bsf LATA,5");
      asm("NOP");
      asm("NOP");  
      
      asm("decfsz bitCount,F");
      asm("goto BitLoop");
      
      asm("decfsz byteCount,F");
      asm("goto ByteLoop");
      
      // 50us Pause
      
    }
    was mache ich denn falsch ?, das kann doch nicht so kompliziert sein.....

    Es wird mir wieder Mal nix anderes übrig bleiben als den gesamten Code in Assembler zu programmieren.

    [edit]
    auf dei Variablen kann ich evtl. zugreifen wenn ich einen Unterstrich benutze, zumindest meckert der Compiler dann nicht.
    Es bleiben aber noch genug Probleme übrig...
    Geändert von Siro (22.02.2018 um 23:55 Uhr)

  2. #12
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076
    Guten Morgen liebe Gemeinde,

    ich werde mal eine der vielen Fragen konkretisieren:

    Code:
    #define ZAEHLER 8
    
    int main(void)
    { 
     asm("movlw ZAEHLER");   // undefined symbol ZAEHLER
    was ist hier so Besonderes, dass es nicht funktioniert ?

    so funktioniert es ja:
    Code:
    asm("movlw 8");


    Nun habe ich grad etwas Neues ausprobiert und das geht sogar:
    Code:
    // #define ZAEHLER 8   // so geht es nicht 
    
    asm("ZAEHLER EQU 8");   // aber so geht es 
    
    int main(void)
    {
     asm("movlw ZAEHLER");

    Siro
    Geändert von Siro (23.02.2018 um 08:29 Uhr)

  3. #13
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    07.03.2011
    Beiträge
    1.899
    Zitat Zitat von Siro Beitrag anzeigen
    was mache ich denn falsch ?, das kann doch nicht so kompliziert sein.....

    Es wird mir wieder Mal nix anderes übrig bleiben als den gesamten Code in Assembler zu programmieren.
    Was gibt es für einen Grund, hier Assembler zu verwenden? Seitdem es C für die PICS gibt, hab ich kein Assembler mehr verwendet. Und ich kann auch in deinem Code nichts erkennen, daß sich nicht in C formulieren lässt.

    Wenn ich deinen Code richtig verstanden habe, soll er, ein Array von unsigned chars bitweise auf einem Port ausgeben.

    Code:
    #include <xc.h>
    #include <stdint.h>
    
    #define LED_COUNT 24
    uint8_t LedArray[LED_COUNT];
    
    void LedShiftOut(uint8_t *leds, int8_t count) {
        uint8_t one_byte;
        int8_t bit_count;
    
        while (count) {
            one_byte = *leds++; // next Byte
            for (bit_count = 0; bit_count < 8; bit_count++) {
                LATA5 = one_byte & 0x01; // lowest Bit
                one_byte >>= 1;
            }
            count--;
        }
    }
    
    void main(void) {
        LedShiftOut(LedArray, LED_COUNT);
        return;
    }
    Eigentlich ist das Ganze aber eine Aufgabe für das SPI Modul, wobei man MISO und CLK nicht verwendet.

    Und zu deiner Frage mit
    Code:
    #define ZAEHLER 8
    Der Compiler kennt ZAEHLER nicht, alle Zeilen, die mit einem # beginnen, werden vom Präprozessor bearbeitet. Die bekommt der Compiler garnicht zu sehen. Das "#define" tut das Gleiche, was "suchen und ersetzten" in deinem Editor macht, jedesmal vor dem Compilieren.

    Wenn ich lese, was du hier in diesem Thread so schreibst, wirst du mit deinem Ansatz nicht wirklich glücklich werden. Entweder du schreibst alles in Assembler, wozu es IMHO keine Notwendigkeit gibt, oder du programmierst in C. Die Mischung ist eigentlich immer Pfusch und führt am Ende zu unwartbarem Code. Die Arduino-Leute sind noch einen Schritt weiter gegangen und verwenden C++.

    MfG Klebwax
    Strom fließt auch durch krumme Drähte !

  4. #14
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076
    Moin Klebwax,
    ersteinmal Danke für deine Mühe und Informationen.

    Im Prinzip hast Du recht, man braucht "meistens" keinen Assembler, wenn man schon in "C" programmiert.
    Aber manchmal gibt es doch einige Ausnahmen.
    Ich möchte die RGB Leds Typ WS2812B ansteuern und die haben/wollen leider ein sehr genaues Timing haben. +/- 150ns laut Datenblatt.
    Da bleibt nicht viel Freiraum für einen "nicht optimierten" C-Code (Free Version )

    Im Prinzip will ich nur die Daten in dem "richtigen" Timing ausschieben, der Rest sollte in "C" sein.
    Auch richtig erkannt, dass man dafür das SPI Interface nehmen könnte, wobei ich hier noch nicht sicher bin ob das
    mit dem Timing hinhaut. Bin mometan noch etwas in der Experimentierphase.

    Generell sollte es aber auch möglich sein, Assembler mit "C" zu mischen und ich bin quasi am erforschen
    wie das am besten oder überhaupt geht. Komme ja auch grad etwas weiter....


    Mit dem Preprocessor ist mir eigentlich klar, aber anscheinend nur "eigentlich"
    Wenn der Preprozssor alle #defines vorher einsetzt bevor er compiliert und/oder assembliert,
    dann müsste die Assemblerzeile doch auch richtig aussehen.

    #define ZAEHLER 8
    sagt aus, daß überall im Code wo ZAEHLER auftaucht die 8 eingetragen wird (wie Du auch geschrieben hast: suchen/ersetzen).
    Erst dann wird compiliert/assembliert und demnach steht doch dann in meiner Assemblerzeile
    anstelle von
    asm("movlw ZAEHLER");
    asm("movlw 8");
    oder habe ich das falsch verstanden ?

    [Edit] mir ist grad ein Licht aufgegangen:
    Ein define wird NICHT ersetzt wenn er in Ausdrücken mit Hochkomma steht.
    Der identifier wird nur ersetzt, wenn er ein Token bildet. Der identifier wird also nicht ersetzt, wenn er in einem Kommentar, in einer Zeichenfolge oder als Teil eines längeren Bezeichners erscheint ...

    Siro

    (Ziel ist es mit einen kleinen 8 Füssler (momentan PIC12F1840) 24 RGB Leds anzusteuern)
    Das gibt es übrigens auch schon fertig in Assembler:
    http://www.picalic.de/PIC2WS2812/picsolution.html
    Geändert von Siro (23.02.2018 um 11:37 Uhr)

  5. #15
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    07.03.2011
    Beiträge
    1.899
    Zitat Zitat von Siro Beitrag anzeigen
    Generell sollte es aber auch möglich sein, Assembler mit "C" zu mischen ...
    es sollen schon Leute für weniger gefeuert worden sein

    #define ZAEHLER 8
    sagt aus, daß überall im Code
    im C-Code
    wo ZAEHLER auftaucht die 8 eingetragen wird (wie Du auch geschrieben hast: suchen/ersetzen).
    Erst dann wird compiliert/assembliert und demnach steht doch dann in meiner Assemblerzeile
    anstelle von
    asm("movlw ZAEHLER");
    asm("movlw 8");
    oder habe ich das falsch verstanden ?
    und nicht in Strings "... ZAEHLER"

    Die WS2812 mit ihrem Timing sind ein besonderes Thema. Eigentlich benötigt man dafür ein HW-Modul im Prozessor wie SPI oder PWM. Die Lösungen mit SPI sind eher suboptimal. Aber wenn Assembler, dann würd ich nicht mischen sondern die wirklich notwendigen Funktionen komplett in Assembler schreiben und in einen extra File packen. Im XC8 Manual in Kapitel 5.12 findet sich da eine Anleitung.

    MfG Klebwax
    Strom fließt auch durch krumme Drähte !

  6. #16
    Erfahrener Benutzer Roboter-Spezialist Avatar von witkatz
    Registriert seit
    24.05.2006
    Ort
    NRW
    Alter
    53
    Beiträge
    540
    Blog-Einträge
    17
    Zitat Zitat von Siro Beitrag anzeigen
    Code:
    ...
    unsigned char LedArray[LED_COUNT];
    
    void LedShiftOut(void)
    {
      asm("BANKSEL LedArray");
    ...
    MPLAB_XC8_C_Compiler_User_Guide.pdf:
    Most C symbols map to an corresponding assembly equivalent.
    ...
    The name of a C function maps to an assembly label that will have the same name, but
    with an underscore prepended. So the function main() will define an assembly label
    _main.
    nach meinem Wissen gilt das für Funktionen als auch für Variablen, also folgendes müsste gehen:
    Code:
    asm("BANKSEL _LedArray");

  7. #17
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076
    Du hast völlig Recht Witkatz, mit dem Unterstrich kann ich auf die Variablen zugreifen
    ebenso auf die Funktionsnamen.
    Bei BANKSEL geht das auch, obwohl der Operand _LedArray dabei sogar in Hochkomma steht.

    Code:
    #define LED_COUNT 24
    unsigned char LedArray[LED_COUNT];
    
    unsigned char count;
    
    void MeineFunc(void)
    { volatile unsigned char x;
      x++;
    }
    
    int main(void)
    {
     asm("movf  _count,W");       // geht Variable laden mit Unterstrich
     asm("movwf _count");         // geht Variable speichern mit Unterstrich
     asm("call _MeineFunc");      // geht Funktionsaufruf mit Unterstrich
     asm("BANKSEL   _LedArray");  // geht mit Unterstrich
    
    // asm("LFSR FSR0,_LedArray");  // geht leider nicht
    Ich werde sicher noch einiges propbieren, das Wochende fängt ja erst an.
    und wünsche Euch allen ein schönes Wochenende und danke, dass ihr meine "Code Eskapaden" ertragt....

  8. #18
    Erfahrener Benutzer Roboter-Spezialist Avatar von witkatz
    Registriert seit
    24.05.2006
    Ort
    NRW
    Alter
    53
    Beiträge
    540
    Blog-Einträge
    17
    Zitat Zitat von Siro Beitrag anzeigen
    Code:
    // asm("LFSR FSR0,_LedArray");  // geht leider nicht
    Kennt dein PIC den Befehl überhaupt? Ist nämlich ein PIC18 Befehl, so hab ich's zumindest im MPASM Quick Chart gefunden.

  9. #19
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076
    Ich lach mich kaputt.....
    Du hast ja sowas von recht Witkatz

    Oh Mann, das tut ja weh , vielen Dank für die Info
    --------------------------------------------------

    Ich habe jetzt einen laufenden Code, fast ausschließlich in "C" , basierend auf der Funktion von Klebwax(dessen Code ich geklaut habe).

    Code:
    // so viele LEDs sollen angesteuert werden:
    #define LED_COUNT 3
    
    /* Jede LED hat 3 Bytes insgesamt also 24 Bits */
    typedef  struct  // __pack weil wir keinen Speicher verschwenden wollen ????
    { 
        U8 green;     /* 8 Bit fuer die Helligkeit */
        U8 red;       /* 8 Bit fuer die Helligkeit */
        U8 blue;      /* 8 Bit fuer die Helligkeit */
    } TLed;           /* Type Bezeichner ist TLed */
    
    TLed LedArray[LED_COUNT];
    
    void LedShiftOut(U8* leds, U8 count) 
    {
        U8 one_byte;
        U8 bit_count;
    
        count *=3;             // 3 Bytes pro Led RGB
        while (count) {
            one_byte = *leds++; // next Byte
            for (bit_count = 0; bit_count < 8; bit_count++) 
            {
                if (one_byte & 0x01) // lowest Bit
                {
                    LATA5 = 1;
                    asm("NOP");
                    asm("NOP");
                    asm("NOP");
                    LATA5 = 0;
                } else
                {
                    LATA5 = 1;
                    asm("NOP");
                    LATA5 = 0;
                }    
                one_byte >>= 1;
            }
            count--;
        }
           
        Delay_ms(1);
    }
    Das Timing stimmt eigentlich nicht, aber das scheint wesentlich unkritischer zu sein als das Datenblatt vorgibt.
    Die Low Phasen dürfen nämlich viel länger sein, das scheint nicht zu stören. Die sind bei mir alle so ca. 2us.
    Die High-Phasen müssen lediglich stimmen, dann ist die Welt in Ordnung.
    Ich habe zwischen den Bytes sogar 5us Pause, das stellt kein Problem dar.

    Klicke auf die Grafik für eine größere Ansicht

Name:	Timing_RGB.png
Hits:	4
Größe:	53,3 KB
ID:	33295

    Nochmal einen DANK an alle Die mir hilfreiche Informationen gegeben haben (beonders Witkatz + Klebwax)
    Geändert von Siro (23.02.2018 um 21:20 Uhr)

  10. #20
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    07.03.2011
    Beiträge
    1.899
    @Siro

    Jetzt könnte man noch die Lbraryfunktion

    NOP();

    statt

    asm("NOP");

    verwenden und alles wäre plain C.

    MfG Klebwax
    Strom fließt auch durch krumme Drähte !

Seite 2 von 3 ErsteErste 123 LetzteLetzte

Ähnliche Themen

  1. Bascom Inline-Assembler
    Von Che Guevara im Forum Assembler-Programmierung
    Antworten: 64
    Letzter Beitrag: 07.02.2012, 20:00
  2. Inline Assembler
    Von Che Guevara im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 16
    Letzter Beitrag: 01.02.2010, 20:25
  3. AVR GCC inline Assembler
    Von chientech im Forum Assembler-Programmierung
    Antworten: 1
    Letzter Beitrag: 26.09.2009, 17:39
  4. Inline Assembler für Anfänger
    Von 1udo1 im Forum C - Programmierung (GCC u.a.)
    Antworten: 3
    Letzter Beitrag: 25.10.2007, 20:53
  5. Parameterübergabe bei Inline-Assembler
    Von ogni42 im Forum C - Programmierung (GCC u.a.)
    Antworten: 21
    Letzter Beitrag: 30.03.2006, 14:32

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

LiTime Speicher und Akkus