你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

快速互转 HEX (16进制) 方法——适合 MCU 用的 C语言

[复制链接]
gaosmile 发布时间:2020-3-19 13:51
缘由
这个起因是昨晚群里有人在讨论怎么把字符串转成
HEX方法最佳,讨论到最后变成哪种方法效率最优了。毕竟这代码是要在MCU上面跑的,要同时考虑到时间和空间的最优解。

当然讨论的是有结果的,具体实现的方法和代码在下面展示。
char数组转16进制HEX串
例子:

将如下的量

  1. char str[] = "12345";
  2. char data[] = {1,2,3,4,5,0xff};
复制代码

转成

  1. "313233343500"
  2. "0102030405FF"
复制代码

这样的结果
这个其实很简单,追求速度的话,查表就好了

0-16对应0-F即可:

  1. const char hex_table[] = {
  2. '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
  3. };
复制代码

然后一个个从表里取出来,拼到对应位置即可:

  1. void to_hex(char *s, int l, char *d)
  2. {
  3.     while(l--)
  4.     {
  5.         *(d+2*l+1) = hex_table[(*(s+l))&0x0f];
  6.         *(d+2*l) = hex_table[(*(s+l))>>4];
  7.     }
  8. }
复制代码

完整测试代码如下:

  1. #include <stdio.h>
  2. const char hex_table[] = {
  3. '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
  4. };
  5. void to_hex(char *s, int l, char *d)
  6. {
  7.     while(l--)
  8.     {
  9.         *(d+2*l+1) = hex_table[(*(s+l))&0x0f];
  10.         *(d+2*l) = hex_table[(*(s+l))>>4];
  11.     }
  12. }
  13. int main () {
  14.     char s[]= "1234";
  15.     char d[9];
  16.     d[8] = '\0';
  17.     to_hex(s,4,d);
  18.     printf("%s",d);
  19.     return 0;
  20. }
复制代码

输出结果:3132333416进制HEX串转成数值数组
例子:

将类似
"AAbb2fFF"的量转成{0xAA,0xBB,0x2F,0xff}这样的结果

这里如果还用查表的话,这个rom占用会浪费掉不少空间,所有查表法直接就被否决掉了(如果是PC上,追求极致速度的话,当然可以用)。

同时,为了通用性,代码需要兼容大小写两种输入数据

在仔细研究数据的结构时,我发现了个规律:

ASCII中的
0-9对应了0x30-0x39
ASCII中的A-F对应了0x41-0x46
ASCII中的a-f对应了0x61-0x66

也就是说,只要这一个字符大于
0x39,那它一定是字母;同时,在上面的分析也可以发现,如果这个字符是字母,不论大写小写,只需要看低四位就可以直接判断这个字符代表的数是多少

具体逻辑如下:

判断这个字符是否大于0x39

如果不是,直接取这个字符的低四位当作结果

如果是,则为字母,将他的低四位加上
9即为所需结果

具体实现代码也如下:

  1. void from_hex(char *s, int l, char *d)
  2. {
  3.     while(l--)
  4.     {
  5.         char* p = s+l;
  6.         char* p2 = p-1;
  7.         *(d+l/2) =
  8.         ( (*p>'9'? *p+9 : *p) & 0x0f ) |
  9.         ( (*p2>'9'? *p2+9 : *p2) << 4 );
  10.         l--;
  11.     }
  12. }
复制代码



完整的测试代码
  1. <font color="#003000">
  2. #include <stdio.h>
  3. void from_hex(char *s, int l, char *d)
  4. {
  5.     while(l--)
  6.     {
  7.         char* p = s+l;
  8.         char* p2 = p-1;
  9.         *(d+l/2) =
  10.         ( (*p>'9'? *p+9 : *p) & 0x0f ) |
  11.         ( (*p2>'9'? *p2+9 : *p2) << 4 );
  12.         l--;
  13.     }
  14. }
  15. int main () {
  16.     char s[]= "6F6B6f6b";
  17.     char d[5];
  18.     d[4] = '\0';
  19.     from_hex(s,8,d);
  20.     printf("%s",d);
  21.     return 0;
  22. }</font><font color="#003000">
  23. </font>
复制代码
输出结果:okok

如果你有更好的方法,欢迎在留言讨论!
收藏 评论0 发布时间:2020-3-19 13:51

举报

0个回答

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版