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:数据寄存器:
应用步骤:
1先根据是主还是从设置端口的模式(输入还是输出)
主机:SS MOSI SCK 为出 MISO为入
从机:SS MOSI SCK 为入 MISO 为出
2配置相应的寄存器(就三个寄存器,注意用到中断时要先开总中断)
3用中断或查询法发送或接收数据
注意:主机或者从机都可以发送或接收。发送完之后就可以马上发下一个数据了。接收也是只要接收完了也可以马上接收下一个数据了
一:发送:(一般用查询方式发送比较好:此时只要查询发送完毕的标志位SPIF是否置位)
常用:while(!(SPSR & (1< 例子: 主机发送(查询方式)(只要发送完毕了就可以继续发送了) //主机模式下发送1-255 #include #define uint unsigned int #define uchar unsigned char void spi_init(void) { PORTB |= (1< SPSR = 0x00; //SPI2x=0 } void SPI_send_data(char cData) { PORTB &=~ (1< while(!(SPSR & (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) { PORTA = 0x00; DDRA = 0xFF; PORTB = 0xFF; } void spi_init(void) { DDRB = (1<<5) |(1<<7); DDRB&=~(1<<4)|(1<<6); SPCR = 0x63; // SPI允许。从机方式 SPSR = 0x00; // SPI倍速.频率为系统时钟 } void init_devices(void) { port_init(); spi_init(); } //主函数 int main(void) { init_devices(); while(1) { while(!(SPSR & (1< _delay_loop_2(900); } } 3从机中断方式接收数据(注意:当进入中断服务程序后SPIF会自动清零) /*中断方式接收数据*/ #include #include #define uchar unsigned char #define uint unsigned int //端口初始化 void port_init(void) { PORTA = 0xFF; DDRA = 0xFF; } void spi_init(void) { PORTB |= (1<<4) | (1<<5) | (1<<6) | (1<<7); // 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(); while(1); } //SPI中断函数 SIGNAL(SIG_SPI) { PORTA=SPDR; }
上一篇:AVR128单片机最小系统串口,外部中断,跑马灯,uCOS-II移植
下一篇:AVR128_uC/OS-II 移植代码
推荐阅读最新更新时间:2024-11-05 15:24
设计资源 培训 开发板 精华推荐
- DER-966 - 使用基于 PowiGaN 的 InnoSwitch4-CZ、ClampZero 和 HiperPFS-5 的 140 W USB PD 3.1 扩展功率范围充电器
- USB_IAP
- RP507K001 应用电路,带同步整流器的 DC-DC 降压转换器
- K70-SOM: EmCraft Systems的Kinetis®K70系统级模块(SOM)和入门套件
- 安信可VB02底板
- Tda7391Pd 32W桥式车载收音机放大器典型应用
- 使用 NXP Semiconductors 的 TDA8559T 的参考设计
- OM13514: I²C总线RTC PCF85363A的PC评估板
- 使用 Richtek Technology Corporation 的 RT7252A 的参考设计
- IS31AP4833 具有 3D 增强音频功率驱动器的高音、低音控制的典型应用