学习HAL库STM32F103C8T6(SPI、门禁密码实验)
一、SPI
1.1 IIC与SPI对比
1.2 SPI是什么?
1.3 SPI物理架构
SPI 总线包含 4 条通讯线,分别为 SS、SCK、MOSI、MISO。它们的作用介绍如下 :
(1) MISO – Master Input Slave Output,主设备数据输入,从设备数据输出
(2) MOSI – Master Output Slave Input,主设备数据输出,从设备数据输入
(3) SCK – Serial Clock,时钟信号,由主设备产生
(4) CS – Chip Select,片选信号,由主设备控制
1.4 SPI工作原理
SPI 通信中,主机和从机都有一个串行移位寄存器。主机通过向自己的 SPI 串行寄存器写入一个字节来发起 传输。
首先,拉低相应的 SS 信号线,表示与特定的从机进行通信。
2. 主机通过发送 SCLK 时钟信号告诉从机进行数据的读写操作。
3. 注意,SCLK 时钟信号可以是低电平有效或高电平有效,因为SPI有不同的模式(下文将介绍)。
4. 主机将要发送的数据写入发送数据缓冲区,然后通过移位寄存器逐位地将数据传输给从机的串行移位寄 存器,使用 MOSI 信号线进行传输。同时,从机的 MISO 接口接收到的数据也经过移位寄存器一位一位 地移到接收缓冲区。
5. 从机也通过 MISO 信号线将自己串行移位寄存器中的内容返回给主机。同时,从机通过 MOSI 信号线接 收主机发送的数据。这样,两个移位寄存器中的内容就被交换。
SPI通信只有主模式和从模式,没有明确的读和写操作之分。实际上,外设的写操作和读操作是同步完成的。 在SPI通信中,发送一个数据必然会收到一个数据;如果要接收一个数据,就必须先发送一个数据。
如果只进行写操作,主机可以忽略从设备传输过来的字节,因为主机不需要接收数据。
如果主机要读取从设备的一个字节,那么主机必须发送一个空字节来引发从设备的传输。
1.5 SPI工作模式
时钟极性(CPOL):
没有数据传输时时钟线的空闲状态电平
0:SCK在空闲状态保持低电平
1:SCK在空闲状态保持高电平
时钟相位(CPHA): 时钟线在第几个时钟边沿采样数据
0:SCK的第一(奇数)边沿进行数据位采样,数据在第一个时钟边沿被锁存
1:SCK的第二(偶数)边沿进行数据位采样,数据在第二个时钟边沿被锁存
模式 0 和模式 3 最常用。
模式 0 时序图:
模式 3 时序图:
二、项目:门禁密码
2.1 项目需求
1. 矩阵键盘输入密码,正确则开锁,错误则提示;
2. 按下#号确认输入,按下*号修改密码;
3. 密码保存在 W25Q128 里;
4. OLED 屏幕显示信息。
2.2 硬件清单
矩阵键盘
OLED 屏幕
W25Q128
三、W25Q128介绍
3.1 W25Q128型号介绍
W25Q128是华邦公司推出的一款容量为 128M-bit(相当于 16M-byte)的 SPI 接口的 NOR Flash 芯片。 给大家解释一下新单词:
NOR Flash:一种非易失性存储器,它可以在断电或掉电后仍然保持存储的数据,因此被广泛应用于长 期数据存储。它具有容量大,可重复擦写、按“扇区/块”擦除的特性。Flash 是有一个物理特性:只能写 0 ,不能写 1 ,写 1 靠擦除。
它还有很多不同容量的好兄弟:
3.2 W25Q128模块参数及引脚介绍
W25Q128 的模块各个厂家做的各有不同,只是长得不一样而已,使用方式、引脚都是一样的。下面我介绍 的是我们自绘的 W25Q128 模块。
W25Q128参数:
3.3 W25Q128存储架构
W25Q128 将 16M 的容量分为 256 个块(block),每块 64K 字节;每块分为 16 个扇区(sector),一扇 区 4K 字节;每扇区分为 16 个页(page),一页 256 字节。
W25Q128 的最小擦除单位为一个扇区,也就是每次必须擦除 4K 个字节。这样我们需要给 W25Q128 开辟 一个至少 4K 的缓存区。
3.4 W25Q128常用指令
W25Q128 有非常多的指令,这里我们只介绍几个指令。
3.5 W25Q128状态寄存器
3.6 W25Q128驱动代码
3.6.1 各引脚在不同模式下的模式
3.6.2 代码编写
头文件
驱动代码编写
主函数调用(实现写读操作)
四、矩阵键盘
4.1 型号介绍
我们矩阵键盘的型号多种多样,有 1x4、3x3、3x4、4x4,甚至是 8x8 的;有薄膜的,有按键的。
4.2 工作参数及引脚介绍
引脚介绍:
按键式的有的有引脚标识,R 是行,C 是列。
有的没有引脚标识,可以找商家问下,或者自己看原理 图。
4.3 矩阵键盘工作原理
矩阵键盘由行列两路信号组成矩阵,每个按键连接到行列的交叉点。也就是说识别时一端必须是输出高电平 或者低电平,另一端去检测是否是高电平或者低电平。
矩阵键盘识别常用——逐行逐列扫描法
1. 使列线连接的I/O引脚输出低电平,四条行线所连接的I/O引脚输出高电平。当没有按键按下时,四条行 线所连接的I/O引脚读取到的将时全部是高电平;而当有按键按下时,由于该按键所在的行线与列线相 通,行线将被下拉到低电平。此时读取行线所连接的引脚,将不在是高电平。
2. 逐列将列线将依次置低电平,读取行线,如果某一条行线为低电平,则说明该行线与当前为低电平的列 线交叉点处的按键被按下,从判断按键按下。
大家看完逐行逐列扫描法是不是觉得,有点麻烦?所以我改进了一下,我们用中断来实现识别。
1. 把所有行引脚设成中断引脚,下降沿触发,且上拉输出高电平。
2. 把所有列引脚设成输入,内部下拉。 这样,当有中断触发的时候就可以知道哪一行有按键按下,再逐列看哪一列变成高电平,就是哪个按键被触 发了。
4.4 代码编写
头文件
驱动代码编写
主函数调用
五、OLED代码改写
OLED驱动代码跟之前写过的一模一样,加了几个这个项目用的到的函数
5.1 代码编写
用取模工具把要用的汉字取好放在头文件中备用
改写后的代码
头文件编写
驱动代码编写
六、最终代码编写
将以上模块代码集成到一个文件代码中
代码编写
头文件编写
项目函数代码实现
主函数编写
最终实现项目需求