官方提供的58x的spi例程,spi主机模式下的发送方式有三种单字节发送,FIFO连续发送,DMA连续发送。本文分别对SPI0主机模式下三种发送模式进行使用。

本次使用的是CH582m做为主机,W25Q64FV作为从机。

一、单字节发送

本次调试中实现对W25Q64FVflas进行读id,擦除,写入,读取。

在进行主要操作的时候先理清代码逻辑。主机先将SCS总线拉低,保证能够开始接收数据。再通过W25Q64FV的手册我们知道在进行操作之前要判断当前是否在

忙碌状态。如果不在忙碌状态将进行下一步。通过手册我们可以知道通过发送对应的地址(0x05or0x35)进行判忙。

程序中实现判断忙碌的操作可见如下:

void SPI_Flash_Wait_Busy(void)
{
uint8_t busy;
do
{
GPIOA_ResetBits(GPIO_Pin_12);
SPI0_MasterSendByte(0x05); busy=SPI0_MasterRecvByte();
GPIOA_SetBits(GPIO_Pin_12); PRINT("busy%02x\r\n",busy);
}
while((busy&0x01)==0x01); }

接下来基本就按照需要使用的器件的手册进行读写等操作:

(1)、读ID:

读ID看是否能够读到正确的设备ID:

#define W25Q80 0XEF13
#define W25Q16 0XEF14
#define W25Q32 0XEF15
#define W25Q64 0XEF16
#define W25Q128 0XEF17

我们读ID根据手册的提示需要对就相应的寄存器地址进行操作;程序演示如下所示:

void read_wq64_id(void)
{
uint8_t ID1,ID2;
GPIOA_ResetBits(GPIO_Pin_12);
SPI0_MasterSendByte(0x90);
SPI0_MasterSendByte(0x00);
SPI0_MasterSendByte(0x00);
SPI0_MasterSendByte(0x00);
ID1=SPI0_MasterRecvByte();
ID2=SPI0_MasterRecvByte();
GPIOA_SetBits(GPIO_Pin_12); PRINT("%02x\r\n %02x\r\n ",ID1,ID2); }

读取到的数据是EF16证明读取的ID没有问题。如果是其他的值可以在程序加判断直到是自己使用器件的ID再在进行下面的操作;

(2)、擦除扇区

在写之前要对对应的扇区进行擦除,

从手册上可以看出是4k擦除,还要注意在指令之后有24bit地址的操作,写入20h后需要进行移位操作,详情可见程序

手册中有这样一句话:A Write Enable instruction must be executed before the device will accept the Sector Erase Instruction (Status Register bit WEL must equal 1)。在进行擦除操作之前需要写使能:

所以擦除之前需要进行写使能:对应时序操作如下

代码实现:

void SPI_Write_Enable(void)
{
GPIOA_ResetBits(GPIO_Pin_12);
SPI0_MasterSendByte(0x06);
GPIOA_SetBits(GPIO_Pin_12); }

下面的则是擦除部分的代码:

void erase_sector(uint32_t SectorAddress)
{
SectorAddress *= 4096;
SPI_Write_Enable();
SPI_Flash_Wait_Busy();
GPIOA_ResetBits(GPIO_Pin_12);
SPI0_MasterSendByte(0x20); SPI0_MasterSendByte((uint8_t)(SectorAddress>>16));
SPI0_MasterSendByte((uint8_t)(SectorAddress>>8));
SPI0_MasterSendByte((uint8_t)SectorAddress);
GPIOA_SetBits(GPIO_Pin_12); }

(3)读操作,

进行读操作的情况下;读的操作稍微方便一些不需要进行判忙写使能等操作

在进行读操作的时,注意时序图中有一个Data Out 1,此时会有输出

void read_wq64_data(uint8_t instruction,uint32_t ReadAddr,uint16_t ReadByteNum,uint8_t *p_Buffer)
{
uint16_t i;
GPIOA_ResetBits(GPIO_Pin_12);
SPI0_MasterSendByte(instruction);
SPI0_MasterSendByte((uint8_t)(ReadAddr>>16));
SPI0_MasterSendByte((uint8_t)(ReadAddr>>8));
SPI0_MasterSendByte((uint8_t)ReadAddr); for(i = 0; i < ReadByteNum; i++)
{
p_Buffer[i] = SPI0_MasterRecvByte(); }
GPIOA_SetBits(GPIO_Pin_12); }

(5)写操作;

本次写入是按页写入,写之前先看手册注意手册中需要操作的部分

对应程序如下所示:

void  write_wq64_page_data(uint8_t *p_Buffer,uint32_t PageAddress,uint16_t WriteByteNum)
{
SPI_Write_Enable(); GPIOA_ResetBits(GPIO_Pin_12);
SPI0_MasterSendByte(0x02);
SPI0_MasterSendByte((uint8_t)(PageAddress>>16));
SPI0_MasterSendByte((uint8_t)(PageAddress>>8));
SPI0_MasterSendByte((uint8_t)PageAddress);
if(WriteByteNum > 256)
{
WriteByteNum=256;
PRINT("\r\n Err");
}
while(WriteByteNum--)
{
SPI0_MasterSendByte(*p_Buffer);
p_Buffer++;
}
GPIOA_SetBits(GPIO_Pin_12);
SPI_Flash_Wait_Busy();
}

差不多一个流程就是如此;可以在程序中加入打印或者使用逻辑分析仪等辅助工具对现象进行查看。

准备写入的数据__attribute__((aligned(4))) UINT8 spiBuff[] = {2, 2, 3, 3, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6};读出的结果如下

本次操作关键是对片选信号线的操作与对不同指令的读写操作,具体按照手册的时序的操作来即可。

仅是个人学习分享;如有任何错漏敬请留言指正。

CH58x/CH57x硬件SPI操作外部flash学习记录的更多相关文章

  1. STM32学习笔记(八) SPI总线(操作外部flash)

    1. SPI总线简介 SPI全称串行外设接口,是一种高速,全双工,同步的外设总线:它工作在主从方式,常规需要至少4根线才能够正常工作.SPI作为基本的外设接口,在FLASH,EPPROM和一些数字通讯 ...

  2. KL25用SPI操作nor flash

    KL25的SPI连接一个nor flash.该flash型号为FM25F04,支持SPI的模式0和模式3,要求高位先发送,在上升沿采集数据. 通常,SPI有4种模式,取决于CPOL与CPHA如何配置. ...

  3. spi数据KL25用SPI操作nor flash

    最近研究spi数据,稍微总结一下,以后继续补充: KL25的SPI连接一个nor flash.该flash型号为FM25F04,支撑SPI的模式0和模式3,要求高位先发送,在上升沿采集数据. 通常,S ...

  4. ESP8266清理flash学习记录

    学习来源:http://bbs.eeworld.com.cn/thread-497588-1-1.html 还稍看了电子产品世界 主要内容 1在windows 上通过 命令行 安装  Python环境 ...

  5. php 链式操作的实现 学习记录

    php 面向对象中实现链式操作的关键部分:调用的方法中返回当前对象 ,从而实现链式操作: <?php namespace commom; class db { public function w ...

  6. ElasticSearch 学习记录之ES几种常见的聚合操作

    ES几种常见的聚合操作 普通聚合 POST /product/_search { "size": 0, "aggs": { "agg_city&quo ...

  7. ElasticSearch 学习记录之 分布式文档存储往ES中存数据和取数据的原理

    分布式文档存储 ES分布式特性 屏蔽了分布式系统的复杂性 集群内的原理 垂直扩容和水平扩容 真正的扩容能力是来自于水平扩容–为集群添加更多的节点,并且将负载压力和稳定性分散到这些节点中 ES集群特点 ...

  8. ElasticSearch 学习记录之ES短语匹配基本用法

    短语匹配 短语匹配故名思意就是对分词后的短语就是匹配,而不是仅仅对单独的单词进行匹配 下面就是根据下面的脚本例子来看整个短语匹配的有哪些作用和优点 GET /my_index/my_type/_sea ...

  9. ElasticSearch 学习记录之如任何设计可扩容的索引结构

    扩容设计 扩容的单元 一个分片即一个 Lucene 索引 ,一个 Elasticsearch 索引即一系列分片的集合 一个分片即为 扩容的单元 . 一个最小的索引拥有一个分片. 一个只有一个分片的索引 ...

  10. ElasticSearch 学习记录之ES高亮搜索

    高亮搜索 ES 通过在查询的时候可以在查询之后的字段数据加上html 标签字段,使文档在在web 界面上显示的时候是由颜色或者字体格式的 GET /product/_search { "si ...

随机推荐

  1. Sentinel 是如何做限流的

    限流是保障服务高可用的方式之一,尤其是在微服务架构中,对接口或资源进行限流可以有效地保障服务的可用性和稳定性. 之前的项目中使用的限流措施主要是Guava的RateLimiter.RateLimite ...

  2. node做服务器

    // 用于创建网站服务器的模块 const http = require('http'); // 创建web服务器,app对象就是网站服务器对象 const app = http.createServ ...

  3. Redis 缓存常见问题

    本文为博主原创,未经允许不得转载: 目录: 1. 缓存穿透 1.1 出现原因 1.2 解决方案 1.3 布隆过滤器 2. 缓存雪崩 3. 缓存失效(缓存击穿,热点缓存) 1. 缓存穿透: 缓存穿透是指 ...

  4. Linux 安装 mysql 及配置存储位置

    本文为博主原创,未经允许不得转载: 新申请的服务器,需要确认服务器的磁盘是否进行了挂载,可参考这篇文章:https://www.cnblogs.com/zjdxr-up/p/14873242.html ...

  5. PHP安全之道学习笔记6:密码安全

    PHP安全之道:密码安全    最近几年用户数据泄露越发频繁,一些使用PHP技术的大型网站被暴库或者脱库,facebook公司曾因为此类事件股价暴跌.从长远发展来看,用户的数据安全对于网站来说至关重要 ...

  6. 一 , FileChanle

    package nio; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.ByteBuffer ...

  7. [IDEA] - 左侧目录结构没了,怎么处理

    把项目目录下的.idea删除,再重启IDEA打开项目就行了

  8. [转帖]oracle ZHS16GBK的数据库导入到字符集为AL32UTF8的数据库(转载+自己经验总结)

    字符集子集向其超集转换是可行的,如此例 ZHS16GBK转换为AL32UTF8. 导出使用的字符集将会记录在导出文件中,当文件导入时,将会检查导出时使用的字符集设置,如果这个字符集不同于导入客户端的N ...

  9. [转帖]Kafka 性能优化与问题深究

    Kafka 性能优化与问题深究 一.Kafka深入探究 1.1 kafka整体介绍 1. 1.1 Kafka 如何做到高吞吐.低延迟的呢? Kafka是一个分布式高吞吐量的消息系统,这里提下 Kafk ...

  10. [转帖]Unixbench的使用(综合性能测试、2D测试)和问题解决(跑不出多线程分数,调不出窗口,报错等)

    一.Unixbench简介 Unixbench一个基于系统的基准测试工具,不单纯是CPU 内存 或者磁盘测试工具.测试结果不仅仅取决于硬件,也取决于系统.开发库.甚至是编译器.Unixbench是一个 ...