Forum: Mikrocontroller und Digitale Elektronik wie lange braucht mein uC zur Ausführung von.


von Stefan H. (stefan0985)


Lesenswert?

Hallo

ich muss wissen wie lange mein uC zur Abarbeitung von folgendem Program 
teil braucht.


void SPI_Transmit(char sData)
{
/* Start transmission */
SPDR=sData;
/*Wait for transmission complete */
  while(!(SPSR & (1<<SPIF)))
  {

  }

}


tabellenlaenge=0x2000; //8192

for(x=0x0000;x<tabellenlaenge;x++)
  {
  y=abs(4095*sin(2*3.141592652*x/tabellenlaenge));

  datagram[0]=0xFF;
  datagram[1]=(unsigned char)(x>>8);
  datagram[2]=(unsigned char)(x);
  datagram[3]=(unsigned char)(y>>8);
  datagram[4]=(unsigned char)(y);

  SPI_Transmit(datagram[0]);
  SPI_Transmit(datagram[1]);
  SPI_Transmit(datagram[2]);
  SPI_Transmit(datagram[3]);
  SPI_Transmit(datagram[4]);
  }

Clock rate select habe ich auf (0<<SPR1)|(0<<SPR0) und SPI2X auch auf 
Null.
Clock rate select ist also auf fosc/4 (bedeutet doch, dass eine SCK 
periode 4 CLK takte benötigt oder ist diese annahme schon falsch?

da die for schleife und das abspeichern ins das array datagram im 
verhältniss zum übertragen via SPI nicht ins gewicht fällt und ich eig. 
auch nur wissen muss wie lange die übertragung der 8192*5 (5*8bits) 
spi-datagramme dauert kann dies vernachlässigt werden.

bei meiner rechnung komm ich nun auf folgendes.
5mal SPI_transmit= 40bits=40SCK zyklen=40*4CLK zyklen

also: t=(40*8192)*4/16MHz=0,08192s

ich habe aber ca. 6,5s gemessen. und zwar so. LED1 an obige FOR.Schleife 
LED1 aus und LED2 an. zwischen LED1 und LED2 sind halt ca. 6,5sekunden.

wo liegt mein fehler.

bin für jeden hinweis/jede hilfe sehr dankbar

gruß

von Justus S. (jussa)


Lesenswert?

Stefan Haller schrieb:
> y=abs(4095*sin(2*3.141592652*x/tabellenlaenge));

mit floats rechnen dauert immer lange...

von Karl H. (kbuchegg)


Lesenswert?

Justus Skorps schrieb:
> Stefan Haller schrieb:
>> y=abs(4095*sin(2*3.141592652*x/tabellenlaenge));
>
> mit floats rechnen dauert immer lange...

und wenns dann auch noch ein sin sein darf ... da kannst du dir gleich 
auch noch einen Kaffee dazwischen kochen gehen.

Oder verfügt der unbekannte µC etwa über eine FPU?

> da die for schleife und das abspeichern ins das array datagram im
> verhältniss zum übertragen via SPI nicht ins gewicht fällt

Die nicht.
Aber die Rechnerei!
Mal sehen, das sind

   2 float Multiplikationen (eine wird der Compiler auflösen)
   1 float Division
   1 float Sinus
   1 float Absolutwert
   1 Konvertierung float zu int (zumindest denke ich das x und y int
                                 sein werden, da du nur 2 Bytes
                                 verschickts)
   1 Konvertierung int zu float

Summa summarum sind das ein paar Hundert Takte, wenns überhaupt im 
3-stelligen Bereich bleibt, was ich eigentlich bezweifle aber nicht 
nachgemessen habe.

von Falk B. (falk)


Lesenswert?

@  Stefan Haller (stefan0985)

>ich muss wissen wie lange mein uC zur Abarbeitung von folgendem Program
>teil braucht.

Dann simulier das doch einfach im AVR-Studio.
1
for(x=0x0000;x<tabellenlaenge;x++)
2
  {
3
  y=abs(4095*sin(2*3.141592652*x/tabellenlaenge));

Das wird eher lange dauern, denn das ist eine echte Fließkommarechnung. 
Hier wäre Festkommaarithmetik deutlich schneller. Wahrscheinlich ist 
aber eine feste Sinustabelle noch schneller und hier sinnvoller.

>da die for schleife und das abspeichern ins das array datagram im
>verhältniss zum übertragen via SPI nicht ins gewicht fällt

Wenn das mal kein Irrrtum ist ;-)

> und ich eig.
>auch nur wissen muss wie lange die übertragung der 8192*5 (5*8bits)
>spi-datagramme dauert kann dies vernachlässigt werden.

>bei meiner rechnung komm ich nun auf folgendes.
>5mal SPI_transmit= 40bits=40SCK zyklen=40*4CLK zyklen

Plus geringfügige Pausen zwischen den Bytes, welche kaum vermeidbar 
sind. Rechne mal mit 1,5 bis 2mal soviel Zeit.

>also: t=(40*8192)*4/16MHz=0,08192s

Der Fachmann schreibt hier 81,9ms.

>ich habe aber ca. 6,5s gemessen.

Woran dass wohl liegt . . . ;-)

>wo liegt mein fehler.

Siehe ganz oben.

MFG
Falk

von Karl H. (kbuchegg)


Lesenswert?

Das hier
1
void SPI_Transmit(char sData)
2
{
3
/* Start transmission */
4
SPDR=sData;
5
/*Wait for transmission complete */
6
  while(!(SPSR & (1<<SPIF)))
7
  {
8
9
  }
10
11
}

könnte man auch umdrehen.
Wozu auf das Ende der Übertragung warten?
Während die SPI Einheit läuft, kann das Programm schon wieder an ganz 
anderen Dingen weiterarbeiten (zb. das nächste Byte ranschaffen). Dazu 
hab ich ja Spezialhardware. Die kann ganz alleine und ohne 
Programmaufsicht arbeiten.
Wichtig ist nur, dass die letzte Übertragung abgeschlossen ist, ehe 
versucht wird, das nächste Byte auf die Reise zu bringen

(und der richtige Datentyp für Bytes ist 'unsigned char' oder 'uint8_t' 
aber NIEMALS 'char'.
1
void SPI_Transmit( unsigned char sData )
2
{
3
  /* wait for SPI unit ready */
4
  while( !(SPSR & (1<<SPIF)) )
5
  {
6
  }
7
8
  /* transmit byte */
9
  SPDR = sData;
10
}

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
Noch kein Account? Hier anmelden.