PICのSPIクロックが不安定


8

PIC18F25K22の MSSPモジュールをSPIマスターモードに構成しようとしています。タイミングを見ていると、送信全体を通してクロックが安定していません。写真は言葉よりもそれをよく示しています。 SPIタイミング図

ビットが送信された後、クロックは短くなり、毎回同じ量ではありません。これまでにSPIを使用したことはありませんが、ウィキペディアや他のリソースで見つけた図には、これが表示されていません。私はArduinoも接続しましたが、この動作は見られませんでした。私のコードは:

    #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
}

(またhttps://gist.github.com/stumpylog/5095250

誰かがこれに遭遇したり、原因について提案したりしていますか?

私がしたこと

結局、MSSP1モジュールを機能させることができませんでした。ただし、MSSP2モジュールに変更すると、まったく同じコードで、この動作は発生しませんでした。説明できませんが、問題は解決しました。


SPIを使用するためのコードを提示できますか?
Gustavo Litovsky 2013

1
一般に、SPI(およびI2Cも)は不均一なクロックで動作します。SPIは同期です。同時に、ハードウェアMSSPが不均一なクロックを生成するのは奇妙に思われます。データライン(緑)が低い場合、クロックは均一です。データラインが高い場合、クロックは短くなります。念のため、PICのエラッタを確認してください。
Nick Alexeev

@GustavoLitovsky質問にコードを直接追加しました。
Trenton Holmes

@NickAlexeevありがとう、私はそれを見ました。MSSPモジュールについては何も言及されていません。私のスレーブがタイミングをそのまま処理できるかどうかを確認する必要があります。
Trenton Holmes

おそらくあなたの問題とは無関係ですが、あなたのポートのANSELビットをクリアするコードは見当たりません。マイクロチップは、ピンをデジタルではなくデフォルトでアナログ入力にするという迷惑な選択をしました。
apalopohapa 2013年

回答:


3

これは推測ですが、各バイトにしてはいけないものをリセットしている可能性があります。ビットレートジェネレーターや一般的な周辺機器構成などの設定は、1回だけ行う必要があります。

追加:

これで、MSSP1を機能させることができなかったが、MSSP2は機能するようになりました。これは、意図しない書き込みを行っているコードのどこかにバグがあることを示しています。それはたまたまいくつかのMSSP1状態にぶつかっています。それが奇妙に動作し、MSSP2が機能する理由です。

これを手放すだけではいけません。MSSP2に移行することで問題が解決したように見えるかもしれませんが、せいぜい一時的に回避するだけで済みます。次に別の場所にあるものとリンクすると、別のメモリが落書きされる可能性があります。これを見つけて実際に修正しないと、このファームウェアは永久に不安定になります。最悪のケースは、明らかな症状がなく、問題があることを明確にすることを好む場合です。この問題は、1年後に適切なデータが検出されたときに表示されます。フィールドに1000があった後、顧客サイトのみが表示されます。これを正しい方法で今すぐ修正します。


2

シグナルインテグリティの問題が発生している可能性があります。LAショットでは、データラインが落ちるときにクロックラインのグリッチが表示されます。2つが十分に分離され、トレースまたは配線が長すぎないことを確認してください。また、クロックレートを遅くするか、ラインに小さなRCフィルターを追加してみます(ラインが長い場合は、たとえば220Ωの直列抵抗だけが役立つ場合があります)。

オシロスコープを使用している場合は、これを使用してラインをチェックし、シグナルインテグリティが良好であることを確認してください。そうでない場合は、上記の提案を試して、信号の品質が良くなるまで調整してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.