深圳雷龙SD NAND的存储应用方案

news2024/10/6 22:25:40

前言:

        很感谢深圳雷龙发展有限公司为博主提供的两片SD NAND的存储芯片,在这里博主记录一下自己的使用过程以及部分设计。

深入了解该产品:

        拿到这个产品之后,我大致了解了下两款芯片的性能。CSNP4GCR01-AMW是一种基于NAND闪存和SD控制器的4Gb密度嵌入式存储;而CSNP32GCR01-AOW是一种基于NAND闪存和SD控制器的32Gb密度嵌入式存储。与原始NAND相比其具有嵌入式坏块管理和更强的嵌入式ECC。即使在异常断电,它仍然可以安全地保存数据。作为一个存储芯片,它确实做到了小巧,LGA-8的封装对比我之前用到过的TF卡,只占到了其面积的三分之一,这样对于一些嵌入式的设计就方便了很多。

         雷龙官方还很贴心的提供了样品的测试板,在这款测试板上,我焊接了4GB的CSNP4GCR01-AMW上去,并且跑了一下分,对于一款小的存储芯片而言,实在难得。

        (上图为测试板焊接图) 

       博主日前在设计基于H616与NB-IOT的嵌入式智能储物柜的时候考虑过存储方面的问题,当时在SD NAND和EMMC与TF卡中徘徊,以下是几个存储类型的对比。

         经过多方对比,本着不需要频繁更换的原则,同时也为了更好的防水和成本考虑,最终决定使用雷龙公司的SD NAND 作为设计样品的存储部分。

        此外,SD NAND还具有不用写驱动程序自带坏块管理的NAND FLASH(贴片式TF卡),不标准的SDIO接口,也同时兼容SPI/SD接口,10万次的SLC晶圆擦写寿命,通过一万次的随机掉电测试耐高低温,经过跑分测得,速度级别Class10。标准的SD2.0协议,普通的SD卡可以直接驱动,支持TF卡启动的SOC都可以用SD NAND,而且雷龙官方还贴心的提供了STM32参考例程和原厂技术支持,这对于刚上手的小白而言,十分友好。

设计理念:

        使用H616作为主控CPU并搭配NB-IOT来向申请下来的云端传输数据,当WIFI正常时,储物数据每搁两小时向云端传输一次,当有人取出物品时再次向云端发送一次数据(不保留在SD NAND中);一旦系统检测到WIFI出现问题,储物数据转而存储到SD NAND中,取物时输入的物品ID和取出时间一并放入SD NAND中(我也是看中了SD NAND与原始NAND相比其具有嵌入式坏块管理和更强的嵌入式ECC。即使在异常断电,它仍然可以安全地保存数据这一点)。

部分SD NAND的参考设计

        根据官方数据手册提供的SD NAND参考设计,只占用8个GPIO,对于H616来说,确实很友好

         这里为了不泄露他人的劳动成果,我也就不粘PCB设计了。

 采用H616驱动SD NAND的示例代码

        下面是关于H616驱动SD NAND的示例代码,这里记录一下自己当初的学习过程(注:这个代码不能直接拿过来就用,而是要根据自己的需求修改)

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "h616_sdio.h"

// 定义SDIO引脚
#define SDIO_CMD_PIN    0
#define SDIO_CLK_PIN    1
#define SDIO_D0_PIN     2
#define SDIO_D1_PIN     3
#define SDIO_D2_PIN     4
#define SDIO_D3_PIN     5

// 定义NAND芯片命令
#define CMD_READ        0x00
#define CMD_WRITE       0x80
#define CMD_ERASE       0x60
#define CMD_STATUS      0x70
#define CMD_RESET       0xff

// 定义NAND芯片状态
#define STATUS_READY    0x40
#define STATUS_ERROR    0x01

// 初始化SDIO控制器
void sdio_init()
{
    // 设置SDIO引脚模式和速率
    h616_sdio_set_pin_mode(SDIO_CMD_PIN, H616_SDIO_PIN_MODE_SDIO);
    h616_sdio_set_pin_mode(SDIO_CLK_PIN, H616_SDIO_PIN_MODE_SDIO);
    h616_sdio_set_pin_mode(SDIO_D0_PIN, H616_SDIO_PIN_MODE_SDIO);
    h616_sdio_set_pin_mode(SDIO_D1_PIN, H616_SDIO_PIN_MODE_SDIO);
    h616_sdio_set_pin_mode(SDIO_D2_PIN, H616_SDIO_PIN_MODE_SDIO);
    h616_sdio_set_pin_mode(SDIO_D3_PIN, H616_SDIO_PIN_MODE_SDIO);
    h616_sdio_set_clock(H616_SDIO_CLOCK_FREQ_25MHZ);

    // 初始化SDIO控制器
    h616_sdio_init();
}

// 发送NAND芯片命令
void nand_send_cmd(uint8_t cmd)
{
    // 设置SDIO控制器传输模式和命令码
    h616_sdio_set_transfer_mode(H616_SDIO_TRANSFER_MODE_WRITE);
    h616_sdio_set_command_code(cmd);

    // 发送命令
    h616_sdio_send_command();
}

// 发送NAND芯片地址
void nand_send_addr(uint32_t addr)
{
    // 设置SDIO控制器传输模式和地址
    h616_sdio_set_transfer_mode(H616_SDIO_TRANSFER_MODE_WRITE);
    h616_sdio_set_address(addr);

    // 发送地址
    h616_sdio_send_address();
}

// 读取NAND芯片数据
void nand_read_data(uint8_t *data, uint32_t size)
{
    // 设置SDIO控制器传输模式
    h616_sdio_set_transfer_mode(H616_SDIO_TRANSFER_MODE_READ);

    // 读取数据
    h616_sdio_read_data(data, size);
}

// 写入NAND芯片数据
void nand_write_data(const uint8_t *data, uint32_t size)
{
    // 设置SDIO控制器传输模式
    h616_sdio_set_transfer_mode(H616_SDIO_TRANSFER_MODE_WRITE);

    // 写入数据
    h616_sdio_write_data(data, size);
}

// 读取NAND芯片状态
uint8_t nand_read_status()
{
    uint8_t status;

    // 发送读取状态命令
    nand_send_cmd(CMD_STATUS);

    // 读取状态
    nand_read_data(&status, 1);

    return status;
}

// 等待NAND芯片准备就绪
void nand_wait_ready()
{
    uint8_t status;

    // 循环读取状态,直到NAND芯片准备就绪
    do {
        status = nand_read_status();
    } while ((status & STATUS_READY) == 0);
}

// 读取NAND芯片数据
void nand_read(uint32_t page, uint32_t column, uint8_t *data, uint32_t size)
{
    // 发送读取命令和地址
    nand_send_cmd(CMD_READ);
    nand_send_addr(column | (page << 8));

    // 等待NAND芯片准备就绪
    nand_wait_ready();

    // 读取数据
    nand_read_data(data, size);
}

// 写入NAND芯片数据
void nand_write(uint32_t page, uint32_t column, const uint8_t *data, uint32_t size)
{
    // 发送写入命令和地址
    nand_send_cmd(CMD_WRITE);
    nand_send_addr(column | (page << 8));

    // 写入数据
    nand_write_data(data, size);

    // 等待NAND芯片准备就绪
    nand_wait_ready();
}

// 擦除NAND芯片块
void nand_erase(uint32_t block)
{
    // 发送擦除命令和地址
    nand_send_cmd(CMD_ERASE);
    nand_send_addr(block << 8);

    // 等待NAND芯片准备就绪
    nand_wait_ready();
}

// 复位NAND芯片
void nand_reset()
{
    // 发送复位命令
    nand_send_cmd(CMD_RESET);

    // 等待NAND芯片准备就绪
    nand_wait_ready();
}

// 示例程序入口
int main()
{
    uint8_t data[2048];
    memset(data, 0x5a, sizeof(data));

    // 初始化SDIO控制器
    sdio_init();

    // 复位NAND芯片
    nand_reset();

    // 擦除第0块
    nand_erase(0);

    // 写入第0页
    nand_write(0, 0, data, sizeof(data));

    // 读取第0页
    nand_read(0, 0, data, sizeof(data));

    return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

paddle 52 在paddleseg中实现cutmix数据增强方式

CutMix是一种极其有效的数据增强方式,尤其是在遥感影像语义分割中。这主要是因为遥感影像标注成本较大,在实际业务中通常都是采用局部标注的方式进行标注,如下图所示仅对标注成本较小的区域进行标注,而对标注成本较大的地方进行忽略。这使得标签数据中各种类别边界较少(例…

【Python零基础学习入门篇③】——第三节:Python的字符串类型

⬇️⬇️⬇️⬇️⬇️⬇️ ⭐⭐⭐Hello&#xff0c;大家好呀我是陈童学哦&#xff0c;一个普通大一在校生&#xff0c;请大家多多关照呀嘿嘿&#x1f601;&#x1f60a;&#x1f618; &#x1f31f;&#x1f31f;&#x1f31f;技术这条路固然很艰辛&#xff0c;但既已选择&…

VS+Qt+C++银行排队叫号系统

程序示例精选 VSQtC银行排队叫号系统 如需安装运行环境或远程调试&#xff0c;见文章底部个人QQ名片&#xff0c;由专业技术人员远程协助&#xff01; 前言 这篇博客针对<<VSQtC银行排队叫号系统>>编写代码&#xff0c;带用户登录&#xff0c;管理员登录&#xff…

Mysql当中Json相关的函数详解

目录 一、前言二、创建JSON文本的函数2.1.JSON_ARRAY&#xff08;转换json数组&#xff09;2.2.JSON_OBJECT&#xff08;转换json对象&#xff09;2.3.JSON_QUOTE&#xff08;转义字符串&#xff09; 三、搜索JSON文本的函数3.1.JSON_CONTAINS&#xff08;json当中是否包含指定…

thinkphp6结合layui增删改查综合案列

文章目录 技术栈实现代码实现数据库 本案例适合新手&#xff0c;特别是杠刚入门thinkphp和layui&#xff0c;但又不是特别熟悉这类 主要实现登录退出功能&#xff0c;用户模块的增删改查功能&#xff0c;分页功能是layui表单自带功能 效果图 左侧的菜单栏我没有写对应的页面&am…

学习记录:2023.4.28

2023.4.28 实习学习记录 Vue1、SVG学习&#xff1a;2、watch监听&#xff1a;3、< g>标签&#xff1a; Vue 1、SVG学习&#xff1a; 百度百科&#xff1a;SVG是可缩放矢量图形&#xff0c;是基于可扩展标记语言(标准通用标记语言的子集)&#xff0c;用于描述二维矢量图…

二、C++、STL标准模板库和泛型编程 ——适配器、补充(侯捷)

侯捷 C八部曲笔记汇总 - - - 持续更新 ! ! ! 一、C 面向对象高级开发 1、C面向对象高级编程(上) 2、C面向对象高级编程(下) 二、STL 标准库和泛型编程 1、分配器、序列式容器 2、关联式容器 3、迭代器、 算法、仿函数 4、适配器、补充 三、C 设计模式 四、C 新标准 五、C 内存管…

时序预测 | MATLAB实现BO-CNN-LSTM贝叶斯优化卷积神经网络-长短期记忆网络时间序列预测

时序预测 | MATLAB实现BO-CNN-LSTM贝叶斯优化卷积神经网络-长短期记忆网络时间序列预测 目录 时序预测 | MATLAB实现BO-CNN-LSTM贝叶斯优化卷积神经网络-长短期记忆网络时间序列预测效果一览基本介绍模型搭建程序设计参考资料 效果一览 基本介绍 MATLAB实现BO-CNN-LSTM贝叶斯优…

c++标准模板(STL)(std::array)(四)

定义于头文件 <array> template< class T, std::size_t N > struct array;(C11 起) std::array 是封装固定大小数组的容器。 此容器是一个聚合类型&#xff0c;其语义等同于保有一个 C 风格数组 T[N] 作为其唯一非静态数据成员的结构体。不同于 C 风格数…

MySQL 高可用实战

文章目录 前言实现思路环境准备一、实现MySQL高可用1.1 修改配置文件1.2 MySQL监控脚本1.4 重启keepalived1.5 查看虚拟ip 二、高可用验证2.1 模拟宕机2.2 查看虚拟ip2.3 连接MySQL2.4 恢复主机2.5 查看虚拟ip 总结 前言 请各大网友尊重本人原创知识分享&#xff0c;谨记本人博…

基于脉搏波的疾病诊断:准确率接近100%的未来前景?

脉搏波分析作为一种无创诊断方法&#xff0c;在糖尿病诊断领域具有巨大潜力。某些研究表明&#xff0c;基于脉搏波的诊断方法在准确性方面可能优于传统血糖检测方法。然而&#xff0c;在将这种方法应用于临床之前&#xff0c;我们需要关注其稳定性、易用性、成本效益等因素。 首…

老胡的周刊(第089期)

老胡的信息周刊[1]&#xff0c;记录这周我看到的有价值的信息&#xff0c;主要针对计算机领域&#xff0c;内容主题极大程度被我个人喜好主导。这个项目核心目的在于记录让自己有印象的信息做一个留存以及共享。 &#x1f3af; 项目 MOSS[2] 来自复旦大学的开源工具增强型会话语…

翻译: 迁移学习和微调 Transfer learning fine-tuning

1. 介绍 迁移学习包括获取在一个问题上学到的特征&#xff0c;并将它们用于一个新的类似问题。例如&#xff0c;已经学会识别浣熊的模型的特征可能有助于启动旨在识别狸猫的模型。 迁移学习通常用于您的数据集数据太少而无法从头开始训练全尺寸模型的任务。 在深度学习的背景…

AI模型推理(1)——入门篇

前言 本文主要介绍AI模型推理的相关基础概念&#xff0c;为后续云原生模型推理服务的学习做准备。 初识模型部署 对于深度学习模型来说&#xff0c;模型部署指让训练好的模型在特定环境中运行的过程。相比于常规的软件部署&#xff0c;模型部署会面临更多的难题&#xff1a; …

SPI机制详细讲解

文章目录 SPI机制案例分析建立DriverManager建立MysqlDriver来实现扩展建立OracleDriver来实现扩展测试spitest 源码分析ServiceLoader类的结构reload加载类LazyIterator类parse解析URL对象方法parseLine方法 SPI机制 SPI &#xff0c;全称为 Service Provider Interface&…

Bridge模式如何配置

Bridge模式案例&#xff08;一&#xff09; 基于Docker引擎启动Nginx WEB容器&#xff0c;默认以Bridge方式启动Docker容器&#xff0c;会动态DHCP给Docker容器分配IP、网关等信息&#xff0c;操作指令如下&#xff1a; 查看镜像列表 docker images#运行新的Nginx容器 dock…

ChatGPT实现代码解释

代码解释 新手程序员在入门之初&#xff0c;最好的学习路径就是直接阅读其他人的代码&#xff0c;从中学会别人是怎么写的&#xff0c;为什么这么写。过去&#xff0c;这个学习过程可能需要广泛阅读官方文档&#xff0c;在 GitHub issue 上提问&#xff0c;上 Stack Overflow …

内网渗透(六十)之AS-REP Roasting攻击

AS-REP Roasting攻击 AS-REP Roasting是一种针对用户账户进行离线爆破的攻击方式。但是该攻击方式使用上比较受限,因为其需要用户账户设置“不要求Kerberos预身份验证”选项。而该选项默认是没有勾选的。Kerberos域身份验证发生在Kerberos身份验证的第一阶段(AS_REQ&AS_…

手记系列之四 ----- 关于使用MySql的一些经验

前言 本篇文章主要介绍的关于本人在使用MySql记录笔记的一些使用方法和经验&#xff0c;温馨提示&#xff0c;本文有点长&#xff0c;约1.5w字&#xff0c;几十张图片&#xff0c;建议收藏查看。 一、MySql安装 下载地址:https://dev.mysql.com/downloads/ 在安装MySql之前&a…

我在VScode学Java(Java一维数组)

我的个人博客主页&#xff1a;如果\真能转义1️⃣说1️⃣的博客主页 关于Java基本语法学习---->可以参考我的这篇博客&#xff1a;(我在Vscode学Java) 我在VScode学Java(Java一维数组&#xff09; Java 一维数组 声明数组&#xff1a;先声明&#xff0c;后使用 动态分配内…