www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Globales Array über SPI ausgeben


Autor: Johann (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi @ all

Ich habe ein globales unsigned char array mit 512 Elemente. Dieses 
möchte ich über die SPI-Schnittstelle ausgeben. Mein Code ist aber um 
Faktor 2 zu langsam. Ich benutze einen ATMEGA 2561 µC von Atmel. Laut 
meinen Berechnungen muss es locker möglich sein dies um Faktor 2 zu 
beschleunigen, jeoch ist mein C-Code wohl zu schlecht. Vielleicht kann 
mir ja jemand weiterhelfen.

Ich löse alle 7,8µs einen Timerinterrupt aus. (dies funktioniert auch 
bereits) In der Timerinterruptserviceroutine setze ich mir dann das Flag 
modus auf 1 und beende die Serviceroutine. Im Hauptprogramm frage ich 
dann das Flag immer ab. Ist dieses 1 so gebe ich 4 Elemente aus dem 
globalen Array über die SPI-Schnittstelle aus und setze anschließend das 
Modus-Flag auf 0 zurück.

// hier st mein globales Array und meine anderen globalen Variablen
volatile unsigned char spiegelpositionen[512];
volatile unsigned char modus;
volatile unsigned int aktuelle_scanspiegelposition;


// jetzt zum Hauptprogramm

while (1)
   {

      if(modus == 1)
      {
         // CS für die SPI Übertragung auf 0 setzen
         CS_DAC_SIGNAL = 0;
         SPDR = spiegelpositionen[aktuelle_scanspiegelposition];
         aktuelle_scanspiegelposition = aktuelle_scanspiegelposition + 
1;
         while(!(SPSR & 0x80));
         SPDR = spiegelpositionen[aktuelle_scanspiegelposition];
         aktuelle_scanspiegelposition = aktuelle_scanspiegelposition + 
1;
         while(!(SPSR & 0x80));
         SPDR = spiegelpositionen[aktuelle_scanspiegelposition];
         aktuelle_scanspiegelposition = aktuelle_scanspiegelposition + 
1;
         while(!(SPSR & 0x80));
         SPDR = spiegelpositionen[aktuelle_scanspiegelposition];
         aktuelle_scanspiegelposition = aktuelle_scanspiegelposition + 
1;
         while(!(SPSR & 0x80));
         CS_DAC_SIGNAL = 1;

         if(aktuelle_scanspiegelposition == 512)
         {
            aktuelle_scanspiegelposition = 0;
         }

         modus = 0;

         TestPin0 = 0;
      }
      else
      {
         //Leerlaufmodus
      }


Im Hauptprogramm gebe ich 4 Arrayelement aus und zähle die Position 
hoch. Jedoch dauert es zu lange. Kann man dies besser lösen?

Autor: manateemoo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wieso Timer Interrupt und nicht "SPI Ready" oder wie auch immer das beim 
ATMEGA heisst?

Autor: Mi Mo (mike123)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

welche Taktfrequenz hat dein System?
Welche Optimierungsstufe hat dein System?


@16 MHz braucht dein System alleine für die Übertragung der 4Byte 2µs, 
aber das soll es net sein...

auf die schnelle diese Lösung!
         // CS für die SPI Übertragung auf 0 setzen
         CS_DAC_SIGNAL = 0;

         SPDR = spiegelpositionen[aktuelle_scanspiegelposition++];
         while(!(SPSR & 0x80));
         SPDR = spiegelpositionen[aktuelle_scanspiegelposition++];
         while(!(SPSR & 0x80));
         SPDR = spiegelpositionen[aktuelle_scanspiegelposition++];
         while(!(SPSR & 0x80));
         SPDR = spiegelpositionen[aktuelle_scanspiegelposition++];
         while(!(SPSR & 0x80));
         CS_DAC_SIGNAL = 1;

         if(aktuelle_scanspiegelposition == 512) 
         {
               aktuelle_scanspiegelposition = 0;
         }

bzw.: unsigned int *ptr;

ptr = spiegelpositionen[aktuelle_scanspiegelposition];

         SPDR = *ptr++;
         while(!(SPSR & 0x80));
         SPDR = *ptr++;
         while(!(SPSR & 0x80));
         SPDR = *ptr++;
         while(!(SPSR & 0x80));
         SPDR = *ptr++;
         while(!(SPSR & 0x80));


du musst dann natürlich noch die aktuelle "aktuelle_scanspiegelposition" 
behandeln...


sorry, hab grad keine zeit mehr, muss weg.
keine Richtigkeit für evtl. schreibfehler!!

ansonsten anylisiere den code im assembly-listing, bzw. schreib den code 
direkt in Assembler!!

Gruß,
Michel

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Diese ganzen volatiles sind nur dort nötig, wo die ISR auch drauf 
zugreift. Sind ein ziemlicher Knüppel zwischen die Beine des Compilers.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nutze das SPI Modul einfach besser aus. Solange rausgetaktet wird
kann man schon mal Daten aus dem Speicher holen und Zähler
inkrementieren.

         // CS für die SPI Übertragung auf 0 setzen
         unsigned char c;
         CS_DAC_SIGNAL = 0;

         SPDR = spiegelpositionen[aktuelle_scanspiegelposition++];
         c=spiegelpositionen[aktuelle_scanspiegelposition++];
         while(!(SPSR & 0x80));
         SPDR = c;
         c=spiegelpositionen[aktuelle_scanspiegelposition++];
         while(!(SPSR & 0x80));
         SPDR = c;
         c=spiegelpositionen[aktuelle_scanspiegelposition++];
         while(!(SPSR & 0x80));
         SPDR = c;
         while(!(SPSR & 0x80));
         CS_DAC_SIGNAL = 1;

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.