- fchao-Sinus-Wechselrichter AliExpress         
Ergebnis 1 bis 3 von 3

Thema: Mischung von Assembler und C

Baum-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076

    Mischung von Assembler und C

    Hallo zusammen,

    ich steuere grad mit dem PIC10F332 einen RGB-Stripe an.
    Das fuktioniert auch schon ganz hervorragend, bin ganz begeistert.
    Sein maximales Timing bekommt das grade so auf die Reihe.
    Die Ausschiebefunktion musste ich jedoch in Assembler implementieren wegen der Laufzeit
    und da taucht nun ein "kleines" Problemchen auf:

    In der Ausschiebefunktion benötige ich auch die Anzahl der LEDs die ich mit
    #define LED_COUNT 4
    in "C" declariert habe.

    Wie komme ich da aber ran innerhalb meiner Assembler Ausschiebefunktion ?

    Natürlich kann ich in Assembler hier den Wert multipliziert mit 3 direkt ins Register laden,
    aber dann muss ich bei Änderungen von LED_COUNT auch jedesmal den Assemblercode ändern,
    das halte ich für eine "schlechte/unschöne" Programmierung.
    ....vegesse ich auch garantiert irgendwann wenn ich später mal Änderungen vornehme...

    Code:
    // Declaration einer einzelnen RGB LED 
    // Jede LED hat 3 Bytes, insgesamt also 24 Bits 
    typedef struct // __pack ? bei 8 Bittern unnötig, ist immer packed
    {
      U8 green; /* 8 Bit fuer die Helligkeit gruen */
      U8 red;   /* 8 Bit fuer die Helligkeit rot   */
      U8 blue;  /* 8 Bit fuer die Helligkeit blau  */
    } TLed;     /* Type Bezeichner ist TLed */
    
    #define LED_COUNT 4         // Anzahl der anzusteuernden RGB Leds 
    
    TLed LedArray[LED_COUNT];   // gesamtes Datenarray der Ledkette 
                                // dieses Array wird dann per Assmblercode ausgeschoben
    
    //------------------------------------------------------------------------------
    // Der Assembler-Code zum Ausschieben von LedArray:
    // für 250ns Instruction Cycle Time 4 MHz
    // PMDATL enthält das auszuschiebene Datenbyte für die WS2812 RGB-Led Kette
    // wird also als Zwischenspeicher benutzt. (8 Bit Register)
    // PMADRL wird für den Bytezähler benutzt  (8 Bit Register)
    // PMDATH wird als Bitzähler benutzt !!! ist nur ein 6 Bit Register
    // das reicht aber, wir zählen ja nur von 8 bis 0
    
    void asm_LedShiftOut(void)
    {
      asm("movlw LOW _LedArray");  // address of LedArray
      asm("movwf FSR");            // to FSR index register
    
      asm("movlw 12");        // <==== eigentlich LED_COUNT * 3) das geht aber nicht <======
    
      asm("movwf PMADRL");         // use PMADRL as byteCount
      
    asm("Label_NextByte:");        // !! WICHTIG, der Doppelpunkt ab XC8 V2.20 !!
      asm("movlw 8");              // set bit count to 8
      asm("movwf PMDATH");         // use PMDATH as Bitcounter
      asm("movf  INDF,W");         // load byte from LedArray to W register
      asm("movwf PMDATL");         // save Databyte to PMDATL 
    
    asm("Label_ByteLoop:");
      asm("btfsc PMDATL,7");       // scip if databit is clear (MSB)
      asm("goto Label_High");      // else databit ist set
      asm("bsf LATA,0");           // set WS2812 DataLine to High 250ns
      asm("bcf LATA,0");           // set WS2812 DataLine to Low
      asm("goto Label_nextBit");
     
    asm("Label_High:");                    // High Bit
      asm("bsf LATA,0");                   // set WS2812 DataLine to High
      asm("NOP"); asm("NOP"); asm("NOP");  // hold Line High for 1000ns
      asm("bcf LATA,0");                   // set Line to Low
    
    asm("Label_nextBit:");
      asm("rlf PMDATL,F");          // databyte left
      asm("decfsz PMDATH,F");       // bitCount-1, scip if all bits done
      asm("goto Label_ByteLoop");   // next bit
      
      asm("incf FSR,F");            // address pointer to next Led Byte
      asm("decfsz PMADRL,F");       // byteCount-1 scip if all bytes done
      asm("goto Label_NextByte");   // else send next byte
    
      //   __delay_us(100); // Das Ende der Datenübertragung erreicht wenn die Leitung länger als 50us Low bleibt.
      //  !!! mindestens 80us bei SK68 Leds 
        
      // hier brauche ich eigentlich nicht warten, weil der restliche Programmcode benötigt ja schon Zeit ???
      asm("movlw 0x85");           // das sind 100us 
      asm("movwf PMDATL");
      asm("Label_delay100:");
      asm("decfsz PMDATL,F");
      asm("goto Label_delay100");
    }
    Vielleicht habt Ihr eine Idee wie man das evtl. auch anders lösen kann.

    Siro
    Geändert von Siro (17.09.2020 um 20:19 Uhr)

Ähnliche Themen

  1. RP6 und Assembler
    Von ThomasD im Forum Microcontroller allgemeine Fragen/Andere Microcontroller
    Antworten: 1
    Letzter Beitrag: 18.04.2010, 21:29
  2. assembler
    Von m1cha im Forum Allgemeines zum Thema Roboter / Modellbau
    Antworten: 1
    Letzter Beitrag: 29.01.2008, 13:27
  3. if in Assembler???
    Von XDavidX im Forum PIC Controller
    Antworten: 7
    Letzter Beitrag: 29.01.2006, 11:56
  4. Assembler und I2C ?
    Von ProgDom im Forum AVR Hardwarethemen
    Antworten: 5
    Letzter Beitrag: 20.07.2005, 14:46
  5. Assembler ADW ???
    Von ProgDom im Forum AVR Hardwarethemen
    Antworten: 3
    Letzter Beitrag: 11.07.2005, 20:59

Berechtigungen

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

12V Akku bauen