FPGA解析串口指令控制spi flash完成连续写、读、擦除数据

前言

最近在收拾抽屉时找到一个某宝的spi flash模块,如下图所示,我就想用能不能串口来读写flash,大致过程就是,串口向fpga发送一条指令,fpga解析出指令控制flah,这个指令协议目前就是:
55 + AA + CMD + LEN_h + LEN_m + LEN_l + DATA
CMD:01 写;02 读;03 擦除(片擦除);
LEN_h/m/l:三个字节表示读写长度,高字节在前低字节灾后;
DATA:如果是写flah,DATA则为需要写入的数据,其它两种状态可以不填;
spi flash模块

1. 串口指令解析

软件使用序列式状态机完成串口指令解析,最后解析出三个使能信号,以及相应的数据、长度、地址。
在这里插入图片描述

always@(posedge clk,negedge rst_n)if(!rst_n)state<=S0;else begincase(state)S0:if(uart_vld)beginif(uart_dat == 8'h55)state<=S1;elsestate<=S0;					end else state<=S0;					S1:if(uart_vld)beginif(uart_dat == 8'hAA)state<=S2;elsestate<=S0;					end else state<=S1;S2:if(uart_vld)state<=S3;elsestate<=S2;S3://命令字if(uart_vld)state<=S4;elsestate<=S3;		S4://长度hif(uart_vld)state<=S5;elsestate<=S4;	S5://长度mif(uart_vld)state<=S6;elsestate<=S5;S6://长度lif(uart_vld)state<=S7;elsestate<=S6;S7:state<=S7;default:state<=S0;	endcaseend

2. flash 控制

对于flash三个功能(读、写、擦书)分别设计了三个模块,每个模块完成对应功能以及输出flash的cs、sclk、sdi等信号,但是flash接口只有一组控制信号,因此需要对三个模块输出的flash控制信号进行选择输出,如下所示。

always@(posedge clk,negedge rst_n)if(!rst_n)begino_spi_cen	<=1'b1;		o_spi_sclk	<=1'b0; 		o_spi_sdi	<=1'b0; 	end else begincase(work_state)3'b001:begin//xieo_spi_cen	<= wr_flash_csn		;o_spi_sclk	<= wr_flash_sclk		;o_spi_sdi	<= wr_flash_sdi		;end3'b010:begin//duo_spi_cen	<= rd_flash_csn		;o_spi_sclk	<= rd_flash_sclk		;o_spi_sdi	<= rd_flash_sdi		;end	3'b100:begin//cachuo_spi_cen	<= er_flash_csn		;o_spi_sclk	<= er_flash_sclk		;o_spi_sdi	<= er_flash_sdi		;end	default:begino_spi_cen	<=1'b1;		o_spi_sclk	<=1'b0; 		o_spi_sdi	<=1'b0; endendcaseendassign 	work_state	={spi_flash_erctl,spi_flash_rdctl,spi_flash_wrctl};			

2.1 flash写控制

软件对flash写控制的基本方法是收到一个串口数据就写进flash,并不是先缓存256个字节然后直接进行页编程,这样搞控制逻辑比较复杂。方法确定后就是软件实现,上级输出了vld和data(vld和data上上沿对齐,vld只有一个时钟宽度),使用vld作为触发条件,完成数据写入。
同样软件使用序列式状态机器进行流程控制。然后先写使能,然后正常写指令(02)、地址数据。
在这里插入图片描述

always@(posedge clk,negedge rst_n)if(!rst_n)state<=S0;else if(clken)begincase(state)S0:if(spi_flash_ctlr[2] && vld_zk)state<=S1;elsestate<=S0;S1://xieshineng  function code 06if(&cnt && cnt_bit=='d7)state<=S2;else	state<=S1;S2://delayif(&cnt && cnt_bit==WIDTH-1)state<=S3;else	state<=S2;S3://xie gongneng ma 02if(&cnt && cnt_bit=='d7)state<=S4;else state<=S3;S4://xie dizhiif(&cnt && cnt_bit=='d23)state<=S5;else state<=S4;S5://xie shuju if(&cnt && cnt_bit=='d7)state<=S6;else state<=S5;S6:if(&cnt)state<=S7;else state<=S6;S7:if(cnt_byte == wr_len)state<=S8;elsestate<=S0;S8:state<=S8;default:state<=S0;endcaseend

写

2.2 flash擦除

直接在写控制上面改,前面有个写使能,下图是擦除指令(C7/60)
在这里插入图片描述

always@(posedge clk,negedge rst_n)if(!rst_n)state<=S0;else if(clken)begincase(state)S0:if(spi_flash_ctlr[2:1]==2'b01)state<=S1;elsestate<=S0;S1://xieshineng  function code 06if(&cnt && cnt_bit=='d7)state<=S2;else	state<=S1;S2://delayif(&cnt && cnt_bit==WIDTH-1)state<=S3;else	state<=S2;S3://if(&cnt && cnt_bit=='d7)state<=S6;else state<=S3;S6:if(&cnt)state<=S7;else state<=S6;S7:state<=S8;S8:state<=S8;default:state<=S0;endcaseend

在这里插入图片描述

2.3 flash读控制

从falsh读数据比较简单,接口时序如下图,软件实现同样还是序列式状态机,根据传入的长度决定读取的字节数。
因为数据从flash读出后需要通过串口发送,因此为了减少工作量,从flash读出一个数据,串口就发送一个数据,因此为了避免flash两个数据都读出来了串口一个都没发完,需要控制flash读数间隔,使得这个间隔大于串口发完一个字节的时间,举个栗子,假设现在串口波特率为115200,那么发完一个字节的时间约为86.8us(10位),那么flash读数间隔要大于86.9us。
在这里插入图片描述

always@(posedge clk,negedge rst_n)if(!rst_n)state<=S0;else if(clken)begincase(state)S0:if(spi_flash_ctlr[2:1]==2'b01)state<=S1;elsestate<=S0;S1:state<=S2;S2://cs xian ladi 		if(&cnt)	state<=S3;else state<=S2;S3://xie gongneng ma 02if(&cnt && cnt_bit=='d7)state<=S4;else state<=S3;S4://xie dizhiif(&cnt && cnt_bit=='d23)state<=S5;else state<=S4;S5://xie shuju if(&cnt && cnt_bit=='d7)state<=S6;else state<=S5;S6:if(&cnt)state<=S7;else state<=S6;S7:if(cnt_byte == rd_len)state<=S8;elsestate<=S9;S9:if(dly_end)state<=S1;else state<=S9;S8:state<=S8;default:state<=S0;endcaseend

在这里插入图片描述

3. 实物测试

开始我设置的波特率为921600,擦除和写没问题,至少在时序上是很完美的,但是回读出来的数据如下图前十个字节一样,本来写入是01~0a,现在读出的数据中第2、3、5、7、9都是FF,后来我把波特率降到9600,然后就好了,下图最后10个字节。中间10个ff是擦除完后读出来数据。
软件工程链接:
软件工程、源码、仿真、数据手册、fllash仿真模型
在这里插入图片描述
最后来张全家福
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/104976.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Java架构-包管理工具】-Maven基础(一)

本文摘要 Maven作为Java后端使用频率非常高的一款依赖管理工具&#xff0c;在此咱们由浅入深&#xff0c;分三篇文章&#xff08;Maven基础、Maven进阶、私服搭建&#xff09;来深入学习Maven&#xff0c;此篇为开篇主要介绍Maven概念、模型、安装配置、基本命令 文章目录 本文…

微信开发之一键创建微信群聊的技术实现

创建微信群 本接口为敏感接口&#xff0c;请查阅调用规范手册创建后&#xff0c;手机上不会显示该群&#xff0c;往该群主动发条消息手机即可显示。 请求URL&#xff1a; http://域名地址/createChatroom 请求方式&#xff1a; POST 请求头Headers&#xff1a; Content-T…

LeetCode——二叉树篇(八)

刷题顺序及思路来源于代码随想录&#xff0c;网站地址&#xff1a;https://programmercarl.com 目录 236. 二叉树的最近公共祖先 235. 二叉搜索树的最近公共祖 迭代 递归 701. 二叉搜索树中的插入操作 450. 删除二叉搜索树中的节点 236. 二叉树的最近公共祖先 给定一个二…

睿趣科技:抖音开网店要怎么找货源

在当今数字化的时代&#xff0c;电商平台的兴起为越来越多的人提供了开设网店的机会&#xff0c;而抖音作为一个充满活力的短视频平台&#xff0c;也为创业者提供了广阔的发展空间。然而&#xff0c;对于许多初次涉足电商领域的人来说&#xff0c;找到合适的货源却是一个重要的…

无涯教程-PHP - 全局变量函数

全局变量 与局部变量相反,可以在程序的任何部分访问全局变量。通过将关键字 GLOBAL 放置在应被识别为全局变量的前面,可以很方便地实现这一目标。 <?php$somevar15;function addit() {GLOBAL $somevar;$somevar;print "Somevar is $somevar";}addit(); ?> …

全球纳米烧结银市场年复合增长率为6.5%!

烧结银简单来讲是指经过低温烧结技术将纳米银粉&#xff08;平均粒径<0.1μm(100nm)&#xff09;印刷在承印物上&#xff0c;使之成为具有传导电流和排除积累静电荷能力的银浆&#xff0c;其由导电填料——银粉、粘合剂、溶剂及改善性能的微量添加剂组成&#xff0c;使用低熔…

【数据结构】复杂度

&#x1f525;博客主页&#xff1a;小王又困了 &#x1f4da;系列专栏&#xff1a;数据结构 &#x1f31f;人之为学&#xff0c;不日近则日退 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 目录 一、什么是数据结构 二、什么是算法 三、算法的效率 四、时间复杂度 4.…

RT-Thread学习——简介

简介 RT-Thread是一个实时操作系统&#xff0c;移植到stm32单片机上。 常见的操作系统&#xff1a; Windows、Linux、MAC安卓、IOS鸿蒙操作系统 RT-Thread是一个集实时操作系统&#xff08;RTOS&#xff09;内核、中间件组件和开发者社区于一体的技术平台。 RT-Thread也是…

手把手教你部署Jenkins教程,小白也能学会(多图预警)!

背景 公司的前端、后端构建及部署工作都是人工去做&#xff0c;随着业务扩大&#xff0c;项目迭代速度变快&#xff0c;人员增多&#xff0c;各种问题都暴露出来&#xff0c;将通过一个简单案例分享一下基于Jenkins的前后端自动化工作流搭建的过程&#xff0c;搭建完这套工作流…

Matlab高光谱遥感数据处理与混合像元分解实践技术

光谱和图像是人们观察世界的两种方式&#xff0c;高光谱遥感通过“图谱合一”的技术创新将两者结合起来&#xff0c;大大提高了人们对客观世界的认知能力&#xff0c;本来在宽波段遥感中不可探测的物质&#xff0c;在高光谱遥感中能被探测。以高光谱遥感为核心&#xff0c;构建…

基于Java+SpringBoot+vue前后端分离夕阳红公寓管理系统设计实现

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

上传WSL项目到gitlab

上传WSL项目到gitlab 设置ssh将SSH公钥添加到Gitlab 将WSL上的代码上传到gitlab确保在WSL环境中安装了git下面是上传代码到GitLab的具体步骤&#xff1a; 可能遇到的各种错误 设置ssh Gitlab添加SSH KEY 什么是SSH ? SSH 是一种网络协议&#xff0c;具备协议级别的认证及会话…

stm32之11.USART串口通信

可以添加上拉电阻&#xff0c;但会增加功耗&#xff0c;传输距离变长 要添加库函数USART 官方参考文档说明书位置 ALT&#xff0b;左键可实现整体删除&#xff08;如下图&#xff09; 输出模式第三种模式AF ---------------------- 源码 远程控制pc端 #include <stm32f4x…

【keepalived双机热备与 lvs(DR)】

目录 一、概述 1.简介 2.原理 3.作用 二、安装 1.配置文件 2.配置项 三、功能模块 1.core 2.vrrp 3.check 四、配置双机热备 1.master 2.backup 五、验证 1.ping验证 2.服务验证 六、双机热备的脑裂现象 七、keepalivedlvs&#xff08;DR&#xff09; 1.作…

CAD泰森多边形框架3D插件

插件介绍 CAD泰森多边形框架3D插件可用于在AutoCAD软件内生成三维Voronoi框架结构实体模型&#xff0c;适用于多孔Voronoi科研论文渲染绘图、Voronoi框架有限元建模、Voronoi空间结构优化等方面的应用。 使用说明 插件可设置生成的几何尺寸、晶格尺寸及边框直径等信息。 插…

说点大实话丨知名技术博主 Kirito 测评云原生网关

作者&#xff1a;徐靖峰 关注了阿里云云原生公众号&#xff0c;经常能看到 MSE-Higress 相关的推文&#xff0c;恰逢这次阿里云产品举办了一个 MSE-Higress 云原生网关的测评活动&#xff0c;借此机会体验了一把云原生网关的功能。 购买流程体验 购买网关时&#xff0c;页面明…

Ubuntu16.04-ros-kinetic环境搭建笔记=1=

tips&#xff1a;搬运资料&#xff0c;留个记录 安装Ubuntu Ubuntu官网下载地址 安装 虚拟机安装Ubuntu 最好断网安装Ubuntu&#xff0c;可以节约时间 Ubuntu基础设置 Ubuntu换国内源 换成清华源 sudo apt upgradeVMwareTool安装 把这个压缩包拖到桌面&#xff0c;否则只读…

ms-tpm-20-ref 在linux下编译

1、代码地址&#xff0c; GitHub - microsoft/ms-tpm-20-ref: Reference implementation of the TCG Trusted Platform Module 2.0 specification.Reference implementation of the TCG Trusted Platform Module 2.0 specification. - GitHub - microsoft/ms-tpm-20-ref: Refe…

keepalived双机热备,keepalived+lvs(DR)

本节主要学习了keepalivedlvs的作用和配置方法主要配置调度器和web节点&#xff0c;还有keepalived的双击热备&#xff0c;主要内容有概述&#xff0c;安装&#xff0c;功能模块&#xff0c;配置双击热备&#xff0c;验证方法&#xff0c;双击热备的脑裂现象和VIP无法通信。 目…

【uni-app】压缩图片并添加水印

总体思路 dom 结点 这里的 cvHeight 和 cvWidth 初始时要设置为你后续需要压缩后的最大宽高。假设我们在图片上传后图片最大为 350 * 350 <u-upload :fileList"baseInfoFormData.entrustFileList" afterRead"afterFileRead" multiple></u-uploa…