单片机 > 单片机程序设计 > 详情

STM32通信接口硬件SPI

发布时间:2021-07-23 发布时间:
|

     一、概述 

      SPI是串行外设接口(Serial Peripheral Interface)的缩写。SPI,是一种高速的,全双工,同步的通信总线,是Motorola最先在其的MC68HCXX芯片上使用,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省空间,提供方便,正是出于这种简单易用的特性,如今越来越多的芯片集成了这种通信协议。


        SPI接口主要应用在实时时钟、E2PROM、FLASH、AD转换器还有数字信号处理器和数字信号解码器之间,它的用途相当广泛。而且其传输速度较快一般可以达到10M以上。


二、基本原理


        由图可知SPI一般由四条线组成:MISO(主机输入从机输出)、MOSI(主机输出从机输入)、SCLK(时钟线)、CS(片选信号)


        四线模式的SPI支持全双工,如果把MISO和MOSI合为一条数据线,就变成了三线SPI,只支持半双工。


        主机的数据通过移位寄存器传输给从机时,从机的数据也会通过它的移位寄存器传输给主机


         示例:(从最低位开始)


                                                主机                        从机


                                               00000000                11111111


                第一个时钟周期      00000001                11111110


                第二个时钟周期      00000011                11111100 


                 ......


                 第八个时钟周期      11111111                00000000


        所以说每次的数据传输就相当于主机从机的数据进行交换


        由此,如果要传输数据给从机,主机只要忽略掉从从机接收到的数据即可,如果要从从机读取数据,就可以发送无意义的数据给从机(如0x00)


       注意:大多数情况下发送和接收并不会同时进行。


三、STM32上的SPI


        STM32 上的SPI接口提供俩个功能,支持SPI协议和I2S音频协议,默认情况下,选择的是SPI功能。可通过软件将接口从SPI切换到I2S。


        STM32上SPI的特性如下


      SPI的框图如下:       

    这个框图并不复杂,主要要关注的就是MISO和MOSI那里。


    数据总线中的数据写入发送缓冲区,通过移位寄存器一位一位的从MOSI发送,同时从机返回的数据从MISO进入移位寄存器,进入接收缓冲区。


    下面的部分就是波特率发生器,主控制逻辑以及通信控制。


    注意:CPOL(时钟极性)决定SPI接口传输时时钟空闲状态的电平(1,高电平;0,低电平)


                CPHA(时钟相位)控制在时钟的第一个还是第二个边沿被采集(1,第二个边沿,0,第一个边沿)


                


四、STM32 上SPI的实现流程


       1、配置相关引脚的复用功能,使能SPI时钟


        2、设置SPI的工作模式


        3、使能SPI


        代码如下:


        初始化函数     


void SPI1_Init(void)

{  

u16 tempreg=0;

RCC->AHB1ENR|=1<<0;    //使能PORTA时钟    

RCC->APB2ENR|=1<<12;    //SPI1时钟使能 

GPIO_Set(GPIOB,7<<3,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PU); //PB3~5复用功能输出

  GPIO_AF_Set(GPIOB,3,5); //PB3,AF5

  GPIO_AF_Set(GPIOB,4,5); //PB4,AF5

  GPIO_AF_Set(GPIOB,5,5); //PB5,AF5 

 

//这里只针对SPI口初始化

RCC->APB2RSTR|=1<<12; //复位SPI1

RCC->APB2RSTR&=~(1<<12);//停止复位SPI1

tempreg|=0<<10; //全双工模式

tempreg|=1<<9; //软件nss管理

tempreg|=1<<8;  

tempreg|=1<<2; //SPI主机  

tempreg|=0<<11; //8位数据格式

tempreg|=1<<1; //空闲模式下SCK为1 CPOL=1 

tempreg|=1<<0; //数据采样从第2个时间边沿开始,CPHA=1  

  //对SPI1属于APB2的外设.时钟频率最大为84Mhz频率.

tempreg|=7<<3; //Fsck=Fpclk1/256

tempreg|=0<<7; //MSB First  

tempreg|=1<<6; //SPI启动 

SPI1->CR1=tempreg; //设置CR1  

SPI1->I2SCFGR&=~(1<<11);//选择SPI模式

SPI1_ReadWriteByte(0xff);//启动传输  

}   

        这里对SPI1进行初始化,首先使能IO口的时钟,初始化IO口味复用功能,复用为SPI1,。首先先复位SPI1,设置为全双工模式,软件从器件管理,内部从器件选择,作为主机,八位数据格式,空闲状态高电平,第二个时间边沿开始采样,设置波特率256分频,从最高位开始传输,使能SPI。


        再选择SPI模式(I2SCFGR寄存器的第11位)


        发送一个字节启动传输


    传输速度设置函数 


//SPI1速度设置函数

//SpeedSet:0~7

//SPI速度=fAPB2/2^(SpeedSet+1)

//fAPB2时钟一般为84Mhz

void SPI1_SetSpeed(u8 SpeedSet)

{

SpeedSet&=0X07; //限制范围

SPI1->CR1&=0XFFC7; 

SPI1->CR1|=SpeedSet<<3; //设置SPI1速度  

SPI1->CR1|=1<<6; //SPI设备使能   


    通过改变分频系数来设置SPI的传输速度


读写一个字节


//SPI1 读写一个字节

//TxData:要写入的字节

//返回值:读取到的字节

u8 SPI1_ReadWriteByte(u8 TxData)

{  

while((SPI1->SR&1<<1)==0); //等待发送区空 

SPI1->DR=TxData;   //发送一个byte  

while((SPI1->SR&1<<0)==0); //等待接收完一个byte  

  return SPI1->DR;          //返回收到的数据     

}

    TxDate为要发送的字节,函数的返回值为接收到的字节


五、使用SPI


    在使用SPI时先将片选信号拉低选中从器件,然后发送或者接收数据,完成后,拉高片选。


    随后的博客会通过W25Q128的使用来介绍SPI的使用。


关键字:STM32  通信接口  硬件SPI

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
PIC单片机基础知识之二