SPI概述
来源:互联网 发布:广东淘宝卖家卷款逃跑 编辑:程序博客网 时间:2024/05/16 03:57
SPI概述
一、SPI简介
SPI是一种串行外围设备接口,高速全双工的通信总线,广泛应用于ADC、LCD等设备于MCU间通信场合。
SPI包含4条总线,分别为NSS、SCK、MISO、MOSI,各信号线功能如下:
1. NSS
NSS为片选信号,当NSS信号为低电平时,片选有效,开始SPI主从模式通讯。
SPI主从模式的配置真正起作用的是内部NSS引脚,内部NSS引脚才真正连接到SPI通讯控制器上。软件NSS模式和硬件NSS模式由SSM控制位实现,SSM位控制内部NSS引脚与SSI位(软件模式)相连,还是与NSS外部引脚(STM32引脚,硬件模式)。如图1-1所示。
图1-1内外部NSS
在实际的应用中,STM32的SPI功能通常用作主模式。选择软件模式输入控制内部NSS为高电平,使能外部NSS管脚为普通IO口输出低电平来使能从设备,实现一主多从设备的数据交流。如图1-2所示。
图1-2 一主多从
2. SCK
SCK为时钟信号线,由主通讯设备产生,不同的设备支持的时钟频率不一样,STM32的SPI时钟频率最大为fpclk/2.
3. MISO和MOSI
MISO和MOSI为主设备和从设备通讯数据线。MISO为从主机到从机,MOSI为从从机到主机。
二、SPI寄存器配置
因为在实际的应用中,STM32的SPI功能通常用作主模式,选择软件模式配置NSS管脚,在此以SPI1为例说明该种SPI工作模式配置步骤:
1. 使能SP1时钟,配置GPIOA5、6、7、8;
查找《STM32参考手册》中系统结构图得知SPI和GPIOA均挂载在APB2时钟线上,查找APB2外设时钟使能寄存器(RCC_APB2ENR)(图1-4),使能SPI和GPIOA的时钟:
RCC->APB2ENR |= 1<<2; //使能GPIOA时钟;
RCC->APB2ENR |= 1<<12; //使能SPI1时钟;
参考前文《GPIO概述》配置5,6,7,为复用推挽输出:
GPIOA->CRL &= 0x000FFFFF;
GPIOA->CRL |= 0xBBB00000; //复用推挽输出
GPIOA->ODR |= 0x07<<5; //上拉
图1-3 STM32系统结构图
图1-4 RCC_APB2ENR
2. 开全双工模式并配置软件管理NSS
SPI1->CR1 |= 0<<10; //全双工模式
SPI1->CR1 |= 1<<9; //软件NSS-SSM
SPI1->CR1 |= 1<<8; //软件NSS-SSI
图1-5 SPI_CR1
3. 设置SPI1位主机并设置数据帧格式
SPI1->CR1 |= 1<<2; //SPI主机
SPI1->CR1 |= 0<<11; //8bit数据格式
4. 设置时钟极性和相位极性
SPI1->CR1 =1<<1; //空闲模式下SCK=1,CPOL=1
SPI1->CR1 = 1<<0; //数据采样从第二个时钟边沿开始,CPHA=1
5. 传输速度和LSBfIRST帧格式设置
SPI1->CR1 |=7<<3; //设置SCK波特率为
SPI1->CR1 |=0<<7; //MSBfirst
6. 使能SPI1
SPI1->CR1 |=1<<6; //SPI设备使能
三、SPI库配置
Void SPI1_Configuration(void)
{
SPI_InitTypeDef SPI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; //复用推挽输出
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; //NSS推挽输出
GPIO_Init(GPIOB,&GPIO_InitStructure);
SPI_InitStructure.SPI_Direction=SPI_Direction_2Lines_FullDuplex;//SPI设置为双线双向全双工
SPI_InitStructure.SPI_Mode=SPI_Mode_Master;//设置为主SPI
SPI_InitStructure.SPI_DataSize=SPI_DataSize_8b;//SPI发送接收8位帧结构
SPI_InitStructure.SPI_CPOL=SPI_CPOL_High;//设置时钟悬空高
SPI_InitStructure.SPI_CPHA=SPI_CPHA_2Edge;//数据捕获于第二个时钟沿
SPI_InitStructure.SPI_NSS=SPI_NSS_Soft;//内部NSS信号SSI位控制,SSI=1,SSM=1
SPI_InitStructure.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_8;//波特率预分频值为 8
SPI_InitStructure.SPI_FirstBit=SPI_FirstBit_MSB;//数据传输从MSB位开始
SPI_InitStructure.SPI_CRCPolynomial = 7;//SPI_CRCPolynomial定义了用于CRC值计算的多项式
SPI_Init(SPI1,&SPI_InitStructure);//参数传送
SPI_Cmd(SPI1,ENABLE); //使能 SPI
}
四、SPI数据接收/发送
寄存器版
u8 SPI1_ReadWriteByte(u8 TxData)
{
While((SPI1->SR &1<<1) ==0); //发送区非空循环,TXE=1为空
SPI1->DR = TxData;
While((SPI1->SR &1<<0) ==0); //等待接收到一个字节,RXNE=1为空
Return SPI1->DR;
}
库操作版:
u8 SPI_SendWriteByte(u8 byte) //SPI 读写函数
{
while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE)==RESET);//判断发送缓冲区是否为空
SPI_I2S_SendData(SPI1,byte);//发送数据
while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE)==RESET);//判断接收缓冲区是否是空的
return SPI_I2S_ReceiveData(SPI1);//接收数据,并返回到接收缓冲区
}
五、SPI接收中断
中断开启:SPI_I2S_ITConfig(SPI1,SPI_I2S_IT_RXNE,ENABLE);
中断清除:SPI_I2S_ClearFlag(SPI1,SPI_I2S_IT_RXNE); //实际工作中,读取SPI_DR寄存器时将清除RXNE位,因此可以不用清除中断标志,同USART。
- SPI概述
- SPI概述
- SPI概述
- SPI概述
- SPI master驱动程序概述
- arm spi 接口概述
- spi总线概述1(spi-summary)
- spi总线概述2(spi-summary)
- spi总线概述3(spi-summary)
- Linux SPI架构分析概述
- LINUX驱动之SPI子系统之一概述
- 数字接口SPI和I2C的区别与联系概述
- 两单片机通过 SPI 通信的软件协议设计概述
- Linux SPI总线和设备驱动架构之一:系统概述
- Linux SPI总线和设备驱动架构之一:系统概述
- Linux SPI总线和设备驱动架构之一:系统概述
- Linux SPI总线和设备驱动架构之一:系统概述
- Linux SPI总线和设备驱动架构之一:系统概述
- 【原理】也就一个简单的jquery收缩菜单而已
- Spring BeanFactory学习
- android技术选型
- 12月份的武汉免费玩
- 最新鲜最详细的Android SDK下载安装及配置教程
- SPI概述
- 【Python】udp聊天器
- Android自定义View第三弹(反人类尺子)
- Cocos Creator—最佳构建部署实践
- 金蝶K3系统没有委外加工模块,如果变通处理委外业务?
- CAS之5.2x版本自定义密码验证-yellowcong
- mt2503[SIM]版本是否支持EAP-SIM/EAP-AKA?
- Android USB OTG功能如何打开及实现
- 前端小白--图片懒加载imgLazyLoading