一、简介
很多时候我们需要将单片机内部的数据导出进行分析与处理,但是实际上内存数据是以HEX格式存储在内存中的并且不同类型的数据的存储格式也是不一样的。为了方便统一使用浮点型数组存储数据然后一并导出,并采用matlab进行转换得到原始数据。
二、工具
1.Keil
2. Vim
3. matlab
三、预备知识
3.1 SAVE命令
命令格式:SAVE filename startAddr,endAddr
(例)SAVE data.hex 0x20000924,0x20000924+2000
3.2 stm32中各种数据类型的长度
Float-------4 double------8
uint32_t ---4 short-------4
(例)1000个float数组起始位置为0x20000924
SAVE data.hex 0x20000924,0x20000924+4000
3.3 stm32中存储数据的格式
Stm32中数据的保存格式是小端模式,所以读取出来的数据需要转换成常用的大端模式。如00001A41 转换成 411A0000
3.4 HEX格式
3.5 VIM 操作
Vim是一款编辑器,类似于记事本但是功能要强大很多,这里我们采用vim对hex格式的文本进行编辑变成matlab能够读取的格式。
注意:整列操作使用 Ctrl+Shift+v
3.6 float型数据格式
在二进制科学表示法中,S=M*2^N 主要由三部分构成:符号位+阶码(N)+尾数(M)。对于float型数据,其二进制有32位,其中符号位1位,阶码8位,尾数23位;对于double型数据,其二进制为64位,符号位1位,阶码11位,尾数52位。
float 符号位 阶码 尾数
1 8 23
四、操作步骤
4.1 定义float型数组
定义了以一个float型的数组,并赋予一半正数一半负数
4.2 使用SAVE命令导出
4.2.1进入debug模式下,找到command窗口
4.2.2 查看起始位置
4.2.3 在command窗口输入命令
回车即可
4.3 使用vim对文本编辑
4.3.1 在根目录下可以找到getData.hex 然后用vim打开
打开后,参考hex格式介绍
4.3.2 对文本进行编辑
删除第1,2行和最后一行,然后将有颜色的都删掉,每隔
8位留一个空格,每行32位,最后保存成.txt格式
4.4 使用matlab脚本进行处理
4.4.1 导入到matlab
将文件名改成相应的名称,然后仅运行第一、二行
查看data1的大小,我这次数据有996个
4.4.2 使用脚本进行处理
将循环次数改成相应的大小,再次运行全部代码
可以看到在result数组里面便是解码好的数据
五、代码简介
clc;
clear;
fileId = fopen('./getData.txt');
data1 = textscan(fileId,'%s');
result =[];
for i = 1:996
a = data1{1,1}{i,1};
b = a(1:2);
c = a(3:4);
d = a(5:6);
e = a(7:8);
f = [e,d,c,b];
bin_all = dec2bin(hex2dec(f));
%获取到数据
while(length(bin_all)~=32)
bin_all = ['0',bin_all];
end
bin_symbol = bin_all(1);%获取第一位为符号位
dec_symbol = str2num(bin_symbol);
if(dec_symbol==0)
dec_symbol = 1;
else
dec_symbol = -1;
end
bin_str = bin_all(2:9);%后面2到9位为阶位
bin_man = bin_all(10:32);%后面23位为尾数位
dec_str = bin2dec(bin_str) - 127;%阶位采用补码的形式,需要减去127
bin_man_dec = bin_man(dec_str+1:23);%整数部分
bin_man_int = ['1',bin_man(1:dec_str)];%小数部分
dec_int = bin2dec(bin_man_int);%先将整数部分转换为十进制
dec_dec =0;%将小数部分转换为十进制,matlab中没有函数直接调用
for j= 1:(23-dec_str)
if(bin_man_dec(j)=='1')
dec_dec = dec_dec + 2^(-j);%每一位代表2的-n次方,如011则是 0*0.5+1*0.25+1*0.125
end
end
result(i) = dec_symbol*(dec_dec +dec_int);%最终的解码结果
end