便携式气体分析仪的特点就是离线运行。尽管是离线运行,但测试数据还是需要的,所以采取方式保存数据就是必须的。在本次项目中我们计划采用SD卡来保存数据。

1、硬件设计

该读卡器整合 SD 卡规范和 FAT 文件格式规范,只要通过本模块规定的通讯协议就可以把数据存储在 SD 卡中的文件中。该读卡器连接方便采用串口通讯方式,如下图:

该读卡器摸块通讯协议比较简单,本模块的通讯协议分为命令发送和命令的应答两部分,其中命令格式由4个部分组成:命令识别码(0x55 0xAA),命令号,字节数(参数的个数,占2个字节,先发送低位字节,再发送高位字节),参数(根据命令的不同而不同),校验和(除命令识别码和校验和本身,所有发送数据之和的低 8 位数据)。命令格式如图:

应答分为两部分:命令的执行情况(编码将附录 1),数据。数据根据命令的不同而不同。

根据上述描述,我们设计SD卡的接口电路如下:

2、软件设计

接下来我们根据协议编写读写SD卡的软件,主要实现状态检测、创建文件、打开文件、写文件、关闭文件、保存文件以及获取文件信息等。

1)获取系统的状态命令

获取系统的状态命令是用来获取模块当前的状态。命令编码是:0x01,命令格式如下:

//检测系统SD卡的状态

uint8_t GetSDCardStatus(void)

{

uint8_t CommandText[6]={0x55,0xAA,0x01,0x00,0x00,0x01};

uint8_t StatusByte=0xaa;

StatusByte = SendCommand(CommandText,6);

Delayms(50);

return StatusByte;

}

2)创建文件命令

创建文件命令提供给主机创建文件的功能。参数为 N 字节 8.3 文件格式的文件名(字符串格式,即文件名以 0 结尾),即 8 字节的基本文件名(模块不支持汉字编码,字母不区分大小写),3 字节扩展名。命令编码是:0x02,命令格式如下:

//创建文件,返回操作状态

uint8_t CreateFile(uint8_t fileName[8])

{

uint8_t CommandText[19]={0x55,0xAA,0x02,0x0D,0x00,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x2E,0x74,0x78,0x74,0x00,0x41};

uint8_t StatusByte;

StatusByte=0xaa;

uint16_t i;

for(i=0;i<8;i++)

{

CommandText[i+5]=fileName[i];

}

uint8_t checksum=0x00;

for(i=2;i<18;i++)

{

checksum+=CommandText[i];

}

CommandText[18]=checksum;

StatusByte = SendCommand(CommandText,19);

return StatusByte;

}

(3)打开文件命令

该命令为主机提供打开文件的功能。参数为 N 字节 8.3 文件格式的文件名(字符串格式,即文件名以0 结尾),即 8 字节的基本文件名(模块不支持汉字编码,字母不区分大小写),3 字节扩展名。命令编码是:0x06命令格式如下,其中个数占 2 字节,低字节先发送:

//打开文件

uint8_t OpenFile(uint8_t fileName[8])

{

uint8_t CommandText[19]={0x55,0xAA,0x06,0x0D,0x00,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x2E,0x74,0x78,0x74,0x00,0x45};//打开文件命令 0x06

uint8_t StatusByte=0xaa;

uint16_t i;

for(i=0;i<8;i++)

{

CommandText[i+5]=fileName[i];

}

uint8_t checksum=0x00;

for(i=2;i<18;i++)

{

checksum+=CommandText[i];

}

CommandText[18]=checksum;

StatusByte = SendCommand(CommandText,19);

return StatusByte;

}

4)获取文件信息命令

本命令为主机提供了读取当前打开文件的文件指针值和文件大小的功能。命令编码是:0x09,其命令格式如下:

//获取文件信息命令

void GetFileStatus(uint8_t rxData[])

{

uint8_t CommandText[6]={0x55,0xAA,0x09,0x00,0x00,0x09};//获取文件信息命令0x09

uint16_t i;

for(i=0;i<6;i++)

{

//等待传送结束

while(USART_GetFlagStatus(UART4, USART_FLAG_TXE) == RESET)

{

}

// 写一个字节到对应的串口传送数据寄存器

USART_SendData(UART4, CommandText[i]);

}

Delayms(20);

for(i=0;i<9;i++)

{

// 等待字节被对应的串口完全接收

//while(USART_GetFlagStatus(UART4, USART_FLAG_RXNE) == RESET)

//{

//}

// 获取接收到的字节

rxData[i] = USART_ReceiveData(UART4);

}

}

5)写文件命令

该命令为主机提供向已打开文件中写入数据的功能。每写一个数据文件指针自动加1,当数据写完,文件指针指向最后一个数据地址加1的位置。命令编码是:0x05,命令格式如下,其中个数占2字节,低字节先发送,起始地址占4字节,低字节先发送:

//写文件,返回写操作的状态

uint8_t WriteToFile(uint8_t * address,uint8_t data[],uint16_t datalength)

{

uint16_t count=datalength+10+19;

uint8_t CommandText[70];

uint8_t StatusByte=0xaa;

uint16_t i;

CommandText[0]=0x55;

CommandText[1]=0xAA;

CommandText[2]=0x05;

CommandText[3]=datalength+4+19;

CommandText[4]=0x00;

CommandText[5]=0xFF;

CommandText[6]=0xFF;

CommandText[7]=0xFF;

CommandText[8]=0xFF;

for(i=0;i<datalength;i++)

{

CommandText[i+9]=data[i];

}

CommandText[datalength+9]=(saveDate[0]/10)+0x30;

CommandText[datalength+10]=(saveDate[0]%10)+0x30;

CommandText[datalength+11]=0x2D;

CommandText[datalength+12]=(saveDate[1]/10)+0x30;

CommandText[datalength+13]=(saveDate[1]%10)+0x30;

CommandText[datalength+14]=0x2D;

CommandText[datalength+15]=(saveDate[2]/10)+0x30;

CommandText[datalength+16]=(saveDate[2]%10)+0x30;

CommandText[datalength+17]=0x20;

CommandText[datalength+18]=(saveDate[3]/10)+0x30;

CommandText[datalength+19]=(saveDate[3]%10)+0x30;

CommandText[datalength+20]=0x3A;

CommandText[datalength+21]=(saveDate[4]/10)+0x30;

CommandText[datalength+22]=(saveDate[4]%10)+0x30;

CommandText[datalength+23]=0x3A;

CommandText[datalength+24]=(saveDate[5]/10)+0x30;

CommandText[datalength+25]=(saveDate[5]%10)+0x30;

CommandText[datalength+26]=0x0D;

CommandText[datalength+27]=0x0A;

uint8_t checksum=0x00;

for(i=2;i<count-1;i++)

{

checksum+=CommandText[i];

}

CommandText[count-1]=checksum;

StatusByte = SendCommand(CommandText,count);

return StatusByte;

}

6)保存文件命令

该命令为主机提供保存当前打开文件的功能,为了防止频繁写 SD 卡,每次送入模块的数据先是保存在模块的 512 字节的扇区缓冲中,所以为了防止数据丢失,完成所有数据的传输后,要发送保存文件命令来保存文件。命令编码是:0x04,命令格式如下:

//保存文件,返回操作执行状态

uint8_t SaveFile(void)

{

uint8_t CommandText[6]={0x55,0xAA,0x04,0x00,0x00,0x04};//保存文件命令 0x04

uint8_t StatusByte=0xaa;

StatusByte = SendCommand(CommandText,6);

return StatusByte;

}

7)关闭文件命令

该命令为主机提供关闭当前打开的文件的功能。在创建文件、创建文件夹、打开文件之前要求关闭当前打开的文件,才可以执行这些命令,否则返回失败。命令编码是:0x08,命令格式如下:

//关闭文件,返回操作执行状态

uint8_t CloseFile(void)

{

uint8_t CommandText[19]={0x55,0xAA,0x08,0x00,0x00,0x08};//关闭文件命令 0x08

uint8_t StatusByte=0xaa;

StatusByte = SendCommand(CommandText,6);

return StatusByte;

}

3、测试结果

编写完程序,我们测试以我们想要的格式写一些数据下去文件被保存为文本文件,以时间为文件名,数据格式与预期一致。至此SD卡读写完成。

STM32L476应用开发之五:数据保存与SD卡操作的更多相关文章

  1. Android开发 将数据保存到SD卡

    前言: 使用Activity的openFileOutput()方法保存文件,文件是存放在手机空间上,一般手机的存储空间不是很大,存放些小文件还行,如果要存放像视频这样的大文件,是不可行的.对于像视频这 ...

  2. WP8.1 Study12:文件压缩与Known Folder(包含SD卡操作)

    一.文件压缩 当应用程序保存和加载数据,它可以使用压缩. 1.使用 Windows.Storage.Compression.Compressor 压缩,获得一个Compressor stream. v ...

  3. Android 常见SD卡操作

    目录 Android 常见SD卡操作 Android 常见SD卡操作 参考 https://blog.csdn.net/mad1989/article/details/37568667. [0.] E ...

  4. SD卡操作相关的工具SDCardUtils

    SD卡操作相关的工具 package com.flyou.utils; import java.io.File; import android.os.Environment; import andro ...

  5. Android中向SD卡读写数据,读SD卡和手机内存

    package com.example.sdoperation; import java.io.BufferedReader; import java.io.File; import java.io. ...

  6. Android数据存储之SD卡

    为了更好的存取应用程序的大文件数据,应用程序需要读. 写SD卡上的文件.SD卡大大扩充手机的存储能力. 操作SD首先要加权限: <!--在SDCard中创建与删除文件权限 --> < ...

  7. SD卡操作

    读写SD卡 Context类的openFileInput和openFileOutput方法都是针对应用程序的数据文件夹进行的文件操作,由于手机的ROM容量有限,因此这种操作有一定局限性. 手机的SD卡 ...

  8. ios开发——实用技术篇&数据保存于恢复

    数据保存于恢复 用户操作(输入数据)之后,应用程序退出并且终止之后,当用户再次打开应用的时候还是保持原来的状态 一:在storyBoard中设置恢复标志符 二:在AppDalegate中代理方法 -( ...

  9. STM32平台SD卡的FatFS文件系统开发

    STM32平台SD卡的FatFS文件系统开发 系统平台: STM32系列的STM32F103ZE SPI方式与SD卡通信 SD上移植FatFS系统 1 FatFS文件系统 1.1 FatFS简介 Fa ...

随机推荐

  1. GCC编译器原理(一)03------GCC 工具:gprof、ld、libbfd、libiberty 和libopcodes

    1.3.7 gprof:性能分析工具 参考文档:https://www.cnblogs.com/andashu/p/6378000.html gprof是GNU profile工具,可以运行于linu ...

  2. Maven的日常

    强烈建议把 Maven 的 settings.xml 文件同时放在:%USER_HOME%/.m2/settings.xml 和${maven.home}/conf/settings.xml 两个地方 ...

  3. [kuangbin带你飞]专题一 简单搜索(回顾)

    A - 棋盘问题 POJ - 1321 注意条件:不能每放一个棋子,就标记一行和一列,我们直接枚举每一行就可以了. AC代码: #include<iostream> #include< ...

  4. mysql 查询优化 ~ 优化基础补充

    一 简介:此文章是对于 sql通用基础的补充说明 二 虚拟列: mysql虚拟列是mysql5.7的新特性,对于函数计算形成的结果可作为虚拟列,并可以对虚拟列添加索引,这样就能加速sql的运行,不过有 ...

  5. (7)Java数据结构--集合map,set,list详解

    MAP,SET,LIST,等JAVA中集合解析(了解) - clam_clam的专栏 - CSDN博---有颜色, http://blog.csdn.net/clam_clam/article/det ...

  6. MySql cmd下的学习笔记 —— 有关select的操作(max, min等常见函数)

    先把之前建的goods表找到 找到最贵的本店价(max) 找到最便宜的本店价(min) 查出一共还有多少商品(count) 查看商品价的平均价(avg) 查看本店有多少种商品 当count(*)时 输 ...

  7. 20165337岳源 预备作业3:Linux安装及命令入门

    安装虚拟机 按照基于VirtualBox虚拟机安装Ubuntu图文教程的步骤安装虚拟机,遇到的问题通过同学的帮助也得到了解决.例如:虚拟机无法选择64位系统. 常用的Linux命令 Tab 补全命令. ...

  8. C++ 引用变量

    int rats; int & rodents = rats; rats 和 rodents 可以互换,他们指向相同的值和内存单元.其实就是给rats取了别名rodents. 修改其中任意一个 ...

  9. python-----短信、电话告警

    Twilio 1.访问http://twilio.com/并注册.注册了新账户后,你需要验证一个手机号码,短信将发给该号码. 2.Twilio 提供的试用账户包括一个电话号码,它将作为短信的发送者.你 ...

  10. 【转】Python之mmap内存映射模块(大文本处理)说明

    [转]Python之mmap内存映射模块(大文本处理)说明 背景: 通常在UNIX下面处理文本文件的方法是sed.awk等shell命令,对于处理大文件受CPU,IO等因素影响,对服务器也有一定的压力 ...