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?
Wieso Timer Interrupt und nicht "SPI Ready" oder wie auch immer das beim ATMEGA heisst?
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
Diese ganzen volatiles sind nur dort nötig, wo die ISR auch drauf zugreift. Sind ein ziemlicher Knüppel zwischen die Beine des Compilers.
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;
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.