刀刀网
您的当前位置:首页SPI协议简介

SPI协议简介

来源:刀刀网


SPI:一种3线(有的没有SS线(选择主或从机模式))或4线的通信方式:

MOSI:主机出从机进数据线

MISO:主机进从机从数据线 SCK: 时钟线 SS: 主从模式选择线

工作过程的理解:设置好相应的配置后就可以发送或接收数据,当放送或

接收完成后就会是SPIF置位,此时如果开了中断就会就入中断服务程序。如果没开中断就可以通过查询该标志位来做相应的事。进入中段服务程序后,或者读(写)SPDR寄存器都可以清零SPIF标志位。从而可以开始下一次的传输 相应的寄存器

1:SCPR:控制寄存器:SPI的大部分设置

2:SPSR:标志寄存器:(查看一些标志(主要是SPIF位)和设置SPI速度) 3:SPDR:数据寄存器:

SS引脚的说明:(实质就是当配置为输入时:是主机还是从机由输入的电平来决定)

从机模式: 当 SPI 配置为从机时,从机选择引脚 SS 总是为输入。SS 为低将激活 SPI 接口, MISO

成为输出 ( 用户必须进行相应的端口配置 ) 引脚,其他引脚成为输入引脚。当 SS 为高时

所有的引脚成为输入, SPI 逻辑复位,不再接收数据。 SS引脚对于数据包/字节的同步非常有用,可以使从机的位计数器与主机的时钟发生器同

步。当SS 拉高时SPI从机立即复位接收和发送逻辑,并丢弃移位寄存器里不完整的数据。

主机模式:当 SPI 配置为主机时 (SPCR 的 MSTR置位 ),用户可以决定 SS 引脚的方向。

管脚配置

若 SS 配置为输出,则此引脚可以用作普通的 I/O 口而不影响 SPI 系统。典型应用是用来 驱动从机的 SS 引脚。

如果 SS 配置为输入,必须保持为高以保证 SPI 的正常工作。若系统配置为主机,SS 为

输入,但被外设拉低,则 SPI 系统会将此低电平解释为有一个外部主机将自己选择为从

机。为了防止总线冲突, SPI 系统将实现如下动作: 1. 清零 SPCR 的 MSTR 位,使 SPI 成为从机,从而 MOSI 和 SCK变为输入。

2. SPSR 的 SPIF 置位。若 SPI 中断和全局中断开放,则中断服务程序将得到执行。

因此,使用中断方式处理 SPI 主机的数据传输,并且存在 SS 被拉低的可能性时,中断服

务程序应该检查 MSTR 是否为 \"1”。若被清零,用户必须将其置位,以重新使能 SPI 主机 模式。

一:SCPR:控制寄存器:(SPI的大部分设置都在该寄存器)

二SPSR:标志寄存器:(查看一些标志和设置SPI速度,主要是用到SPIF这

个标志位,接收完成和发送完成都会置位这个标志,进入中断服务程序或访问SPDR寄存 器都可以清零这个标志)

三SPDR:数据寄存器:

M16的SPI功能强大的AVR SPI全双工支持全部四种SPI模式主机或从机模式可配置的SPI位速率,最高达8MHzSPI 控制寄存器-SPCRSPI 状态寄存器-SPSRSPI 数据寄存器-SPDRSPI寄存器设置SPI初始化函数与读写1字节函数主讲人:尹延辉版权:力天电子www.lt430.com

应用步骤:

1先根据是主还是从设置端口的模式(输入还是输出) 主机:SS MOSI SCK 为出 MISO为入 从机:SS MOSI SCK 为入 MISO 为出

2配置相应的寄存器(就三个寄存器,注意用到中断时要先开总中断) 3用中断或查询法发送或接收数据

注意:主机或者从机都可以发送或接收。发送完之后就可以马上发下一个

数据了。接收也是只要接收完了也可以马上接收下一个数据了

一:发送:(一般用查询方式发送比较好:此时只要查询发送完毕的标志位

SPIF是否置位)

常用: while(!(SPSR & (1<查询法:实质就是查询SPSR的SPIF位是否置位,接收完和发送完都可以

置位,(如果开了中断的话就会进入相应的中断)

例子:

1. 主机发送(查询方式)(只要发送完毕了就可以继续发送了) //主机模式下发送1-255 #include #define uint unsigned int #define uchar unsigned char void spi_init(void) {

PORTB |= (1<DDRB |= (1<SPCR = 0x73; //SPI使能,低位首发,主机模式,时钟模式00,上升沿采样;时钟速率Fosc/128 SPSR = 0x00; //SPI2x=0 }

void SPI_send_data(char cData) {

PORTB &=~ (1<有接地时)

// SPCR |= (1<SPDR =cData;

while(!(SPSR & (1<// PORTB |= (1<void Delay(uint z) // {

unsigned int i,j; for(i=z;i>0;i--) for(j=2000;j>0;j--); }

int main(void) {

unsigned int i=0; spi_init(); while(1) {

for(i=255;i>0;i--) {

SPI_send_data(i);

Delay(100);

}

}

}

2从机接收(查询方式)

#include #include #define uchar unsigned char #define uint unsigned int void port_init(void) { }

void spi_init(void) {

DDRB = (1<<5) |(1<<7); }

DDRB&=~(1<<4)|(1<<6); SPCR = 0x63; // SPSR = 0x00; //

SPI允许。从机方式 SPI倍速.频率为系统时钟

PORTA = 0x00; DDRA = 0xFF; PORTB = 0xFF;

void init_devices(void) { } //主函数 int main(void) {

init_devices(); port_init(); spi_init();

while(1) }

3从机中断方式接收数据(注意:当进入中断服务程序后SPIF会自动清零) /*中断方式接收数据*/ #include #include #define uchar unsigned char { }

while(!(SPSR & (1<#define uint unsigned int

//端口初始化 void port_init(void) { }

void spi_init(void) {

PORTB |= (1<<4) | (1<<5) | (1<<6) | (1<<7); // PORTA = 0xFF; DDRA = 0xFF;

DDRB |= (1<<5) | (1<<7) | (1<<4); //Set MOSI, SCK AND SS as outputs SPCR = 0xE3; //SPI中断使能,SPI使能,低位首发,从机模式,时钟模式00,上升沿采样;时钟速率Fosc/128 SPSR = 0x00; //SPI2x=0 }

void init_devices(void) {

port_init(); spi_init(); sei();//开全局中断

} //主函; int main(void) {

init_devices(); }

//SPI中断函数 SIGNAL(SIG_SPI) {

PORTA=SPDR; }

while(1);

因篇幅问题不能全部显示,请点此查看更多更全内容