Globales Array über SPI ausgeben

Gast #1405780
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?
#1405831
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!
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
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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren