将KEIL中memory window 数据保存到文本,然后改造成十进制数组,方便导入excel进行分析

由于一些原因,需要在keil中采集大量(成千上万)数据然后分析,于是创建了一个uint16_t value[2000]数组。然后我通过

打开keil的command窗口,在其中输入如下命令:

:SAVE D:\value1.txt 0X00080ABC,0X00080ABC+4000

SAVE:为命令
D:\value1.txt: 保存路径
0X00080ABC:需要导出数组开始地址
0X00080ABC+4000:需要导出数组结束地址

这样就可以导出数组数据到本地了,需要注意导出数据的格式是hex386(忘了的话,自己百度一下).

hex386的格式就有点麻烦了,我要的是十进制的数组。一开始我自己通过Notepad++手动编辑修改了一下,可是最后留下来的是十六进制的数组,而且还挺麻烦的,要1min/数组文件。而且导入EXCEL之后还要转换成十进制(这样很直观)。这就不能忍了,几次之后,我就到网上百度一下我这样的情况,发现还是有不少同道也碰到这样的情况,可是,重要的是可是,没有解决我问问题的办法(反正我没找到,就有一些类似的,例如:HextoBin)。

于是我就只好自己写了。采用VS2013,代码如下,复制粘贴就好了,只需要改一下这首行的路径地址就好了。如果不行再好好看看,没有写太多的注释(笑)。

这是主函数:

#define path ("./未充电/0ml2.txt")


int main(void)
{
	FILE *fp;
	fp = fopen(path, "r"); 
	if (fp == NULL)
	{
		printf("open file 失败!\n");
		exit(1);
	}
	else
	{
		printf("open file 成功!\n");
	}
	/*r 打开只读文件,该文件必须存在。
	r + 打开可读写的文件,该文件必须存在。
	w 打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则建立该文件。
	w + 打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。
	a 以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。
	a + 以附加方式打开可读写的文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾后,即文件原先的内容会被保留。
	*/
	printf("失败\n");
	fseek(fp, 0, SEEK_END);
	printf("成功\n");
	int file_size;
	file_size = ftell(fp);

	char tmp[12 * 1024] = { 0 };

	fseek(fp, 0, SEEK_SET);
	fread(tmp, file_size, sizeof(char), fp);
	tmp[file_size] = '\0';
	printf("file_size = %d\n", file_size);
	transformArr(tmp, file_size);//						第一步:将垃圾数据通通变成'g',并重新排序
	//printf("%s", tmp);
//**************************************************************************************************
	int len = deleteElement(tmp, file_size, 'g');//		第二步:删除垃圾数据
	if (-1 == len){
		printf("删除'g'失败\n");
	}
	else{
		printf("删除'g'成功\n");
	}
//**************************************************************************************************
	//printf("%s", tmp);
	len = deleteElement(tmp, len, '\n');//		第三步:删除换行符
	if (-1 == len){
		printf("删除'\\n'失败\n");
	}
	else{
		printf("删除'\\n'成功\n");
	}
//**************************************************************************************************
	//printf("%s", tmp);

	HexToDec(tmp,len);//								第四步:十六进制数转十进制数
	//printf("%s", tmp);
//**************************************************************************************************
	len = addElement(tmp, len, '\n', 4);//				第五步:添加空格
	printf("%s", tmp);printf("\n添加' '函数已执行\n");
//**************************************************************************************************	
	fp = fopen(path, "w+");//					第六步:写入文件
	if (fp == NULL)
	{
		printf("open file failure!\n");
	}
	else
	{
		printf("open and write file successful!\n");
		fputs(tmp, fp);
	}
	fclose(fp);

	return 0;
}

还有一些主函数应用到的函数:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <math.h>
using namespace std;



int HexCharToNum(char c)
{
	if (c >= '0' && c <= '9')
	{
		return (c - '0');
	}
	else if (c >= 'a' && c <= 'f')
	{
		return (c - 87);
	}
	else if (c >= 'A' && c <= 'F')
	{
		return (c - 55);
	}
	else
	{
		//printf("It isn't Hex!\n");
	}
}
/*
功能:判断是否为十六进制里的字符
参数:需要判断的字符
返回值:成功返回1 失败返回0
*/
int isHexNum(char c)
{
	if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))
		return 1;
	return 0;
}

void getformat(char *tmp)
{
	int len = strlen(tmp);
}

/*
功能:删除数组中的指定元素
参数:arr 数组名, len 数组的实际长度, del 要删除的数据
返回值:成功返回数组的有效长度 失败返回-1
*/
int deleteElement(char arr[], int len, char del)
{
	//外层循环寻找要删除的元素
	int i = 0;
	int j = 0;
	int tmp = len;
	for (i = 0; i < len; i++){
		if (arr[i] == del){      //找到要删除的元素
			//将该元素后边的所有元素前移
			for (j = i; j + 1 < len; j++){
				arr[j] = arr[j + 1];
			}
			//数组有有效长度-1
			len--;
			//防止重复元素的删除时,位置的后移
			--i;
		}
	}
	if (!(tmp - len)){
		return -1;
	}
	return len;
}
/*
功能:指定间隔n个数组元素添加指定元素
参数:arr 数组名, len 数组的实际长度, add 要添加的数据
返回值:成功返回数组的有效长度 失败返回-1
*/
int addElement(char arr[], int len, char add, int n)
{
	//外层循环寻找要删除的元素
	int i = 0;
	int j = 0;
	int c = 0;
	int tmp = len;
	for (i = 0; i < len; i++){
		if (c == n)
		{
			c = 0;
			//printf("i = %d\n",i);
			for (j = len; j >= i; j--)//先将之后的所有元素后移
			{
				arr[j + 1] = arr[j];
			}
			arr[i] = add;			//然后填充要添加的元素
			//printf("%c", arr[i]);
			len++;
			i++;
		}
		//printf("%c", arr[i]);
		c++;
	}
	if ((tmp - len) == 0){
		return -1;
	}
	return len;
}
/*
功能:改造文本数据
参数:arr 数组名
返回值:成功返回数组的有效长度 失败返回-1
*/
void transformArr(char tmp[],int len)
{
	int cnt = 0;
	int j = 0;
	int x = 1;
	int n = 0;
	for (int i = 0; i < len; i++)
	{
		if (tmp[i] == '\n')
		{
			n++;
		}
	}
	printf("n = %d\n", n);
	for (int i = 1; i < n + 1; i++)
	{	
		if (i == 1){
			while (tmp[cnt] != '\n')
			{
				tmp[cnt] = 'g';
				cnt++;
			}
			printf("cnt = %d,i = %d\n", cnt, i);
		}
		else if (i == 2){
			while (tmp[cnt] != '\n')
			{
				if (j < 9)
				{
					tmp[cnt] = 'g';

				}
				else if (j < 44)
				{

					if (x == 4)
					{
						int temp = 0;
						x = -1;
						temp = tmp[cnt];
						tmp[cnt] = tmp[cnt - 2];
						tmp[cnt - 2] = temp;
						temp = 0; cnt = cnt - 1;
						temp = tmp[cnt];
						tmp[cnt] = tmp[cnt - 2];
						tmp[cnt - 2] = temp;
					}
					x++;
					//printf("x = %d\n", x);
				}
				else
				{
					tmp[cnt] = 'g';
				}
				cnt++; j++;
			}
			//printf("cnt = %d,i = %d\n", cnt, i);
		}
		else if (i == n - 1){

			while (tmp[cnt] != '\n')
			{

				tmp[cnt] = 'g';
				cnt++;
			}
			printf("cnt = %d,i = %d\n", cnt, i);
		}
		else if (i == n){

			while (tmp[cnt] != '\n')
			{
				tmp[cnt] = 'g';
				cnt++;
			}
			printf("cnt = %d,i = %d\n", cnt, i);
		}
		else{
			j = 0; x = 1;
			while (tmp[cnt] != '\n')
			{
				if (j < 9)
				{
					tmp[cnt] = 'g';

				}
				else if (j < 49)
				{

					if (x == 4)
					{
						int temp = 0;
						x = -1;
						temp = tmp[cnt];
						tmp[cnt] = tmp[cnt - 2];
						tmp[cnt - 2] = temp;
						temp = 0; cnt = cnt - 1;
						temp = tmp[cnt];
						tmp[cnt] = tmp[cnt - 2];
						tmp[cnt - 2] = temp;
					}
					x++;
					//printf("x = %d\n", x);
				}
				else
				{
					tmp[cnt] = 'g';
				}
				cnt++; j++;
			}
			//printf("cnt = %d,i = %d\n", cnt, i);
		}
		cnt++;
	}
	
	
}

void HexToDec(char arr[],int len)
{
	int sum = 0;
	int c = 0;
	for (int i = 0; i < len; i++)
	{
		sum = sum + HexCharToNum(arr[i]) * (int)pow(16, 3-c);
		if (c == 3)
		{
			//printf("%d ", sum);
			arr[i - 0] = (sum % 10) + '0';//个位
			arr[i - 1] = sum / 10 % 10 + '0';
			arr[i - 2] = sum / 100 % 10 + '0';
			arr[i - 3] = sum / 1000 % 10 + '0';
			sum = 0;
			c = -1;
		}
		c++;
	}
}

只需一个main文件,然后生成就OK了。最后只剩下一列十进制的数据,可以直接导入EXCEL了。

18.11.15

发现,地址最后一位竟然对输出的数据格式有影响,真是坑爹!

例:最后一位为数字地址:0x000807e2:

:020000040008F2
:0E07E2006A0270026B026E026E026F026D02FE
:101740000000000000000000000000000000000099
:101750000000000000000000000000000000000089
:101760000000000000000000000000000000000079
:101770000000000000000000000000000000000069
:0317800000000066
:00000001FF

       最后一位为数字地址:0x000807ea:

:020000040008F2
:06078A0000000000000069
:100790000000000000000000000000000000000059
:1007A0000000000000000000000000000000000049
:1008300000000000000000000000000000000000B8
:1008400000000000000000000000000000000000A8
:03085000000000A5
:00000001FF

文本数据格式不一样,那我的上面的代码自然也就不能直接用了。

猜你喜欢

转载自blog.csdn.net/qq_39608070/article/details/82991752