SPI 在 atmega328p 上不起作用

Posted

技术标签:

【中文标题】SPI 在 atmega328p 上不起作用【英文标题】:SPI not working on atmega328p 【发布时间】:2018-02-08 08:46:27 【问题描述】:

我正在尝试对 atmega328p 进行编程,但 SPI 总线无法正常工作。它不会通过总线发送任何数据。

我的代码如下:

#include <asf.h>
#include <stdio.h>
#include <main.h>

int main (void)

    board_init();
    SPI_MasterInit();

    DDRD = (1<<DDD5);

    while(1)
    
        PORTB &= ~(1<<DDB2);
        SPI_MasterTransmit(0xAB);
        PORTB |= (1<<DDB2);

        PORTD ^= (1<<DDD5);
    


void SPI_MasterInit(void)

    /* Set MOSI and SCK output, all others input */
    DDRB = (1<<5) || (1<<3) || (1<<2);
    /* Enable SPI, Master, set clock rate fck/16 */
    SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);


void SPI_MasterTransmit(char cData)

    /* Start transmission */
    SPDR = cData;
    /* Wait for transmission complete */
    while(!(SPSR & (1<<SPIF)));

我正在尝试通过总线 (0xAB) 发送一些随机数据,以检查总线是否正常工作,以便添加更多代码。在 while 循环中,我还设置了一个引脚。

在我的示波器图像上,我看到 SPI 引脚 MOSI 上没有发送数据,并且 CLK 引脚也没有发送信息。 PB5(我每次尝试发送数据时都会反转的引脚)正在工作,并且周期约为 20 微秒。

我正在通过 Atmel ICE 对 Atmega328p 进行编程。编程接口也通过 SPI,我在某处读到这可能是一个问题。我不完全确定。

有谁知道可能是什么问题?

【问题讨论】:

【参考方案1】:

我的第一个猜测是没有将 SS 引脚 (PB2) 设置为输出。它可能会导致几乎随机切换到从模式。但是好像设置为输出(cmets中没有说明)。

但是仔细看这个表达式,很明显它根本没有设置:

DDRB = (1<<5) || (1<<3) || (1<<2);

逻辑或||与按位或|之间存在巨大差异。

【讨论】:

解决了这个问题。有点愚蠢的错误。谢谢。

以上是关于SPI 在 atmega328p 上不起作用的主要内容,如果未能解决你的问题,请参考以下文章

为啥 pull-right 类在 bootstrap 版本 4.1.0 上不起作用? [复制]

ATMEGA328P(Arduino Pro Mini)超低运行功耗探索

328p芯片引脚间距

我正在用 atmel 编写 AVR 程序集,但“调用”指令不起作用

ATMEGA328P引脚定义图

Atmega328P 中的奇怪延迟行为