Hallo,
Ich habe nur einen Interrupthandler. Dieser ist für drei interrupts
zuständig. (SPI)
Er löst die ganze Zeit und es kommt zu dem Watchdogfehler, das Programm
kehrt nicht in die Main zurück. Leider kann ich den Fehler nicht finden.
1
// Includes ----------------------------------------------------------------------------------------
2
#include<hidef.h> /* for EnableInterrupts macro */
3
#include"derivative.h" /* include peripheral declarations */
Ein Bit bzw. Flag bekomme ich nicht gelöscht.
"This bit is set when there is room in the transmit data buffer. It is
cleared byreading SPI1S with SPTEF set, followed by writing a data value
to the transmit buffer at SPI1D. SPI1S must be read with SPTEF = 1
before writing data to SPI1D or the SPI1D write will be ignored. SPTEF
generates an SPTEF CPU interrupt request if the SPTIE bit in the SPI1C1
is also set. SPTEF is automatically set when a data byte transfers from
the transmit buffer into the transmit shift register. For an idle SPI
(no data in the transmit buffer or the shift register and no transfer in
progress), data written to SPI1D is transferred to the shifter almost
immediately so SPTEF is set within two bus cycles allowing a second
8-bit data value to be queued into the transmit buffer. After completion
of the transfer of the value in the shift register, the queued value
from the
transmit buffer will automatically move to the shifter and SPTEF will be
set to indicate there is room for new data in the transmit buffer. If no
new data is waiting in the transmit buffer, SPTEF simply remains set and
no data moves from the buffer to the shifter.
0 SPI transmit buffer not empty
1 SPI transmit buffer empty"
Hier ein auszug aus dem Datenblatt.
Sobald ich keine neuen Daten mehr schreiben will, und das SPTEF Flag
gesetzt bleibt, löst die ganze Zeit das Interrupt aus.
"SPTEF simply remains set..." Genau das versuche ich eigentlich...
Jemand eine Idee?
#Nachtrag:
1
__interruptVectorNumber_Vspi1voidISR_SPI(){
2
3
uint8Temp;
4
uint8Tempo1;
5
uint8Tempo2;
6
7
8
9
//Flags speichern
10
Tempo1=SPI1S_SPRF;
11
Tempo2=SPI1S_SPTEF;
12
13
//Flags löschen
14
SPI1S_SPRF=0;
15
SPI1S_SPTEF=0;
16
17
18
if(Tempo1==1){
19
20
Temp=spi_receiveData();
21
}
22
elseif(Tempo2==1)
23
{
24
//schreibbereit
25
}
26
else{
27
//Fehler
28
}
29
30
}
So versuche ich es mittlerweile, leider auch ohne Erfolg. Einfach 0
setzen geht nicht.
>Mach doch mal aus dieser Zeile
Sollte nichts ändern, wenn der obige Code vollständig ist.
Beinhaltet: "spi_enableInterrupt(true);" auch das obligatorische "sei;"?
Jan R. schrieb:> Sobald ich keine neuen Daten mehr schreiben will, und das SPTEF Flag> gesetzt bleibt, löst die ganze Zeit das Interrupt aus.
Das ist ja auch richtig, damit die Übertragung überhaupt gestartet wird.
Nachdem das letzte Byte übertragen wurde, mußt Du den Interrupt
abschalten.
Das könnte so aussehen:
spi_enableInterrupt(false);
Ich kenne Deinen Prozessor nicht, aber "Frage an Radio Eriwan"
Wie wichtig ist die Sequenz:
Temp = SPI1D;
eigentlich?
Ein Compiler, der was auf sich hält, streicht diesen Befehl ersatzlos,
da Temp in der Folge nicht verwendet wird.
Stichwort: volatile.
M. N. schrieb:> Das ist ja auch richtig, damit die Übertragung überhaupt gestartet wird.> Nachdem das letzte Byte übertragen wurde, mußt Du den Interrupt> abschalten.>> Das könnte so aussehen:> spi_enableInterrupt(false);
Ok, dass wusste ich so nicht. Dann muss ich das Interrupt einfach
ausschalten.
Bei der jetztigen Codeversion habe ich das Interrupt noch nicht
ausgeschaltet, aber es funktioniert in dem Sinne von es schreibt die
ganze Zeit.
// SPI Data Buffer lesen um Interrupt Bit zu leeren
12
Temp=SPI1D;
13
returntrue;
14
}
15
}
Den Watchdog sollte man ja eigentlich nciht im Interrupt feeden. Wenn
ich es allerdings nicht mache, wird das Watchdoginterrupt nach etwa 20
Durchläufen des Sendevorgangs ausgelöst. Ziemlich komisch, es werden
keine Fehler angezeigt -> COP Watchdog caused a Reset
Hat hier noch jemand eine Idee?
Controller: MC9S08AW60 (freescale)
http://www.freescale.com/files/microcontrollers/doc/data_sheet/MC9S08AW60.pdf
Auf jeden Fall schon mal vielen Dank für die hilfreichen Antworten!
Datenblatt Seite 179
"
10.6.1 Clearing Timer Interrupt Flags
TPM interrupt flags are cleared by a 2-step process that includes a read
of the flag bit while it is set (1)
followed by a write of 0 to the bit. If a new event is detected between
these two steps, the sequence is reset
and the interrupt flag remains set after the second step to avoid the
possibility of missing the new event.
"
Ich kann euch mitteilen, dass es so ist. Wieso wird bei mir leider
schwer...
Aber sehe ich das richtig, dass man zwangsläufig in der ISR den
Schreibvorgang starten muss.
Ein solches Konstrukt funktioniert nicht:
1
main(){
2
while(sbufferpos<buffergöße)
3
{
4
SendeData(bufferpos);
5
}
6
}
7
8
ISR()
9
{
10
if(Transmissionbuffer==empty)
11
{
12
sbufferpos++;
13
}
14
}
Wenn man es so machen würde, würde das Interrupt ja permanent ausgelöst
werden, da das Transmissionbufferemptyflag nicht acknowledged wird. Sehe
ich das richtig?