原理
SPI介绍
SPI(Serial Peripheral Interface)串行外围接口,是一种高速、全双工、同步的通信总线,并且在芯片的管脚上只占用四根线,出于简单易用的特性,被越来越多的芯片集成,比如 STM32 系列芯片。
SPI总线包括4条逻辑线:
- MISO:Master input slave output
- MOSI:Master output slave input
- SCLK :Serial Clock 串行时钟信号线,由主机产生,发送给从机
- SS:Slave Select 片选信号线。SPI 协议中没有设备地址,它使用 CS 信号线来寻址,主机把该从设备的 CS 信号线设置为低电平,该从设备即被选中,接着主机开始与被选中的从设备进行 SPI 通信。所以 SPI 通信以 NSS 线置低电平为开始信号,以 CS 线被拉高作为结束信号。
主机和从机都有一个串行移位寄存器(SSPSR),主机通过向它写入一个字节来发起一次传输。寄存器通过 MOSI 信号线将字节传送给从机,从机也将自己的移位寄存器中的内容通过 MISO 信号线返回给主机。这样,两个移位寄存器中的内容就被交换。外设的写操作和读操作是同步完成的。如果只进行写操作,主机只需忽略接收到的字节;反之,若主机要读取从机的一个字节,就必须发送一个空字节来引发从机的传输。
SPI工作模式:时钟极性(CPOL)和时钟相位(CPHA)的4种组合模式,极性和相位共同决定读取数据的方式。
CPOL = 0:时钟空闲时为低电平 0
CPOL = 1:时钟空闲时为高电平1
CPHA = 0:在时钟信号SCK的第一个跳变沿采样
CPHA = 1:在时钟信号SCK的第二个跳变沿采样
STM32F1的SPI
SPI1 是挂接在 APB2 总线上,最大速度是 36Mbits/s,而 SPI2和 SPI3 挂接在 APB1 总线上,最大速度是 18Mbits/s。
(1)SPI接口引脚:我们通常使用的 SPI 总线就是 SCK、MISO、MOSI,片选线可使用任意一个普通 GPIO 代替.
(2)时钟逻辑控制器:SCK 线的时钟信号由波特率发生器根据“ 控制寄存器 CR1”中的 BR[0:2] 位控制,该位是对 APB 时钟的分频因子,分频结果就是 SCK 引脚的输出时钟频率。
(3)数据控制逻辑:当向外发送数据的时候,数据移位寄存器以“发送缓冲区”为数据源,把数据一位一位地通过数据线发送出去;当从外部接收数据的时候,数据移位寄存器把数据线采样到的数据一位一位地存储到“接收缓冲区”中。
(4)整体逻辑控制:配置的“控制寄存器(CR1/CR2)”的参数而改变 SPI模式、波特率、LSB 先行、主从模式、单双向模式等等。
FLASH器件EN25Q128
EN25Q128 是大容量 SPI FLASH 产品,W25Q128 将 16M 的容量分为 256 个块(Block),每个块大小为 64K 字节,每个块又分为 16 个扇区(Sector),每个扇区 4K 个字节。
读数据:可以从任何地方读
写数据:一次最多写一页,否则覆盖。例如本芯片一个扇区为4096个字节,那么需要写16页,要进行至少16次按页写数据。
擦数据:擦数据的最小单位是一个扇区,也可以直接擦出整个芯片。
步骤
- 编写USART驱动程序(STM32F1系列通用)
- 将固件库文件stm32f10x_usart.c添加至工程
- 编写头文件:定义串口数据接收结构体,extern结构体变量,函数声明
- 编写驱动文件:
- 初始化函数:
- 使能端口时钟,串口时钟
- 配置GPIO口Tx、Rx引脚:GPIO_InitTypeDef
- 配置串口:波特率、字长、停止位、校验位
- 使能串口
- 清楚接收完成TC中断标志位、开启RXNE接收中断、开启IDLE空闲中断
- NVIC配置:中断源、优先级、使能
- 定义串口数据接收结构体变量
- 中断函数:判断当前中断类型,执行相应的操作
- 初始化函数:
- 编写按键驱动程序
-
- 编写头文件:宏定义连接按键的端口、端口引脚、端口时钟、引脚位带、按键值,函数声明
- 编写驱动文件:
- 按键初始化函数:开启端口时钟,定义GPIO_InitTypeDef结构体变量并初始化
- 按键检测函数:检测到按键被按下,延时10ms消抖,再次确认按键被按
- 编写SPI驱动程序:
- 编写头文件:SPI2端口、引脚、时钟定义,函数声明
- 编写驱动文件:
- SPI初始化函数:开启SPI时钟、端口时钟,总线引脚配置为复用推完输出模式,SPI基本参数配置,使能SPI2
- SPI速度设置函数:直接写CR1寄存器,SPI速度=APB1速度÷分频系数
- 发送&接收数据函数:SPI数据传输需发送数据驱动
- 编写FLASH驱动程序:
- 编写头文件:片选引脚定义,常用指令定义,函数声明
- 编写驱动文件:
- EN25Q128初始化函数:开启端口时钟,设置片选引脚为推挽输出,拉高引脚,调用SPI初始化函数、速度设置函数
- 读数据函数:CS选