目录
一、SPI&W25Q64
1-SPI介绍
SPI(Serial Peripheral interface):是由Motorola公司开发的串行外围设备接口,是一种高速的,全双工,同步的通信总线。主要应用在 EEPROM,FLASH,实时时钟,AD转换器,还有数字信号处理器和数字信号解码器等器件。
SPI通信特征:同步串行全双工 25Mhz
FLASH:具备掉电不丢失数据 读写速度快 特征:只能写0(将1变为0)不能写1(不能将0变为1)
写之前必须要擦除要写的区域 擦除之后的区域每个位都会变成1
反正说白了就是要调通SPI,在这个例程里用IO模拟SPI的模式3,SPI模式三的时序自己去看看吧QAQ
SPI工作原理:
主机拉低片选(激活从机)
主机控制时钟线产生上升沿(下降沿)发送方发送数据
主机控制时钟线产生下降沿(上升沿)接收方采集数据
….
主机拉高片选(通信结束)
2-初始化SPI
硬件分析:
从图上可知需要初始化4个管脚,初始化之前需要去找到相对应的GPIO口:
从图上可得对应GPIO:
FLASH_SPI1_CS --- PA4 --- 通用推挽输出
FLASH_SPI1_SCLK --- PA5 --- 通用推挽输出
FLASH_SPI1_MISO --- PA6 --- 输入模式
FLASH_SPI1_MOSI --- PA7 --- 通用推挽输出
W25Q64 SPI初始化代码如下:文件名为w25q64.c
void W25q64_Init(void)
{
GPIO_InitTypeDef gpio_InitTypeDef;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
gpio_InitTypeDef.GPIO_Mode = GPIO_Mode_OUT;
gpio_InitTypeDef.GPIO_OType = GPIO_OType_PP;
gpio_InitTypeDef.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_7;
GPIO_Init(GPIOA,&gpio_InitTypeDef);
gpio_InitTypeDef.GPIO_Mode = GPIO_Mode_IN;
gpio_InitTypeDef.GPIO_Speed = GPIO_Speed_100MHz;
gpio_InitTypeDef.GPIO_Pin = GPIO_Pin_6;
GPIO_Init(GPIOA,&gpio_InitTypeDef);
W25Q64_CS = 1;
W25Q64_CLK = 1;
}
这里用了位带宏定义了片选、时钟线和数据线,大家注意一下,最后再给大家w25q64.h的代码吧,我们继续往下
3-SPI数据接收和发送函数
根据模式三时序写数据交换函数:
u8 W25q64_DataTransfer(u8 data)
{
u8 i;
u8 buf = 0;
W25Q64_CLK = 1;
for(i=0;i<8;i++)
{
W25Q64_CLK = 0;
if(data & (0x80 >> i))
{
W25Q64_MOSI = 1;
}
else
{
W25Q64_MOSI = 0;
}
W25Q64_CLK = 1;
buf <<= 1;
if(W25Q64_MISO)
buf |= 1;
}
return buf;
}
注意:SPI高位先发,数据长度为8bit
4-验证SPI是否配置正确(读W25Q64的ID)
看图
根据W25Q64参考手册步骤编写代码:
void W25q64_ReadID(void)
{
u16 id = 0;
W25Q64_CS = 0;
W25q64_DataTransfer(0x90);
W25q64_DataTransfer(0x00);
W25q64_DataTransfer(0x00);
W25q64_DataTransfer(0x00);
id = W25q64_DataTransfer(0xff);
id = id << 8 | W25q64_DataTransfer(0xff);
W25Q64_CS = 1;
printf("ID:%#x\r\n",id);
// return id;
}
main.c
int main(void)
{
Usart1_Init(115200);
LED_Config();
W25q64_Init();
Dma_Init();
printf("初始化成功!!!\r\n");
W25q64_ReadID();
while(1)
{
}
}
读取ID效果:
得出W25Q64ID为0XEF16,证明SPI配置正确,能正常与W25Q64通信啦,到这一步头文件自己写应该没什么问题,但也放出来吧,给大家参考一下:
w25q64.h
#ifndef _W25Q64_H
#define _W25Q64_H
#include "stm32f4xx.h"
#include "io_bit.h"
#include "stdio.h"
#define W25Q64_CS PAout(4)
#define W25Q64_CLK PAout(5)
#define W25Q64_MISO PAin(6)
#define W25Q64_MOSI PAout(7)
void W25q64_Init(void);
void W25q64_ReadID(void);
#endif
二、W25Q64简介与API函数
1 - W25Q64芯片介绍
大小:8Mbyte = 8388608byte = 8192kbyte
一页:256byte
标准通信速度:80Mhz
Sector Erase:扇区擦除 4K(最小的擦除单位) 给它擦除的首地址(只能是4096的倍数 0 4096 8192)
1Kbyte = 1024字节 4K = 4096byte 10 (0 ~ 4095) 5000 (4096 – 8191)
Block Erase:块擦除:32K – 64K
最多擦除:10W次
数据保存:20年
2- W25Q64芯片管脚说明
3- W25Q64芯片工作原理
利用SPI发送指令来操作W25Q64
EF16
读ID:可以验证芯片的真伪,检验SPI通信正常不正常
4- W25Q64芯片操作时序
- 写使能
- 读状态寄存器
- 页写
页写最多写256字节的数据(不会自动换页)
- 扇区擦除
- 读ID
读到0xEF16表示SPI驱动成功
- 读数据
大家先看上面的吧,代码晚点补,大家可以多催催我,要资料的留邮箱吧
三、字库烧录
1-烧录字库准备工作
1 什么是字库
2 制作字库
2-利用串口烧录字库到Flash
软件代码连接
链接:https://pan.baidu.com/s/1paV-HYv9ZatbRvOKMl6tRg?pwd=4cxm
提取码:4cxm