Globales Array über SPI ausgeben

Gast #1405780
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?
#1405831
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!
1
         // CS für die SPI Übertragung auf 0 setzen
2
         CS_DAC_SIGNAL = 0;
3

4
         SPDR = spiegelpositionen[aktuelle_scanspiegelposition++];
5
         while(!(SPSR & 0x80));
6
         SPDR = spiegelpositionen[aktuelle_scanspiegelposition++];
7
         while(!(SPSR & 0x80));
8
         SPDR = spiegelpositionen[aktuelle_scanspiegelposition++];
9
         while(!(SPSR & 0x80));
10
         SPDR = spiegelpositionen[aktuelle_scanspiegelposition++];
11
         while(!(SPSR & 0x80));
12
         CS_DAC_SIGNAL = 1;
13

14
         if(aktuelle_scanspiegelposition == 512) 
15
         {
16
               aktuelle_scanspiegelposition = 0;
17
         }
18

19
bzw.: unsigned int *ptr;
20

21
ptr = spiegelpositionen[aktuelle_scanspiegelposition];
22

23
         SPDR = *ptr++;
24
         while(!(SPSR & 0x80));
25
         SPDR = *ptr++;
26
         while(!(SPSR & 0x80));
27
         SPDR = *ptr++;
28
         while(!(SPSR & 0x80));
29
         SPDR = *ptr++;
30
         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
Gast #1405934
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

Eine eigene Frage? Dieser Thread ist über 17 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.