标题: 怎么简洁的把0X138C转换成ASCII码 [打印本页]

作者: PEB188    时间: 2022-2-10 20:22
标题: 怎么简洁的把0X138C转换成ASCII码
把0X138C转换成ASCII '5004'怎么写最简单。因为获取的是电压,我现在是先转换成10进制,再用十进制每位+0x30得到ASCII码。请教简单的高效的写法

作者: rundstedt    时间: 2022-2-10 23:42
  1. int n=0x138c;
  2. char *ptr=&ch[3];
  3. for(int i=0;i<4;i++){
  4.   *ptr--="0123456789"[n%/10];
  5.   n/=10;
  6. }
复制代码

作者: xws245925587    时间: 2022-2-11 09:33
sprintf
作者: lishengaha    时间: 2022-2-11 09:56
用sprintf直接打印到字符串比较简单
作者: xuyaqi    时间: 2022-2-11 10:28
发表于 2022-2-10 23:42

数组 DisBuf 里就是你要的“5004”.

作者: 名字不是重点    时间: 2022-2-11 11:24
        int n=0x138c;
        unsigned char k10 [5];       
        k10[0]=n / 10000 + 0x30;
        k10[1]=n / 1000 % 10+0x30;
        k10[2]=n / 100 % 10+0x30;
        k10[3]=n / 10 % 10+0x30;
        k10[4]=n % 10 + 0x30;
作者: PEB188    时间: 2022-2-11 12:03
xws245925587 发表于 2022-2-11 09:33
sprintf

额,51单片机中没有printf这个函数啊
作者: PEB188    时间: 2022-2-11 12:04
lishengaha 发表于 2022-2-11 09:56
用sprintf直接打印到字符串比较简单

51单片机中没有printf这个函数啊
作者: devcang    时间: 2022-2-11 13:45
PEB188 发表于 2022-2-11 12:04
51单片机中没有printf这个函数啊

看人家的例子,就是C51中的。

一直在用6楼说的做法,直截了当。
作者: 名字不是重点    时间: 2022-2-11 14:09
用sprintf打印字符串的方法可以是可以,但的消耗的代码空间是很吓人的。能不用,则尽量不用。。
作者: PEB188    时间: 2022-2-11 14:40
名字不是重点 发表于 2022-2-11 11:24
int n=0x138c;
        unsigned char k10 [5];       
        k10[0]=n / 10000 + 0x30;

我目前就是用这种方法啊
作者: PEB188    时间: 2022-2-11 14:49
xuyaqi 发表于 2022-2-11 10:28
数组 DisBuf 里就是你要的“5004”.

要的就是这种函数转换
作者: PEB188    时间: 2022-2-11 15:18
名字不是重点 发表于 2022-2-11 14:09
用sprintf打印字符串的方法可以是可以,但的消耗的代码空间是很吓人的。能不用,则尽量不用。。

一开始不知道。。。确实,就用这一句,占用了差不多1K代码空间。
作者: Y_G_G    时间: 2022-2-11 15:38
char   k[10];        //指定数组长度
char a;
sprintf(k,"%.d",Data_Send);//把数据分割成字符串,并存放在k数组中

Data_Send可以是整型,也可以是浮点型
#include "stdio.h" 这个就包含了sprintf函数
作者: 名字不是重点    时间: 2022-2-11 17:01
PEB188 发表于 2022-2-11 14:49
要的就是这种函数转换

这种方式看上去简单,消耗空间可不简单!多出几百个字节不在话下!你还要效率不?
作者: 名字不是重点    时间: 2022-2-11 17:06
void main()
{
  int n=0x138c;
  unsigned char k10[5];

        k10[0]=n/10000 + 0x30;
        k10[1]=n/1000 % 10+0x30;
        k10[2]=n/100 % 10+0x30;
        k10[3]=n/10 % 10+0x30;
        k10[4]=n%10 + 0x30;
       
while(1);       
}
//////////////////////////////////////////////////       
编译后的信息:
Build target 'Target 1'
compiling hex2dec.c...
linking...
Program Size: data=14.0 xdata=0 code=257
"hex2dec" - 0 Error(s), 0 Warning(s).

///////////////////////////////////////////////////


#include <reg52.h>
#include <stdio.h>


void main()
{
int k=0x138c;
unsigned char disbuf[5];
       
        sprintf(disbuf,"%05d",k);
       
while(1);       
}       

       
//////////////////////////////////////////////////       
编译后的信息:
Build target 'Target 1'
compiling hex2dec.c...
linking...
Program Size: data=40.1 xdata=0 code=1087
"hex2dec" - 0 Error(s), 0 Warning(s).
//////////////////////////////////////////////////       
作者: BRPCB    时间: 2022-2-12 14:34
用sprintf可以
作者: rundstedt    时间: 2022-2-12 17:09
名字不是重点 发表于 2022-2-11 17:06
void main()
{
  int n=0x138c;

能不能帮我测试下沙发的代码占用多少资源,我没有C51,用gcc测试可以用,有个小笔误,[n%/10]应该是[n%10],其他代码无问题。
作者: 田贺    时间: 2022-2-12 18:18
要代码简洁用sprintf,代价是多几百个字节;
沙发的有一些小错误,看似是兼顾程序量与大小的最优解法了,附上程序编译结果。

作者: 名字不是重点    时间: 2022-2-12 18:18
发表于 2022-2-12 17:09
能不能帮我测试下沙发的代码占用多少资源,我没有C51,用gcc测试可以用,有个小笔误,[n%/10]应该是[n%10 ...

19楼已给出结果了。。
另外:用Sprintf的方法,运行结果明显比老方法耗费更多的时间。
作者: dzbj    时间: 2022-2-12 19:05
前一阵我也问过类似的问题 就是大数拆位 有两位大佬给的方法都很牛 我是受益匪浅 介绍给吧

uint a=5004;//HEX还是DEC都一样 反正值是一样的
uchar a0[4]={0};//建立一个数组存放拆解出来的位值 顺序是 个 十 百 千

for(x=0;x<4;x++)
{
a0[x]=(a%10)+0x30;//每次只获得最末位的位值 即 个位值 然后转换成ASCII
a=a/10;//每次把总数/10 等于把总数右移一位 注意 不是>>那种移位
}

这个方法减少多次除法运算 效率比从大头拆高很多 很棒 供你参考 但因为我自己没用 根据自己理解写的程序可能有问题 你试试 理解意思即可 如果有疑问 可找一下原帖

我没用这个方法 因为这样还是需要运算 我本来用的是查表法 另一位大佬教我用更简洁的代码实现查表 但查表法要占用更大程序空间 因为要存放表格 尤其在数字很大的时候 所以没推荐给你 对我来说运算比空间重要 宁可牺牲空间也要减少每次运算量
作者: 名字不是重点    时间: 2022-2-12 20:39
dzbj 发表于 2022-2-12 19:05
前一阵我也问过类似的问题 就是大数拆位 有两位大佬给的方法都很牛 我是受益匪浅 介绍给吧

uint a=5004; ...

赞!学习了!
你这个方法,运行得出结果的速度最快,美中不足有2点:
空间占用略大(16+420),且结果是逆向的。数据的后期处理要注意点。
作者: 名字不是重点    时间: 2022-2-12 20:46
dzbj 发表于 2022-2-12 19:05
前一阵我也问过类似的问题 就是大数拆位 有两位大佬给的方法都很牛 我是受益匪浅 介绍给吧

uint a=5004; ...

用  for(x=4;x>0;x--) 这个可以解决逆序问题
作者: 名字不是重点    时间: 2022-2-12 20:57
田贺 发表于 2022-2-12 18:18
要代码简洁用sprintf,代价是多几百个字节;
沙发的有一些小错误,看似是兼顾程序量与大小的最优解法了, ...

这个好,赞!
可以说是这主题中最佳答案了。
速度快、占用空间最小的。。
作者: 名字不是重点    时间: 2022-2-12 20:58
发表于 2022-2-10 23:42

学习了~~
作者: rundstedt    时间: 2022-2-12 21:43
田贺 发表于 2022-2-12 18:18
要代码简洁用sprintf,代价是多几百个字节;
沙发的有一些小错误,看似是兼顾程序量与大小的最优解法了, ...

我用MinGW测试*ptr--没问题啊!为啥要改成ptr[3-i]?难道C51用指针效率非常低嘛?
作者: 名字不是重点    时间: 2022-2-12 23:49
发表于 2022-2-12 21:43
我用MinGW测试*ptr--没问题啊!为啥要改成ptr[3-i]?难道C51用指针效率非常低嘛?

应该是让数组掉个头。

void main()
{
unsigned char  x;
unsigned int n=65535;
unsigned char ptr[5];

for(x=5;x>0;x--)
{
   ptr[x-1]="0123456789"[n%10]-0X30;
   n/=10;
}
while(1);
}
/*/////编译后:
Build target 'Target 1'
linking...
Program Size: data=16.0 xdata=0 code=170
"test" - 0 Error(s), 0 Warning(s).
*/////////






作者: Y_G_G    时间: 2022-2-13 01:43
名字不是重点 发表于 2022-2-11 14:09
用sprintf打印字符串的方法可以是可以,但的消耗的代码空间是很吓人的。能不用,则尽量不用。。

用C语言写程序就是图它省事的
sprintf会占用1K左右的代码空间,如果单片机的内存足够的话,sprintf实在是个好东西
对于有十几K或者几十K内存的单片机,sprintf占用的那点内存并不算多
主要还是自动转换负号和小数点这两个功能比较好用
作者: 名字不是重点    时间: 2022-2-13 10:50
Y_G_G 发表于 2022-2-13 01:43
用C语言写程序就是图它省事的
sprintf会占用1K左右的代码空间,如果单片机的内存足够的话,sprintf实在是 ...

是的,写代码还要兼顾到应用场景。ARM内核的单片用sprintf就是很方便。但用在小体量的51内核上,就要认真考量一下了。
作者: PEB188    时间: 2022-2-16 13:11
田贺 发表于 2022-2-12 18:18
要代码简洁用sprintf,代价是多几百个字节;
沙发的有一些小错误,看似是兼顾程序量与大小的最优解法了, ...

这个for里面两句是什么意思啊
作者: 123456ZXC1    时间: 2022-2-16 15:10
sprintf方便
作者: 名字不是重点    时间: 2022-2-16 20:30
PEB188 发表于 2022-2-16 13:11
这个for里面两句是什么意思啊

for(x=5;x>0;x--)
{
   ptr[x-1]="0123456789"[n%10]-0X30;
//x-1,配合(x=5;x>0;x--),把转换后的数值按“万千百十个”位的顺序存到数组ptr的0-4的单元中。
  //"0123456789":相当于一个数组码表
  //n%10 就是取n的个位数,这个数对应的码值从"0123456789"中取出,
  //-0X30,这个要看转换后的数值去处,比如,用来自定义显示段码,可以加上,
  //毕竟没有人能定义一个长达数10个的成 员的段码表,数码管的段码表一般就20(0x14)个以内
  //但如果是用来字库LCD显示,则可以不用,字库中的数据可是从00-94的。
   n/=10;//把n缩小10倍,并去除小数部分。
}

//明白了吗?不明白我再来




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1