ATMEGA2561 WINC1500驱动实现SPI问题

Posted

技术标签:

【中文标题】ATMEGA2561 WINC1500驱动实现SPI问题【英文标题】:ATMEGA2561 WINC1500 Driver implementation SPI problem 【发布时间】:2020-04-02 11:49:42 【问题描述】:

我正在尝试实现 WINC1500 MLA 驱动程序以与 ATMEGA2561 MCU 一起工作,我已经编写了我的驱动程序代码,它卡在“while((SPSR & (1

我不知道为什么它没有进展。我正在为这个项目使用 Jumpstart ImageCraft IDE。

这是它的实现

void m2mStub_SpiTxRx(uint8_t *p_txBuf,
                     uint16_t txLen,
                     uint8_t *p_rxBuf,
                     uint16_t rxLen)

    uint16_t byteCount;
    uint16_t i;

    // Calculate the number of clock cycles necessary, this implies a full-duplex SPI.
    byteCount = (txLen >= rxLen) ? txLen : rxLen;
    DEBUGOUTF("Calculate the number of clock cycles\n");

    DEBUGOUTF("byteCount %d", byteCount, "\n");
    DEBUGOUTF("txLen %d", txLen, "\n");
    DEBUGOUTF("rxLen %d", rxLen, "\n");

    // Read / Transmit.
    for (i = 0; i < byteCount; ++i)
    
        // Wait for transmitter to be ready. (This is causing the entire thing to crash)
        while((SPSR & (1 << SPIF)) == 0);

        // Transmit.
        if (txLen > 0)
        
            // Send data from the transmit buffer.
            SPDR = (*p_txBuf++);
            --txLen;
        
        else
        
            // No more Tx data to send, just send something to keep clock active.
            SPDR = 0x00U;
        

        // Wait for transfer to finish.
        while((SPSR & (1 << SPIF)) == 0);

        // Send dummy data to slave, so we can read something from it.
        SPDR = 0x00U;

        // Wait for transfer to finish.
        while((SPSR & (1 << SPIF)) == 0);

        // Read or throw away data from the slave as required.
        if (rxLen > 0)
        
            *p_rxBuf++ = SPDR;
            --rxLen;
        
        else
        
            // Clear the registers
            volatile uint8_t reg_clear = 0U;
            reg_clear = SPDR;
            (void)reg_clear;
        

    

【问题讨论】:

好吧,您说“导致整个事情崩溃”,但您的其余描述听起来更像是挂起而不是崩溃。如果发射器根本没有准备好,或者没有正确连接,或者类似的事情,这是可以预料的!我想说你应该从调试你的 SPI 连接开始 【参考方案1】:

我没有足够的信息可以肯定地说,但我的假设是您的 SPI 连接设置不正确。

特别是,我猜你忘记将/SS 设置为输出,与this problem 或this 相同。

在数据表中它说:

主机模式 当 SPI 被配置为主机时(SPCR 中的 MSTR 为 设置),用户可以确定SS引脚的方向。

如果SS配置为输出,则该管脚为通用输出管脚 这不会影响 SPI 系统。通常,该引脚将是 驱动 SPI 从机的 SS 引脚。

如果SS配置为输入,则必须保持高电平以确保Master SPI 操作。 如果 SS 引脚被外围电路驱动为低电平 当 SPI 配置为主机,SS 引脚定义为 输入,SPI系统将此解释为另一个主选择 SPI 作为从机并开始向其发送数据。为了避开公交车 争用,SPI系统采取以下行动:

    SPCR 中的 MSTR 位被清零,SPI 系统成为从机。由于 SPI 成为从机,MOSI 和 SCK 引脚变为 输入。 SPSR 中的 SPIF 标志被置位,如果 SPI 中断被使能,并且 SREG 中的 I 位被置位,将执行中断程序。

因此,当在主模式下使用中断驱动的 SPI 传输时, 并且存在 SS 被驱动为低电平的可能性,中断 应始终检查 MSTR 位是否仍然设置。如果 MSTR 位 已被从机选择清零,它必须由用户设置为 重新启用 SPI 主模式。

因此,您只需将/SS 引脚配置为输出并在您的初始化代码中设置为高,这应该可以解决您的问题:

DDRB |= (1 << PB0); // Set /SS (PB0) as output
PORTB |= (1 << PB0); // Set /SS (PB0) high

【讨论】:

感谢您的回复,但我已将 SS Pin 配置为您提到的输出并将其设置为高,但仍未解决问题

以上是关于ATMEGA2561 WINC1500驱动实现SPI问题的主要内容,如果未能解决你的问题,请参考以下文章

使用 UDRE 和 ATmega328P 的中断驱动 USART

AVR - 高速中断驱动的 UART 代码不工作

A3992学习记录

arduinonanol灯频闪,程序没运行

bzoj 2561: 最小生成树

HDU 2561 二小整数