C atmega328上的SPI不工作

C atmega328上的SPI不工作,c,embedded,microcontroller,spi,atmel,C,Embedded,Microcontroller,Spi,Atmel,我们正在尝试使用SPI与另一个使用atmel atmega328 MCU的IC通信。目标IC接收一个命令(代码中的头),然后将存储在请求寄存器中的信息反馈给我们(如果该命令是写的,则写入)。然而,我们这里有两个问题: SPI中没有任何内容,唯一的变化是CS线路(由我们控制)。没有SPI时钟,数据线上没有数据 写入报头时for循环的第一次迭代程序不会进入while循环(端口6上的LED不会亮起) 如有任何帮助,将不胜感激,代码如下所示 #define DDR_SPI DDRB #define DD

我们正在尝试使用SPI与另一个使用atmel atmega328 MCU的IC通信。目标IC接收一个命令(代码中的头),然后将存储在请求寄存器中的信息反馈给我们(如果该命令是写的,则写入)。然而,我们这里有两个问题:

  • SPI中没有任何内容,唯一的变化是CS线路(由我们控制)。没有SPI时钟,数据线上没有数据

  • 写入报头时for循环的第一次迭代程序不会进入while循环(端口6上的LED不会亮起)

  • 如有任何帮助,将不胜感激,代码如下所示

    #define DDR_SPI DDRB
    #define DD_MISO DDB4
    #define DD_MOSI DDB3
    #define DD_SCK DDB5
    #define DD_SS DDB6
    
    void SPI_MasterInit(void)
    {
        /* Set MOSI, SCK and CS output, all others input */
        DDR_SPI = (1<<DD_MOSI)|(1<<DD_SCK)|(1<<DD_SS);
        /* Enable SPI, Master, set clock rate = System clock / 16 */
        SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
    }
    
    int readfromspilow(uint16 headerLength, const uint8 *headerBuffer, uint32 readLength, uint8 *readBuffer)
    {
    
    
        PORTB &= ~(1 << PORTB6);                // Set CS low
    
        for(int i=0; i<headerLength; i++)
        {
            SPDR = headerBuffer[i];             //Send entry i of the header to the spi register
            sleep_us(5);                        // Give the flag time to reset, might be unnecessary
            PORTD |= (1 << PORTD5);             //LED for diagnostics
            while(!(SPSR & (1<<SPIF))){         //Wait for SPIFinished flag
                PORTD |= (1 << PORTD6);         //LED for diagnostics
            }
    
            PORTD &= ~(1 << PORTD3);            //LED for diagnostics
    
    
    
            //readBuffer[0] = SPDR; // Dummy read as we write the header
        }
    
        for(int i=0; i<readLength; i++)
        {
            SPDR = 0xFF;                        // Dummy write as we read the message body
            sleep_us(5);                        // Give the flag time to reset, might be unnecessary
            while(!(SPSR & (1<<SPIF)));         //Wait for SPIFinished flag
            readBuffer[i] = SPDR ;              //Store the value in the buffer
        }
    
        PORTB |= (1 << PORTB6);                 // Set CS high
    
    
        return;
    }
    
    #定义DDR\u SPI DDRB
    #定义DD_MISO DDB4
    #定义DD_MOSI DDB3
    #定义DD_SCK DDB5
    #定义DD_SS DDB6
    void SPI_MasterInit(void)
    {
    /*设置MOSI、SCK和CS输出,所有其他输入*/
    
    DDR_SPI=(1您的代码似乎是正确的,但由于您没有使用SPI中断处理程序,您需要在通过SPDR发送数据之前清除SPSR中的SPIF位。SPDR不接受任何设置了SPIF标志的数据。

    根据手册19.5.2

    或者,通过首先读取SPI状态来清除SPIF位 使用SPIF集合注册,然后访问SPI数据寄存器(SPDR)

    您的代码不执行此操作,因此可能存在一个从未清除的标志集。请尝试将代码更改为:

    volatile uint8_t spsr = SPSR;       //Dummy-read the flag register to clear flags
    SPDR = headerBuffer[i];             //Send entry i of the header to the spi register
    PORTD |= (1 << PORTD5);             //LED for diagnostics
    while(!(SPSR & (1<<SPIF))){         //Wait for SPIFinished flag
      PORTD |= (1 << PORTD6);           //LED for diagnostics
    }
    
    volatile uint8\u t spsr=spsr;//虚拟读取标志寄存器以清除标志
    SPDR=headerBuffer[i];//将头的条目i发送到spi寄存器
    
    PORTD |=(1我们解决了这个问题,问题是端口B2上的默认SS需要在初始化阶段定义为输出,否则,如果引脚保持浮动,MCU可以更改为从属操作模式。这会在每次发生时将SPIF标志设置为1,这会干扰我们的检查。

    您以后在代码中如何使用它?DDR_SPI和o是什么位匹配?while循环等待SPI完成停止吗?我们只需调用readfromspilow,并将所需命令作为头(地址等)调用我们希望读取的寄存器)预期答案的长度为读取长度,缓冲区中有一个点用于存储读取答案。我通过编辑添加了SPI的定义,不确定“位匹配”是什么意思。while跳过了第一次迭代(不知道为什么),但在下一次迭代中被卡住了(可能是因为SPI从未发出信号完成)