前些天,有位网友谈到经过FPGA来完成SPI通讯。经过帖子的回复发现很多网友对SPI通讯还有些疑问,所以今日就带着咱们从SPI的标准协议,SPI在STM32单片机上的装备及在74HC595逻辑芯片通讯的实例来全方面认识一下这个既杂乱又简略的通讯协议。
SPI 是Serial Peripheral Interface的缩写,直译为串行外围设备接口,SPI是Motorola公司推出的一种同步串行通讯方法,是一种四线同步总线,因其硬件功用很强,与SPI有关的软件就适当简略,使MCU有更多的时刻处理其他业务。这儿要阐明一下,专利在电子职业仍是很要害的,因而,部分其它厂商将SPI通讯协议更名以躲避昂扬的专利费,但其硬件处理方法是相同的,仅仅换了一个称号罢了,例如德仪单片机里的SSI通讯。
常用的SPI通讯方法是标准四线制,如下图电路示意图所示:
MISO:主设备输入/从设备输出引脚。该引脚在从形式下发送数据,在主形式下接纳数据。
MOSI:主设备输出/从设备输入引脚。该引脚在主形式下发送数据,在从形式下接纳数据。
SCK:串口时钟,作为主设备的输出,从设备的输入
NSS:从设备挑选。这是一个可选的引脚,用来挑选主/从设备。
MOSI脚相互衔接,MISO脚相互衔接。这样,数据在主和从之间串行地传输(MSB位在前)。通讯总是由主设备建议。主设备经过MOSI脚把数据发送给从设备,从设备经过MISO引脚回传数据。这意味全双工通讯的数据输出和数据输入是用同一个时钟信号同步的;时钟信号由主设备经过SCK脚供给。
比较杂乱的是这个从挑选(NSS)脚。其有两种形式:软件NSS形式与硬件NSS形式。
软件NSS形式下:在该形式下说得简略一些便是此引脚当作一般的GPIO来运用。其输入/输出的功用与操作GPIO是相同的。咱们经过STM32来操作片外设备时多选用此形式。
硬件NSS形式下:此形式又下分两种状况:状况一、NSS输出被使能:当STM32作业为主SPI,并且NSS输出现已使能,这时NSS引脚被拉低,一切NSS引脚与这个主SPI的NSS引脚相连并装备为硬件NSS的SPI设备,将主动变成从SPI设备;状况二、NSS输出被封闭:答应操作于多主环境。
硬件的衔接咱们说完了,下面我再来介绍时钟线与信号线。
在学习数字逻辑电路时,咱们都听教师讲过数据的锁存方法,例如上升沿锁存等。咱们的SPI通讯方法在硬件上十分灵敏的处理数据锁存方法,经过两个参数的装备供给了四种不同的数据传输形式,如下图所示:
从上图咱们能够看出,当CPHA置高时,其数据锁存在第二个时钟边缘;CPHA清零时,数据锁存在第一个时钟边缘。而CPOL参数置高时,数据锁存在时钟信号的下降沿,时钟线闲暇状况为常高,反之,数据锁存在时钟信号的上升沿,闲暇状况为常低。
关于数据的发送进程,帧格局也是能够修正的,例如能够挑选MSB方法(最高位先发送)或是LSB方法(最低位先发送),还能够挑选刺进CRC校验的方法等,这儿关于这些高档的使用,因为本文片幅有限就不再详细讲解了。
接下来,咱们经过STM32单片机关于SPI外设的初始化进程再来看一下SPI的硬件标准。
void SPI_init(void)
{
RCC_APB2PeriphClockCmd(sFLASH_CS_GPIO_CLK | sFLASH_SPI_MOSI_GPIO_CLK | sFLASH_SPI_MISO_GPIO_CLK |
sFLASH_SPI_SCK_GPIO_CLK, ENABLE);
/*! 装备SPI的外设时钟,并使能 */
RCC_APB2PeriphClockCmd(sFLASH_SPI_CLK, ENABLE);
/*! 装备SCK引脚 */
GPIO_InitStructure.GPIO_Pin = sFLASH_SPI_SCK_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //此处依据详细使用而设置,例如可装备为开漏输出
GPIO_Init(sFLASH_SPI_SCK_GPIO_PORT, GPIO_InitStructure);
/*! 装备MOSI引脚 */
GPIO_InitStructure.GPIO_Pin = sFLASH_SPI_MOSI_PIN;
GPIO_Init(sFLASH_SPI_MOSI_GPIO_PORT, GPIO_InitStructure);
/*! 装备MISO引脚 */
GPIO_InitStructure.GPIO_Pin = sFLASH_SPI_MISO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(sFLASH_SPI_MISO_GPIO_PORT, GPIO_InitStructure);
/*! 装备NSS引脚为GPIO输出 */
GPIO_InitStructure.GPIO_Pin = sFLASH_CS_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(sFLASH_CS_GPIO_PORT, GPIO_InitStructure);
/*! SPI装备 */
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //数据线两线,双向全双半
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; //CPOL置高,时钟线在闲经常高,下降沿锁存数据
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //CPHA置高,则第二个时钟沿锁存数据
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //从引脚为软件装备方法
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4; //SPI时钟频率为4分频
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //MSB最高位优先发送
SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC查验公式挑选第7项
SPI_Init(sFLASH_SPI, SPI_InitStructure);
/*! 使能SPI */
SPI_Cmd(sFLASH_SPI, ENABLE);
}
上面的源代码是示例是ST公司操作SPI flash的Demo示例。咱们再以74HC595芯片的硬件操作操作来装备,初始化SPI外设。
咱们先来看一下74HC595的硬件操作时序图:
从上图,咱们能够看出,时钟线(SH_CP)在闲暇状况为常低,并且为第一个时钟沿的上升沿锁存数据。因而,咱们需求将上面装备初始化的两个参数修正为如下:
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //CPOL置高,时钟线在闲经常低,上降沿锁存数据
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //CPHA清零,则第一个时钟沿锁存数据
其它参数不做修正即可。上述源代码现现已过STM32F103与8片74HC595串联试验经过,示例完好工程源代码能够到电子产品世界论坛片自行查找、下载。
标准四线的SPI通讯不仅为咱们节省了名贵的单片机引脚数,并且其标准的硬件协议也为咱们嵌入式软件编程供给了极大的便当。丰厚的外围器材支撑,例如SPI的flash存储,SPI接口的SD读卡器,SPI接口的网络通讯模块都现已十分遍及,能够看到使用好外设SPI通讯现已成为一名工程师必要的技术之一。
- STM32单片机中文官网
- STM32单片机官方开发工具
- STM32单片机参阅规划