官方提供的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. Canal 组件简介与 vivo 帐号实践

    互联网应用随着业务的发展,部分单表数据体量越来越大,应对服务性能与稳定的考虑,有做分库分表.数据迁移的需要,本文介绍了vivo帐号应对以上需求的实践. 一.前言 Canal 是阿里巴巴开源项目,关于什 ...

  2. 2023是AI爆发的元年,程序员赚钱的机会来了,附49个机会!

    以下是程序员利用AI做代码生成的赚钱思路.方案,共49条,按照不同分类列出: 基于自然语言生成的机会: 1. 开发基于AI的自动生成代码软件,应用于网站开发.移动应用开发.家庭自动化.人工智能等各个领 ...

  3. C# 排序算法1: 冒泡排序

    本文用控制台程序展示数据排序前后的变化,本文数据都按将从小到大进行排序. 1.  准备arr数据  及 arr数据的展示 /// <summary> /// 生成n个元素的int数组 // ...

  4. kafka 在 zookeeper 中保存的数据内容

    转载请注明出处: 1. 服务器上下载 kafka : wget https://archive.apache.org/dist/kafka/2.4.0/kafka_2.12-3.2.0.tgz 2.  ...

  5. idea中配置mybatis 映射文件模版及 mybatis plus 自定义sql

    本文为博主原创,未经允许不得转载: mybatis plus 使用过程中已经很大程度提升了我们开发的效率,因为它内部已经对单表的操作进行了完美的封装,但是关联表操作时, 这时就需要自己定义sql,自定 ...

  6. AI毕业设计生成器(基于AI大模型技术开发)

    这是一个辅助生成计算机毕业设计的工具,可以自动完成毕业设计的源码.它基于几百个github上面开源的java和python项目,运用tengsorflow技术,训练出了AI大模型.基本实现了计算机毕业 ...

  7. 问题--VSCODE编写C含scanf无终端跳出

    1.问题 在VSCODE中编写C程序,用到scanf输入时,发现无终端输入数据 2.解决方法 在设置里搜索RunInTerminal,勾选该选项即可

  8. Laravel - 创建项目

    1,创建目录 ( 路径不要带有中文 ) 2,进入目录,执行下列命令 composer create-project --prefer-dist laravel/laravel project

  9. Mongo-文档主键-ObjectId

    文档主键 文档主键时 _id,如果插入文档时,没有传入则自动生产ObjectId 作为文档主键 文档主键要求在集合中唯一 文档主键可以时另一个文档,被当作字符串对象处理 ObjectId对象 获取文档 ...

  10. [转帖]Nginx 性能优化

    目录 1.调整 worker 进程数 2.调整 worker 连接数 3.调整 work 进程最大打开文件数 4.开启高效文件传输模式 5.限制文件上传大小 6.开启 gzip 压缩 7.本地缓存静态 ...