Ich versuche, das MSSP-Modul eines PIC18F25K22 im SPI-Master-Modus zu konfigurieren . Ich schaue auf das Timing und die Uhr bleibt nicht während der gesamten Übertragung stabil. Ein Bild zeigt es besser als Worte.
Nachdem ein Bit gesendet wurde, verkürzt sich die Uhr und nicht jedes Mal um den gleichen Betrag. Ich habe noch nie mit SPI gearbeitet, aber die Diagramme, die ich auf Wikipedia und anderen Ressourcen gefunden habe, zeigen dies nie. Ich habe auch einen Arduino angeschlossen und dieses Verhalten nicht gesehen. Mein Code lautet:
#pragma config FOSC = INTIO67 // Oscillator Selection bits (Internal oscillator block)
#pragma config PLLCFG = OFF // 4X PLL Enable (Oscillator used directly)
#pragma config BOREN = OFF // Brown-out Reset Enable bits (Brown-out Reset disabled in hardware and software)
#pragma config WDTEN = OFF // Watchdog Timer Enable bits (Watch dog timer is always disabled. SWDTEN has no effect.)
#pragma config MCLRE = EXTMCLR // MCLR Pin Enable bit (MCLR pin enabled, RE3 input pin disabled)
#pragma config LVP = OFF // Single-Supply ICSP Enable bit (Single-Supply ICSP disabled)
#pragma config XINST = OFF // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))
void main(void)
{
OSCCON = 0b11100110;
spi_setup();
__delay_ms(10);
byte temp;
while (TRUE)
{
temp = spi_transfer(0x00);
temp = spi_transfer(0x01);
temp = spi_transfer(0x02);
temp = spi_transfer(0x03);
temp = spi_transfer(0x04);
temp = spi_transfer(0x05);
__delay_us(1);
}
}
void spi_setup(void)
{
SSP1STAT = 0b00000000;
SSP1STATbits.CKE = HIGH; // data transmitted on rising edge
SSP1CON1 = 0b00000000; // enable Master SPI mode
SSP1CON1bits.CKP1 = LOW; //clock idle state is low
//i2c bits, all don't matters for SPI, cleared just in case
SSP1CON3 = 0;
// baud rate generation
SSP1ADD = 0; //FCLOCK = 8Mhz /2 = 2Mhz
// configure pins for output/input as needed
SDI1 = INPUT;
SDO1 = OUTPUT;
SCK1 = OUTPUT;
SS1 = OUTPUT;
SSP1CON1bits.SSPEN1 = HIGH; // enable pins for serial mode
}
unsigned char spi_transfer(unsigned char data)
{
SS1_LAT = LOW; // select slave
PIR1bits.SSPIF = LOW;
SSP1BUF = data;
//while (!SSP1STATbits.BF); //wait for receive to complete
while( !PIR1bits.SSPIF );
SS1_LAT = HIGH; // deselect slave
PIR1bits.SSPIF = LOW; // clear interrupt
return SSP1BUF; //return data from the slave
}
(auch https://gist.github.com/stumpylog/5095250 )
Ist jemand darauf gestoßen oder hat er Vorschläge zur Ursache?
Was ich getan habe
Am Ende konnte ich das MSSP1-Modul nicht zum Laufen bringen. Das Ändern in das MSSP2-Modul, genau derselbe Code, zeigte dieses Verhalten jedoch nicht. Ich kann es nicht erklären, aber das hat das Problem gelöst.
Antworten:
Dies ist eine Vermutung, aber Sie setzen wahrscheinlich etwas zurück, das nicht jedes Byte sein sollte. Dinge wie der Bitratengenerator und die allgemeine Peripheriekonfiguration sollten nur einmal eingestellt werden.
Hinzugefügt:
Sie sagen jetzt, dass Sie MSSP1 nicht zum Laufen bringen konnten, aber MSSP2 zum Laufen gebracht haben. Dies deutet darauf hin, dass Sie an anderer Stelle im Code einen Fehler haben, der unbeabsichtigte Schreibvorgänge ausführt. Es trifft zufällig einen MSSP1-Status, weshalb es seltsam wirkt und warum MSSP2 funktioniert.
Lass das nicht einfach los. Der Wechsel zu MSSP2 scheint das Problem behoben zu haben, aber Sie haben es bestenfalls umgangen, wahrscheinlich vorübergehend. Wenn Sie das nächste Mal an verschiedenen Stellen mit Dingen verknüpfen, wird möglicherweise ein anderer Speicher darauf gekritzelt. Wenn Sie dies nicht finden und wirklich beheben, wird diese Firmware für immer schuppig sein. Der schlimmste Fall ist, wenn es keine offensichtlichen Symptome gibt, die Ihnen den Gefallen tun, um klar zu machen, dass es ein Problem gibt. Das Problem tritt dann ein Jahr später auf, wenn genau die richtigen Daten gefunden werden, nur ein Kundenstandort, nachdem 1000 im Feld sind. BEHEBEN SIE DAS JETZT RICHTIG.
quelle
Es sieht so aus, als hätten Sie möglicherweise Probleme mit der Signalintegrität. Bei der LA-Aufnahme scheint die Taktleitung fehlerhaft zu sein, wenn die Datenleitung abfällt. Stellen Sie sicher, dass die beiden gut isoliert sind und die Leiterbahn oder Verkabelung nicht zu lang ist. Sie können auch versuchen, die Taktrate zu verlangsamen oder ein kleines RC-Filter in die Leitungen einzufügen (wenn die Leitungen lang sind, kann nur ein Vorwiderstand von beispielsweise 220 Ω hilfreich sein).
Wenn Sie ein Oszilloskop haben, überprüfen Sie die Linien damit, um sicherzustellen, dass die Signalintegrität gut ist. Wenn dies nicht der Fall ist, probieren Sie die obigen Vorschläge aus und passen Sie die Einstellungen an, bis Sie Signale von guter Qualität erhalten.
quelle