1. 首页
  2. 技术文章

STM32F10x学习笔记–硬件SPI通讯FLASH第一篇之SPI初始化

  • SPI介绍

SPI总线协议这部分网络上资料齐全,我这里就不多说了。在这里我主要介绍下,学习通信FLASH相关需要知道的地方。首先,需要准备以下资料:

  1. W25X16的数据手册;
  2. STM32F10x中文参考手册;
  3. STM32F10x固件库手册;

以上资料相关部分最好是看过的,主要是W25X16数据手册一定要看明白,STM32中文手册看一下SPI部分,在24章节开始。库函数打开Modules-STM32F10x_StdPeriph_Driver-SPI这里目录下。

对于SPI总线协议:

  1. 支持4种采集模式;
SPI模式 CPOL CPHA 采样时刻
0 0 0 奇数边沿
1 0 1 偶数边沿
2 1 0 奇数边沿
3 1 1 偶数边沿

 

看完W25X16手册我们需要先知道:

  1. SPI的clk最大可达75Mhz;
  2. W25X16支持SPI模式0和模式3;
  3. W25X16传输数据是MSB先行
  4. W25X16内存分布:如下图1

STM32F10x学习笔记--硬件SPI通讯FLASH第一篇之SPI初始化

图1 W25X16内存分布

如图1,对于W25x16来说,共有32个Block,每个Block为64KB,一共32*64=2048MB;每个Block又包含了16个Sector,每个Sector为4KB,16*4KB=64KB为一个Block。

我们看到不管是Block还是Sector 都有写了24字节的4个地址,从左到又都是00-FF刚好256Byte,所以显然通过内部芯片命令一次写入数据最大为256个字节。

看完STM32F10x中文参考手册和库文件手册我们需要大概知道:

  1. STM32的SPI总线支持CS为硬件NSS和普通IO,为了统一和方便设计,不管CS引脚接入到NSS还是其他普通IO上我们都以普通IO模式设计。
  2. STM32F1xx,SPI的时钟是最大为fPCLK/2,其中SPI1的FPCLK是72Mhz,其他SPI借口的Fpclk为36Mhz。
  3. STM32的SPI总线的CS引脚模式为:推挽输出;CLK和MOSI模式推挽复用输出;MISO模式为浮空输入或带上拉输入
  4. SPI支持传输8bit或者16bit数据一帧;可设置数据由MSB先行还是LSB先行。
  5. SPI初始化结构体都有哪些?库文件手册介绍了以下结构体
uint16_t SPI_BaudRatePrescaler 时钟分频系数 最大FCLK/2
uint16_t SPI_CPHA 配置相位模式,共计四中模式0~3模式。
uint16_t SPI_CPOL
uint16_t SPI_CRCPolynomial CRC校验
uint16_t SPI_DataSize 一帧发数据8bit还是16bit
uint16_t SPI_Direction 工作模式:单工、半双工、全双工
uint16_t SPI_FirstBit MSB还是LSB先行
uint16_t SPI_Mode 主还是从模式
uint16_t SPI_NSS 硬件CS还是软件CS

 

每一个含义手册里说明的很清楚。

  • 初始化代码

首先进行GPIO初始化:

void W25x16_SPI_GPIO_Config(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  /*CS初始化*/
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;						 
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);	
   /**CLK**/
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;	
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  //MISO
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;	
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING			
  GPIO_Init(GPIOA, &GPIO_InitStructure);
 //MOSI
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;	
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  GPIO_SetBits(GPIOA,GPIO_Pin_4);			//CS默认高电平
} 

标准的初始化,GPIO的初始化比较简单, GPIO都在A PORT上。

然后对SPI工作模式初始化:

void W25x16_SPI_Workmode_Config(void)
{
   SPI_InitTypeDef  SPI_InitStructure; 
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
  //W25X16 FLASH 手册介绍  支持SPI 0和3 模式
  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;	  //双线全双工
  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;	//主机模式
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;	 //8位
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;	 //选择模式3   CPOL=1 CPHA=1 偶数边沿
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;	 //偶数边沿
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;	//设置CS为普通IO 还是硬件IO
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;	   // 1/2分频    SPI主频F/2 =72/2=36MHZ  
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;	  //发送数据 高位先行
  SPI_InitStructure.SPI_CRCPolynomial = 7;
  SPI_Init(SPI1 , &SPI_InitStructure);
  SPI_Cmd(SPI1 , ENABLE);
}

SPI工作模式的初始化,代码中注释写的很明白了,SPI_InitStructure.SPI_CRCPolynomial = 7; 这段初始化可有可无,因为我们不使用CRC。即便初始化了 后面也不会调用其对应函数来使用。

最后封装到新的函数中,放在Main函数中进行调用初始化即可

void W25x16_SPI_open(void)
{
  W25x16_SPI_GPIO_Config();
  W25x16_SPI_Workmode_Config() ;
}

把这个函数调用以下就完成了SPI的初始化,今天就学习到这里,下一章我们学习,SPI基本发送读取函数和FLAHS基本函数。

原创文章,作者:小峰,如若转载,请注明出处:http://www.wfblog.com/archives/431.html

联系我们

400-800-8888

在线咨询:点击这里给我发消息

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息