SPI Interrupt wird ZU SPÄT ausgelöst nach Sendevorgang
Hallo zusammen,
wie am Titel zu erkennen, habe auch ich gerade Probleme mit SPI. Es handelt sich bei mir um einen PIC18, der als SPI-Slave mit SS betrieben wird, interner Clock (16MHz).
Problem: Der interrupt wird viel zu spät ausgelöst: es vergehen 11,5µs zwischen <jetzt müsste er auslösen> und <der Ausgang RD5 wurde umgeschalten>. RD5=0 bleibt für 10µs erhalten.
Umgehe ich die interrupt-Routine und baue in der Main-Routine eine Abfrage des PIR1bits.SSPIF == 1 und schalte dann den Ausgang RD5=0, geschieht das mit einem Verzug von etwa 1,1-2,4µs (Jitter natürlich deutlich stärker). RD5 bleibt ca. 1,5µs auf low.
Code:
void spi_init(void) {
INTCON = 0; // Disable all interrupts
PIE1 = 0;
PIR1 = 0;
// ----------------------------
SSPCON1bits.SSPEN = 0; // SSPCON1[5]; Allow Programming of serial port
SSPCON1bits.CKP = 1; // SSPCON1[4]; Clock Polarity Select bit; Idle state for clock is a HIGH level
SSPCON1bits.SSPM3 = 0; // SSPCON1[3]; Synchronous Serial Port Mode Select bits
SSPCON1bits.SSPM2 = 1; // SSPCON1[2]; [3-0] 0100 = SPI Slave mode, clock = SCK pin, SS pin control enabled
SSPCON1bits.SSPM1 = 0; // SSPCON1[1];
SSPCON1bits.SSPM0 = 0; // SSPCON1[0];
// ----------------------------
SSPSTATbits.SMP = 0; // SSPSTAT[7]; Input data sampled at middle data output time
SSPSTATbits.CKE = 0; // SSPSTAT[6]; Transmit occurs on active to idle clock state
// ----------------------------
PIE1bits.SSPIE = 1;
PIR1bits.SSPIF = 0; // Master Synchronous Serial Port Interrupt Flag bit (must be cleared by Software)
// 0 = Waiting to transmit/receive
INTCONbits.PEIE = 1; // Enable Peripheral interupts
INTCONbits.GIE = 1; // Global Interupt enable
SSPCON1bits.SSPEN = 1; // End programming and Start serial port
}
ISR:
Code:
void interrupt isr(void)
{
if (PIR1bits.SSPIF == 1)
{
spi_reg_addr=SSPBUF;
SSPBUF=0x00;
RD5=0;
PIR1bits.SSPIF = 0;
}
}
Main:
Code:
void main(){
pic_init();
spi_init();
while(1)
{
PORTDbits.RD5=1;
}
}
Woran kann es liegen, dass die Interrupt-Routine so spät auslöst bzw. wie kann man es beschleunigen?
Grüß,
NRicola
Liste der Anhänge anzeigen (Anzahl: 2)
Ich finde der Compiler sollte umsonst sein, (logisch aus privaten Interesse natürlich ;))
Aber eine Verbreitung der Chips geht meiner Meinung nach auch durch Privatanwender voran,
was ich privat nutze, setzte ich dann auch in der Entwicklung in der Firma ein.
Bei mir war es zumindest so.
-----------
Zum Thema Assembler Listing:
Um ein Assembler Listing zu bekommen must Du erst etwas einstellen: ich beziehe mich auf die MPLABX-IDE
Du klickst oben im Menü
File
Project Properties
oder auch rechte Maustaste in dem Projects Fenster links.
Dann gibt es vermutlich 2 Konfigurationen
eventuell aber auch nur eine.
Dort musst Due auf Conf und dann den Unterpunkt "Loading" wählen.
Hier muss rechts in das Kästchen ein Haken rein bei "Load symbols when......
Nun musst das Projekt neu compiliert (Builded) werden.
Erst dann wird auch ein Assembler File erstellt.
Nun gehst Du oben im Menü auf
"Window" --> Debugging --> Output --> Disamply listing file
Nun sollte sich das Assembler Fenster öffnen.
Bei mir heisst die Funktion
void __interrupt isr(void)
Dann kannst Du Dir den erzeugten code anschauen.
Ich hab mal Bildchen angehangen: