Hallo, ich habe folgende Frage. Ich arbeite mit einem ATXMega128A1 und habe 4 SPI Teilnehmer an einer SPI Schnittstelle (Port F) F_CPU 8MHz prescaler 4 Das hat auch immer mit allen Busteilnehmer funktioniert allerdings muss ich für einen neue SPI Teilnehmer die Geschwindigkeit herabsetzen. Kann man das in der Software ? Für jeden Busteilnehmer einen anderen prescaler definieren also während das programm läuft den prescaler einfach korrigieren ? SPI_MasterInit(&spiMasterF, &SPIF, &PORTF, false, SPI_MODE_0_gc, SPI_INTLVL_OFF_gc, false, SPI_PRESCALER_DIV4_gc); Müsste ich dann jedesmal wenn ich die Geschw. korrigiere diese Funktion aufrufen ? Vielen dank für Eure Bemühungen. Ich hoffe das ich mein problem verständlich dargestellt habe. MfG
Andreas S. schrieb: > Für jeden Busteilnehmer einen anderen > prescaler definieren also während das programm läuft den prescaler > einfach korrigieren ? Prinzipiell ja. Zumindest die Hardware hat da nichts dagegen. > SPI_MasterInit(&spiMasterF, > &SPIF, > &PORTF, > false, > SPI_MODE_0_gc, > SPI_INTLVL_OFF_gc, > false, > SPI_PRESCALER_DIV4_gc); > > Müsste ich dann jedesmal wenn ich die Geschw. korrigiere diese Funktion > aufrufen ? Tja. Da musst du mal in diese SPI Library reinschauen, was dir die an Funktionen anbietet und unter Umständen dann eben eine Funktion nachrüsten, mit der du nur den Prescaler änderst.
Hallo, das ganze basiert auf die application notes von Atmel. Und die sieht so aus. void SPI_MasterInit(SPI_Master_t *spi, SPI_t *module, PORT_t *port, bool lsbFirst, SPI_MODE_t mode, SPI_INTLVL_t intLevel, bool clk2x, SPI_PRESCALER_t clockDivision) { spi->module = module; spi->port = port; spi->interrupted = false; spi->module->CTRL = clockDivision | /* SPI prescaler. */ (clk2x ? SPI_CLK2X_bm : 0) | /* SPI Clock double. */ SPI_ENABLE_bm | /* Enable SPI module. */ (lsbFirst ? SPI_DORD_bm : 0) | /* Data order. */ SPI_MASTER_bm | /* SPI master. */ mode; /* SPI mode. */ /* Interrupt level. */ spi->module->INTCTRL = intLevel; /* No assigned data packet. */ spi->dataPacket = NULL; /* MOSI and SCK as output. */ spi->port->DIRSET = SPI_MOSI_bm | SPI_SCK_bm; } Jetzt kann ich natürlich eine Funktion ergänzen sodass ich nur noch den prescaler verändere. OK Spricht etwas dagegen die ganze Initialisierung nochmal mit dem neuen prescaler aufzurufen ? Das ich dadurch Zeit vergeude weiss ich auch aber für mich wäre das zunächst die einfachste Variante.
Klar, kannst Du machen. In die anderen Register wird dann halt nochmal das geschrieben, was schon drinnen stand. Kostet ein paar Takte mehr, sollte aber keine Nebenwirkungen haben.
hi, ich hab mal festgestellt, dass vor Änderungen die register resettet werden müssn sonst kommt das timinig beim umschalten durceinander bye
@QUAX kannst du noch etwas mehr dazu schreiben. Und wie hast du die Register resettet ? Wenn ich alle neu ueberschreibe und das ganze eh nicht im Interrupt laufen habe sollte es doch keine Probleme geben.
Hallo, das Ganze schaut auf unterster Ebene so aus: z.B. SPIF.CTRL=SPI_MODE_0_gc|SPI_PRESCALER_DIV4_gc|(1<< SPI_ENABLE_bp)|(1<< SPI_MASTER_bp); SPIF.INTCTRL = SPI_INTLVL_OFF_gc; SPIF.STATUS = 0; Nach dem die Datenübertragung abgeschlossen ist, würde ich den SPIF mit: SPIF.CTRL &= ~(1<<SPI_ENABLE_bp) sperren und anschließend mit den veränderten Prescaler wieder starten. SPIF.CTRL = SPI_PRESCALER_DIV64_gc|(1<< SPI_ENABLE_bp)wieder aktivieren. SPIF.STATUS = 0; Ein Versuch is es wert! Gruß G.G.
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.