Moin Leute,
ich habe das Problem, dass mein Controller (PIC24EP) in eine Art
Dauerschleife geht sobald ich "SPI1BUF = Wert;" ausführe. Ich verschicke
am Anfang der Main per UART einen String. Dieser wird einmal verschickt,
sobald ich den SPI1BUF auskommentiere. Wenn ich ihn nicht
auskommentiere, verschickt mein Controller in wiederholter Schleife
immer wieder den String vom Anfang der Main. Wisst ihr, woran das liegen
könnte?
Vielen Dank!
Daniel V. schrieb:> Vielleicht solltest du deinen Code komplett posten und jemand mit> PIC24> Erfahrung könnte dir weiter helfen.> Gibt's einen Watchdog?
Ich habe keinen Watchdog implementiert.
Daniel V. schrieb:> Du hast keinen SPI InterruptHandler implementiert....
Ist das denn notwendig? Ich finde nirgends Literatur dazu. Laut ISBN:
978-3-645-65273-5 ist keiner notwendig.
PIC schrieb im Beitrag #5490543:
> Ist das denn notwendig?
Selbstverständlich, da du ja
PIC schrieb im Beitrag #5490520:
> IEC0bits.SPI1IE = 1; // Enable the interrupt
im Code hast. Da hast du ja sogar im Kommentar geschrieben, daß du einen
Interrupt haben willst.
MfG Klaus
Klaus schrieb:> PIC schrieb im Beitrag #5490543:>> Ist das denn notwendig?>> Selbstverständlich, da du ja>> PIC schrieb im Beitrag #5490520:>> IEC0bits.SPI1IE = 1; // Enable the interrupt>> im Code hast. Da hast du ja sogar im Kommentar geschrieben, daß du einen> Interrupt haben willst.>> MfG Klaus
Und ein fehlender Interrupt erzeugt mit ein Reset?
Mir ist nicht ganz klar, wie ich den Interrupt programmiere. Ist es das
selbe wie beim UART?
Aktivere den Interrupt einfach nicht, dann brauchst du auch keinen
Handler dazu.
Falls du ihn aktivierst, wir der Controller den entsprechenden
Interruptvektor anspringen. Wenn da nix steht, dann gibts halt einen
Reset.
Ansonsten musst du ihn programmieren wie beim UART.
Daniel V. schrieb:> Aktivere den Interrupt einfach nicht, dann brauchst du auch keinen> Handler dazu.> Falls du ihn aktivierst, wir der Controller den entsprechenden> Interruptvektor anspringen. Wenn da nix steht, dann gibts halt einen> Reset.
Ah klasse! Vielen lieben Dank! Da habe ich nicht ganz zuende gedacht.
Wozu wäre ein Interrupt bei einer SPI Routine notwendig?
PIC schrieb im Beitrag #5490559:
> Wozu wäre ein Interrupt bei einer SPI Routine notwendig?
Gegenfrage:
Wozu wäre der Interrupt beim UART notwendig? Immerhin hast du einen
implementiert, wenn auch etwas merkwürdig :-)
Hallo Leute,
ich habe das ganze jetzt als Interrupt probiert. Leider funktionert die
SPI Ansteuerung dann nicht. Wisst ihr woran das liegen könnte? Interrupt
ist aktiviert.
void __attribute__((interrupt,auto_psv)) _SPI1Interrupt(void)
{
IFS0bits.SPI1IF = 0; // Clear SPI Interrupt flag
PORTBbits.RB0 = 0;
SPI1BUF = 0x3D21;
while (!SPI1STATbits.SPIRBF);
PORTBbits.RB0 = 1;
}
Felix schrieb:> Hallo Leute,>> ich habe das ganze jetzt als Interrupt probiert. Leider funktionert die> SPI Ansteuerung dann nicht. Wisst ihr woran das liegen könnte? Interrupt> ist aktiviert.>> void __attribute__((interrupt,auto_psv)) _SPI1Interrupt(void)> {> IFS0bits.SPI1IF = 0; // Clear SPI Interrupt flag> PORTBbits.RB0 = 0;> SPI1BUF = 0x3D21;> while (!SPI1STATbits.SPIRBF);> PORTBbits.RB0 = 1;> }
Das da:
> while (!SPI1STATbits.SPIRBF);
tut man nicht..
In einer ISR sollte man niemals warten. Warum? Weil man alle
niederpriorigeren Interrupts blockiert. So kann man beispielsweise ein
paar Bytes bei der UART-Kommunikation verpassen. Darum ist das ganz
allgemein keine gute Idee.
Du möchtest vermutlich das Chipselect bedienen, oder? Da wäre es
sinnvoller, das Chipselect des SPI-Modules zu verwenden. Dein Controller
hat Peripheral Pin select und SS kann man auf RB0 mappen, soweit ich das
gesehen habe.
Du hast ein PICkit3, oder? häng mal einen Breakpoint in die ISR.
Im Übrigen ist SPIRBF für den Recieve, du meinst vermutlich SPITBF?
jemand schrieb:> Das da:>> while (!SPI1STATbits.SPIRBF);> tut man nicht..> In einer ISR sollte man niemals warten. Warum? Weil man alle> niederpriorigeren Interrupts blockiert. So kann man beispielsweise ein> paar Bytes bei der UART-Kommunikation verpassen. Darum ist das ganz> allgemein keine gute Idee.
Du widersprichst Dir. "Niemals warten" ist natürlich Bullshit.
Beim STM32 z.B. ist es sehr sinnvoll, im DMA Stream Interrupt nach dem
Transfer Complete auf das Zurücksetzen des BSY-Flags zu warten, bevor
man den SPI abschaltet.
Generell sind solche Pauschalaussagen Unsinn, auch wenn hier im Forum
einige sie penetrant wiederholen.
Daher: Hirn einschalten!
Weihnachtsmann schrieb:> Du widersprichst Dir. "Niemals warten" ist natürlich Bullshit.> Beim STM32 z.B. ist es sehr sinnvoll, im DMA Stream Interrupt nach dem> Transfer Complete auf das Zurücksetzen des BSY-Flags zu warten, bevor> man den SPI abschaltet.
In der ISR? Das ist nicht dein Ernst, oder?
Wie gesagt, ein PIC24 hat priorisierte Interrupts. Du legst alle
niederpriorigeren lahm.
Warum, zum Henker, sollte man das wollen?
Der Controller kan im Endeffekt nicht mehr reagieren. Wenn man Dinge wie
Regler oder Überstromabschaltungen drin hat, geht die Schaltung hoch,
nur weil man in der ISR auf ein Flag wartet. Das ist sch...schlecht.
In diesem Fall gibt es mehrere besser Möglichkeiten:
- Chipselect vom SPI-Modul verwenden
- Den TX Interrupt so konfigurieren, dass er kommt, sobalt das Senden
fertig ist
Ich würde das so lösen, wenn man ein Chipselect UNBEDINGT manuell machen
will:
- TX-Interrupt so konfigurieren, dass er triggert, wenn er mit dem
senden fertig ist (Yupp, ein PIC24 kann das)
- Chipselect setzen, senden starten
- In der ISR Pin rücksetzen oder SPI abschalten oder weitersenden
Aber man blockiert in der ISR nicht den ganzen Controller. Auch keinen
STM32.