OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3307|回复: 11

怎么求三串ASCII码的平均值

[复制链接]

8

主题

83

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
238
金钱
238
注册时间
2016-4-4
在线时间
31 小时
发表于 2016-8-19 13:38:51 | 显示全部楼层 |阅读模式
5金钱
现在有三个型号相同的传感器,同时发来三串ASCII码,每串ASCII码都包含介电常数、电导率和温度三个参数,现在要求这三串ASCII码的里面三个参数的平均值。哪位大神有更好的方法,因为特殊原因不想转化成十进制再计算。

31 2B 31 35 2E 39 35 2B 30 2E 30 30 2B 32 37 2E 33 0D 0A
31 2B 35 36 2E 34 30 2B 30 2E 33 34 2B 32 37 2E 38 0D 0A
31 2B 38  2E 33 31 2B 30 2E 30 30 2B 32 38 2E 36 0D 0A


2B 表示的是 ‘+’,起到分割三个参数的作用
2E 表示的是 ‘.’    表示小数
0D 0A 是回车换行


现在要求划线部分的平均值。哪位大神有好的方法。谢谢!

最佳答案

查看完整内容[请看2#楼]

不知道你有没有接触过GPS,GPS通过串口输出的数据以逗号分隔,每个字段的长度也是不定的,而且包含整数和小数,由于公司的代码不能公开,所以我只能说下大致算法你参考下: 先定义3个可以存放介电常数,电导率,温度值三个字符串字段信息的数组: struct DataStringStructure { char jiedian[16]; char diandao[16]; char wendu[16]; }; struct DataStringStructure DataStrInfo1; // 用于存放第1个传 ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

27

主题

711

帖子

0

精华

版主

Rank: 7Rank: 7Rank: 7

积分
12512
金钱
12512
注册时间
2015-11-5
在线时间
2144 小时
发表于 2016-8-19 13:38:52 | 显示全部楼层
本帖最后由 FreeRTOS 于 2016-8-21 01:06 编辑
wscs1993 发表于 2016-8-19 18:24
是我没把问题说明白吧,就是每一串ASCII码包含三个信息,介电常数,电导率,温度值。现在要通过三个传感 ...

不知道你有没有接触过GPS,GPS通过串口输出的数据以逗号分隔,每个字段的长度也是不定的,而且包含整数和小数,由于公司的代码不能公开,所以我只能说下大致算法你参考下:
先定义3个可以存放介电常数,电导率,温度值三个字符串字段信息的数组:
struct DataStringStructure
{
    char jiedian[16];
    char diandao[16];
    char wendu[16];
};

struct DataStringStructure DataStrInfo1;    // 用于存放第1个传感器的所有字符串字段
struct DataStringStructure DataStrInfo2;    // 用于存放第2个传感器的所有字符串字段
struct DataStringStructure DataStrInfo3;    // 用于存放第3个传感器的所有字符串字段

当接收到字符串信息时,使用switch并以'+'作为分隔,将3个字段信息分别存储到结构里面,上面定义的3个结构体变量分别用于存放你的3路传感器发过来的字符串信息,如果连分隔算法都不会的话最好找个C语言算法扎实点的人帮你。

假设最后分离出来的信息(伪代码)是:
DataStrInfo1.jiedian[] = 134.9761      // 注意是字符串,不是数值
DataStrInfo1.diandao[] = 888.3107    // 注意是字符串,不是数值
DataStrInfo1.wendu[] = 35.625        // 注意是字符串,不是数值
同理DataStrInfo2和DataStrInfo3也是类似的字符串信息,当把3个结构字符串都存放起来后,下面进行最重要的一步:转换


转换前先定义转换后存储数据的结构(假设3个数据都是float类型):
struct DataValStructure
{
    float jiedianVal;
    float diandaoVal;
    float wenduVal;
};

struct DataValStructure DataVal1;    // 用于存放第1个传感器的所有参数数值
struct DataValStructure DataVal2;    // 用于存放第2个传感器的所有参数数值
struct DataValStructure DataVal3;    // 用于存放第3个传感器的所有参数数值

如何将字符串转成数值呢?最简单的方法当然是使用C库,当然也可以自己写一个字符串转浮点的函数,先介绍C库的2个比较好用的字符串转数值函数:atoi() 和 atof()

由于你的数值都是float类型的,因此使用 atof() 就可以了,如果有整型数据的话就是用 atoi()
DataVal1.jiedianVal = atof(DataStrInfo1.jiedian);         // 注意这里的转换结果134.9761是数值不是字符串!
DataVal1.diandaoVal = atof(DataStrInfo1.diandao);     // 注意这里的转换结果888.3107是数值不是字符串!
DataVal1.wenduVal = atof(DataStrInfo1.wendu);        // 注意这里的转换结果35.625是数值不是字符串!

好了,第一个数据已经转换出来了,照葫芦画瓢完成 DataVal2 和 DataVal3 的转换就大功告成了,最后的求平均值总知道怎么算吧?!


最后当一回活雷锋提供本人写的浮点字符串转数值函数:
[mw_shl_code=applescript,true]uint32_t Power(uint8_t m, uint8_t n)
{
    uint32_t result=1;
    while(n--)
    {
        result *= m;   
    }
    return result;
}

uint32_t Char2Oct(char* src, uint8_t len)
{
    uint32_t num;
    uint32_t i=1;
   
    num = (src[len-1] - '0');
    len--;
   
    while(len)
    {
        i *= 10;
        num += (src[len-1]-'0')*i;             // 个位
        len--;
    }
    return num;
}

float Char2Float(char* src)
{
    uint8_t i = 0;
    uint8_t j = 0;
    float result;
   
    /* 获取字符串的长度与小数点的偏移 */
    while(src != 0)
    {
        if(src == '.')
        {
            j = i;      // 记录小数点出现的位置
        }
        
        i++;
        if(i > 10)      // 防卡死处理
        {
            i--;
            break;
        }
    }
   
    /* 转换整数部分 */
    result = Char2Oct(&src[0], j);
   
    /* 转换小数部分并整合成一个完整的浮点数 */
    result += (float)Char2Oct(&src[j+1], i-j-1) / Power(10, i-j-1);
   
    /* 返回转换结果 */
    return result;
}[/mw_shl_code]





拿来长岛冰茶换我半晚安睡
回复

使用道具 举报

3

主题

2178

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3323
金钱
3323
注册时间
2013-7-19
在线时间
195 小时
发表于 2016-8-19 14:37:05 | 显示全部楼层
数值=ASCII-0x30,你可以把ASCII码直接相加除以3,就是真实数据的ASCII码
回复

使用道具 举报

8

主题

83

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
238
金钱
238
注册时间
2016-4-4
在线时间
31 小时
 楼主| 发表于 2016-8-19 14:38:49 | 显示全部楼层
ricefat 发表于 2016-8-19 14:37
数值=ASCII-0x30,你可以把ASCII码直接相加除以3,就是真实数据的ASCII码

但是每个参数的长度都是不固定的,如果固定的话就很好计算了。
回复

使用道具 举报

3

主题

2178

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3323
金钱
3323
注册时间
2013-7-19
在线时间
195 小时
发表于 2016-8-19 16:33:35 | 显示全部楼层
wscs1993 发表于 2016-8-19 14:38
但是每个参数的长度都是不固定的,如果固定的话就很好计算了。

2B 表示的是 ‘+’,起到分割三个参数的作用
2E 表示的是 ‘.’    表示小数
0D 0A 是回车换行

根据这些分割标识符单独分离出数据部分就好了
回复

使用道具 举报

8

主题

83

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
238
金钱
238
注册时间
2016-4-4
在线时间
31 小时
 楼主| 发表于 2016-8-19 17:05:52 | 显示全部楼层
ricefat 发表于 2016-8-19 16:33
2B 表示的是 ‘+’,起到分割三个参数的作用
2E 表示的是 ‘.’    表示小数
0D 0A 是回车换行

这样分割行是行,就是有点麻烦,而且处理起来不是很方便
回复

使用道具 举报

3

主题

2178

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3323
金钱
3323
注册时间
2013-7-19
在线时间
195 小时
发表于 2016-8-19 17:40:26 | 显示全部楼层
wscs1993 发表于 2016-8-19 17:05
这样分割行是行,就是有点麻烦,而且处理起来不是很方便

你是有多懒啊……
回复

使用道具 举报

8

主题

83

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
238
金钱
238
注册时间
2016-4-4
在线时间
31 小时
 楼主| 发表于 2016-8-19 17:53:27 | 显示全部楼层
ricefat 发表于 2016-8-19 17:40
你是有多懒啊……

。。。
回复

使用道具 举报

8

主题

83

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
238
金钱
238
注册时间
2016-4-4
在线时间
31 小时
 楼主| 发表于 2016-8-19 18:24:05 | 显示全部楼层
ricefat 发表于 2016-8-19 17:40
你是有多懒啊……

是我没把问题说明白吧,就是每一串ASCII码包含三个信息,介电常数,电导率,温度值。现在要通过三个传感器接收三串ASCII码,但由于传感器的深度不一样,数值也不一样,也就是他们的长度不是一样的,数据不对齐,所以这样操作起来不是很方便。
回复

使用道具 举报

3

主题

548

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1383
金钱
1383
注册时间
2015-2-3
在线时间
197 小时
发表于 2016-8-20 23:08:56 | 显示全部楼层
请百度C库函数sscanf(),轻松解决你的烦恼
回复

使用道具 举报

69

主题

978

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3772
金钱
3772
注册时间
2015-4-26
在线时间
765 小时
发表于 2016-8-21 10:17:32 | 显示全部楼层
此题无解,转一下十进制又不麻烦
我有故事,你有酒吗
回复

使用道具 举报

8

主题

83

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
238
金钱
238
注册时间
2016-4-4
在线时间
31 小时
 楼主| 发表于 2016-8-22 13:47:55 | 显示全部楼层
FreeRTOS 发表于 2016-8-21 00:55
不知道你有没有接触过GPS,GPS通过串口输出的数据以逗号分隔,每个字段的长度也是不定的,而且包含整数和 ...

谢谢!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-1 02:12

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表