概述: SPI协议简介 ●SPI数据传输方向 以模式0为例: 利用了STM32F103VET6和STM32F103C8T6(身边只有这两块了)两款MUC。 ●注意:MOSI连接MOSI,MISO连接MISO(不能像串口那样交叉连接)。 ●注意:上面1us的延时[delay_us(1)]此处可以忽略,这里是因为接收时此单片机外部中断上升沿触发有时延,SCK太快无法准确提取数据,利用其他方式解析从机数据的请忽略。(详细了解请参考博文:STM32外部中断边沿触发存在延时问题)。 ★代码解析:从机采用了外部中断的方式去采集CS的下降沿和SCK的上升沿(从机以CS下降沿为数据接收的开始,以SCK的上升沿作为每bit数据的采样点)。(★★★有好的方法欢迎指导)
软件模拟SPI程序代码
通过两个MCU(STM32F103)来模拟SPI的主从机,完成主机发送从机接收,便于理解SPI协议。
●SPI接口介绍
SCK:时钟信号,由主设备产生,所以主设备SCK信号为输出模式,从设备的SCK信号为输入模式。
CS:使能信号,由主设备控制从设备,,所以主设备CS信号为输出模式,从设备的CS信号为输入模式。
MOSI:主设备数据输出,从设备数据输入,所以主设备MOSI信号为输出模式,从设备的MOSI信号为输入模式。
MISO:主设备数据输入,从设备数据输出,所以主设备MISO信号为输入模式,从设备的MISO信号为输出模式。
●SPI接口连接图
注意:MOSI和MISO不能交叉连接(可以把主从机理解为一个整体系统,MOSI为系统主机发送从机接收的数据线,MISO为主机接收从机发送的数据线)。
SPI作为全双工的的串行通信协议,数据传输时高位在前,低位在后。主机和从机公用由主机产生的SCK信号,所以在每个时钟周期内主机和从机有1bit的数据交换(因为MOSI和MISO数据线上的数据都是在时钟的边沿处被采样)。
如下图:
SPI协议规定数据采样是在SCK的上升沿或下降沿时刻(由SPI模式决定,下面会说到),观察上图,在SCK的边沿处,主机会在MISO处采样(接收来从机的数据),从机会在MOSI处采样(接收来自主机的数据),所以每个时钟周期中会有一bit的数据交换。
●SPI传输模式
SPI总线传输一共有4种模式,这4种模式分别由时钟极性(CPOL)和时钟相位(CPHA)来定义。
CPOL
CPHA
规定了SCK时钟信号空闲状态的电平
规定了数据是在SCK时钟的上升沿还是下降沿被采样
———–
————————————
模式0:CPOL=0,CPHA =0
SCK空闲为低电平,数据在SCK的上升沿被采样(提取数据)
模式1:CPOL=0,CPHA =1
SCK空闲为低电平,数据在SCK的下降沿被采样(提取数据)
模式2:CPOL=1,CPHA =0
SCK空闲为高电平,数据在SCK的下降沿被采样(提取数据)
模式3:CPOL=1,CPHA =1
SCK空闲为高电平,数据在SCK的上升沿被采样(提取数据)
SCK空闲为低电平,数据在SCK的上升沿被采样(提取数据)。
◐在时钟的第一个上升沿(游标1处)
MOSI上数据为1,则主机在此时钟沿放置的数据时1,从机接收此时钟的数据为1。
MISO上数据为0,则从机在此时钟沿放置的数据时0,主机接收此时钟的数据为0。
◐在时钟的第二个上升沿(游标2处)
MOSI上数据为0,则主机在此时钟沿放置的数据时0,从机接收此时钟的数据为0。
MISO上数据为1,则从机在此时钟沿放置的数据时1,主机接收此时钟的数据为1。通过两个单片机模拟SPI来加深理解
※硬件连接方式
主机- STM32F103VET6
从机-STM32F103C8T6
(主机产生) SCK→
→SCK(从机被动)
(主机产生) CS→
→CS (从机被动)
(主机发送)MOSI →
→MOSI (从机接收)
(主机接收) MISO ←
←MISO (从机发送)
✯SPI模式
采用模式0(CPOL=0,CPHA =0):SCK空闲为低电平,数据在SCK的上升沿被采样(提取数据) 。
✯程序思路
★主机拉低CS开始传输数据,在SCK上升沿之前保持MOSI上有稳定的数据输出(因为从机要在SCK的上升沿去采样(提取数据),所以主机在SCK上升沿之前要完成发送数据的放置)。
★从机在CS拉低后(CS有下降沿)开始数据的接收(在SCK的上升沿采集MOSI上的数据)。
✯主机C代码+波形/*SPI发送函数*/ //时钟的上升沿采样数据,下降沿切换数据 先发送高位 void SPI_Write(uint8_t Data) { uint8_t i=0; CS_L; //片选拉低开始传输数据 /*循环8次,发送8bit数据*/ for(i=0;i<8;i++) { SCK_L;//产生下降沿,准备切换数据 delay_us(1);//(可忽略,这里是因为接收时此单片机外部中断上升沿触发有时延,SCK太快无法准确提取数据) /*切换数据*/ if(Data&0x80)//通过8次循环移位,将一个字节的数据,由高到低一位一位的放置到数据线上 { MOSI_H; } else { MOSI_L; } SCK_H; //产生上升沿(从机在此上升沿时采集数据) delay_us(1);//(可忽略,这里是因为接收时此单片机外部中断上升沿触发有时延,SCK太快无法准确提取数据) Data <<= 1; } MOSI_L; SCK_L; CS_H; //片选拉高等待下次数据传输 } int main() { int i=0,j=0; SysTick_init(); SPI_GPIO_Config(); while(1) { SPI_Write(0xA5); } }
★代码解析:要了解代码思路,就要时刻记得我们采用SPI的是模式0(SCK空闲为低电平,数据在SCK的上升沿被采样(提取数据) ),所以1Byte数据放置完毕后,SCK要拉低,CS要拉高,MOSI要恢复默认电平,但是每Bit数据放置完毕后SCK要拉高(因为SCK上升沿前要确保稳定的数据,这样从机才可以在上升沿采样到正确的数据)。所谓放置数据,其实就是在每次SCK拉高之前对MOSI引脚赋值。比如我们发送的数据为0xA5(1010_0101)。
在上图中标号2处的上升沿之前要保证MOSI上(游标1)处有稳定的1bit数据(1),随后的7个上升沿也一样。
✯主机产生的波形
★波形解析:通道1数据:SCK
通道2数据:MOSI
通道3数据:CS
在上图中可以观察到整个数据的传输是在片选CS为低的时刻进行的。在上升沿之前完成了1bit数据的发送。完成1Byte数据的发送后,SC置高,CS置高,MOSI置低,为下一帧数据做准备。
✯从机C代码+波形/*SPI接收数据*/ uint8_t SPI_Read() { /*CS下降沿*/ if(CS_Trigger_Falling == 1) { CS_Trigger_Falling = 0; /*SCK上升沿*/ for(i=0;i<8;i++) { while(SCK_Trigger_Rising != 1);//等待上升沿 SCK_Trigger_Rising = 0; Data_Rec<<=1; if(MOSI_State)//在SCK上升沿时提取数据 { Data_Rec ++; Rec_Data1[i] = 1; } else{} } } return Data_Rec; } int main() { SysTick_init(); SPI_GPIO_Config(); EXTI_PB1_Config(); EXTI_PA2_Config(); while(1) { Get_Data = SPI_Read(); } } /*外部中断0中断*/ void EXTI1_IRQHandler(void)//中断服务函数 { if(EXTI_GetITStatus(EXTI_Line1) != RESET )//reset为清零(!=reset等价于IT=1) { SCK_Trigger_Rising = 1; EXTI_ClearITPendingBit(EXTI_Line1); } } void EXTI2_IRQHandler(void)//中断服务函数 { if(EXTI_GetITStatus(EXTI_Line2) != RESET )//reset为清零(!=reset等价于IT=1) { CS_Trigger_Falling = 1; EXTI_ClearITPendingBit(EXTI_Line2); } }
CS下降沿提取波形:图中紫色信号为CS下降沿点,
SCK上升沿提取波形:下图中紫色信号为SCK上升沿的提取(即从机接收MOSI数据线上的采样点)。
提取数据(数据采样):紫色信号处(采样点)MOSI上的数据即为从机接收到的数据。
从机接收数据结果:
★★★如有错误欢迎指导。
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算