PIC上的SPI时钟不稳定


8

我正在尝试将PIC18F25K22的MSSP模块配置为SPI主模式。我正在查看时序,并且整个传输过程中的时钟都不稳定。图片比文字更能说明问题。 SPI时序图

发送一个比特后,时钟会缩短,并且每次不会缩短相同的时间。我以前没有使用过SPI,但是我在Wikipedia和其他资源上找到的图表从未显示过。我还连接了一个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的代码吗?
古斯塔沃·利托夫斯基2013年

1
通常,SPI(以及I2C)也可以使用非均匀时钟。SPI是同步的。同时,硬件MSSP生成不均匀的时钟似乎很奇怪。当数据线(绿色)为低电平时,您的时钟是一致的。当数据线为高电平时,您的时钟较短。以防万一,请检查您的PIC的勘误表。
尼克·阿列克谢夫

@GustavoLitovsky我现在将代码直接添加到问题中。
特伦顿·福尔摩斯

@NickAlexeev谢谢,我看看了。没有提及有关MSSP模块的信息。我必须检查我的奴隶是否可以按时处理时间。
特伦顿·福尔摩斯

可能与您的问题无关,但是我看不到用于清除端口的ANSEL位的代码。Microchip做出了令人讨厌的选择,即默认情况下将引脚设为模拟输入而不是数字输入。
apalopohapa13年

Answers:


3

这是一个猜测,但是您可能正在重置一些不该每个字节的内容。诸如比特率发生器和一般外围设备配置之类的东西只能设置一次。

添加:

您现在说您无法使MSSP1正常工作,但确实使MSSP2正常工作。这暗示您在代码中其他地方正在执行意外写入的错误。它碰巧碰到了某种MSSP1状态,这就是为什么它的行为异常以及MSSP2起作用的原因。

不要只是放手。迁移到MSSP2可能似乎已解决了该问题,但充其量您可能已经暂时解决了此问题。下次您在不同位置链接事物时,可能会乱涂上不同的内存。如果找不到并真正解决此问题,则该固件将永远是片状的。最坏的情况是,当没有明显的症状使您忙于明确出现问题时。一年后,当仅遇到正确的数据时,该问题就会出现,只有1000个客户站点在现场。立即修复此问题。


2

看来您可能有信号完整性问题-在LA镜头中,当数据线掉落时,时钟线出现了毛刺。尝试确保两者隔离良好,走线或布线不要太长。您还可以尝试降低时钟速率或在线路上添加一个小型RC滤波器(如果线路较长,则仅串联一个220Ω的电阻会有所帮助)

如果您有示波器,请检查示波器的线路,以确保信号完整性良好。如果不是,请尝试上述建议并进行调整,直到信号质量良好为止。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.