官方提供的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. HashMap非线程安全到底有什么问题

    HashMap是Java中常用的数据结构,用于存储键值对,并且提供了快速的查找和插入操作.下面挖掘一下HashMap内部的架构设计思维: 哈希函数的设计: HashMap使用哈希函数将键映射到数组索引 ...

  2. SAE 最佳实践范本:助力视野数科进入云原生“快车道”

    阿里云生态金融科技行业标杆 -- ​ 2021 年,云原生的商业价值正在被加速释放. ​ 一个公认的事实是,Serverless 是当下云原生方向内绝对的亮点.可以看作,它的出现,让企业用户真正地免除 ...

  3. 假如有一个需求,我们要在一个页面中 ul 标签里渲染 **十万** 个 li 标签

    1 // 插入十万条数据 2 const total = 100000; 3 let ul = document.querySelector('ul'); // 拿到 ul 4 5 // 懒加载的思路 ...

  4. Linux vim-go 开发环境搭建

    本文介绍 Linux 下 vim-go 的开发环境搭建.主要参考这篇博客进行的配置,其中记录了几个搭建环境时遇到的问题. 1. vim-go 开发环境搭建 1.1 用户隔离 由于使用的是共享宿主机,为 ...

  5. Mysql 查询优化及索引优化总结

    本文为博主原创,转载请注明出处: 一.Mysql 索引的优缺点: 优点:加快数据的检索速度,这是应用索引的主要用途: 使用唯一索引可以保证数据的唯一性 缺点: 索引也需要占用物理空间,并不是索引越多越 ...

  6. 【SHELL】反斜杠解决多个shell实例扩展

    本意是想获取代码仓相对路径,代码如下 base_dir=`pwd` repo forall -c '{     user_dir=$(realpath --relative-to="$bas ...

  7. Redis-逻辑库-select

  8. mongo-基本操作

    mogo基本操作 mongo对命令大小写敏感,SQL对大小写不敏感 存放 json数据,一条json数据是一个文档 数据库 查看数据库 show databases 切换数据库 use db db 不 ...

  9. [转帖]京东大佬细说:Nginx反向代理时保持长连接,看完直呼"学到了!"

    https://mp.weixin.qq.com/s?__biz=MzU1MzE2NzIzMg==&mid=2247488405&idx=1&sn=7081ff4e0ac1de ...

  10. [转帖][java] GC (Allocation Failure)日志分析

    日前查看某个程序的日志,发现一直在报GC相关的信息,不确定这样的信息是代表正确还是不正确,所以正好借此机会再复习下GC相关的内容: 以其中一行为例来解读下日志信息: [GC (Allocation F ...