打印

ANSI C中如何能将两个char拼合成一个short int?使用指针可以吗

[复制链接]
4783|18
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
程疗匠人|  楼主 | 2009-3-15 10:30 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
以下是我写的代码,能实现功能,但是出警告:指针指向不同的类型。
而且速度也慢,需要42个微秒@12MHz,用汇编10微秒就搞定了,用C能不能有什么高效的办法?
#include <reg52.h>

unsigned long val;
unsigned char *p;

main()
  {
    TR0=1;
    TMOD=0X11;
  while(1)
    {
    p=&val;
    p=p+3;
    *p=TL0;
    p--;
    *p=TH0;
    }
  }

相关帖子

沙发
JayGong| | 2009-3-15 10:35 | 只看该作者

我是用一个联合定义搞定的!

我是用一个联合定义搞定的!

使用特权

评论回复
板凳
ayb_ice| | 2009-3-15 10:36 | 只看该作者

可以

unsigned long val;
unsigned long *p;

main()
  {
    TR0=1;
    TMOD=0X11;
  while(1)
    {
      p = &val;
    p[0] = TH0*256+TL0
    }
  }

使用特权

评论回复
地板
McuPlayer| | 2009-3-15 10:43 | 只看该作者

不要动辄“C51中”

为何不问C语言中?

人为隔断单片机的C语言和标准C语言之间的联系,不利于学习进步。

使用特权

评论回复
5
程疗匠人|  楼主 | 2009-3-15 10:52 | 只看该作者

那么快就有回帖了,还是有疑问:p[0] = TH0*256+TL0

p[0] = TH0*256+TL0中,
p[0]是什么意思?
另外,TH0*256+TL0这样速度会不会很慢?因为有乘法运算。
割裂C51与标准C是我的不对,在此向楼上致歉~~

使用特权

评论回复
6
ayb_ice| | 2009-3-15 11:01 | 只看该作者

LS

你把KEIL想的太笨了.

使用特权

评论回复
7
computer00| | 2009-3-15 11:11 | 只看该作者

keil可能会生成直接将两个值分别写到对应地址的代码

而不是使用乘法运算。

当然,像下面这样的写法最直接了,但是可移植性就稍微差一点,要考虑大小端模式的问题。

     ((unsigned char *)&val)[3]=TL0;
     ((unsigned char *)&val)[2]=TH0;

编译后的代码如下,只生成了2条指令。

    10:   while(1) 
    11:     { 
    12:      ((unsigned char *)&val)[3]=TL0; 
C:0x0008    858A0B   MOV      0x0B,TL0(0x8A)
    13:      ((unsigned char *)&val)[2]=TH0; 
C:0x000B    858C0A   MOV      0x0A,TH0(0x8C)
    14:     } 

使用特权

评论回复
8
程疗匠人|  楼主 | 2009-3-15 11:11 | 只看该作者

经测试,ayb_ice 的程序需要38个机器周期就可以拼合成一个int

比我原来的少了两个机器周期~~,但是我还是觉得慢~~高手有没有更快的方法?

使用特权

评论回复
9
ayb_ice| | 2009-3-15 11:22 | 只看该作者

那就再来一个

unsigned long data val;
unsigned int data *p;

main()
{
  TR0=1;
  TMOD=0X11;
  while(1)
  {
      p = (unsigned int data *)(&val+2);
    p[0] = TH0*256+TL0
  }
}
 

使用特权

评论回复
10
xwj| | 2009-3-15 11:23 | 只看该作者

不要用指针,指针是间址操作,当然慢

应该直接写:
unsigned int val;
unsigned char *p;

main()
  {
    TR0=1;
    TMOD=0X11;
  while(1)
    {
        val=TH0*256+TL0;        
        //或者val=TH0<<8+TL0;
    }
  }

//keil很聪明的,会自动处理优化,两种写法编译结果会是一模一样的!
//为了通用,避免大小端的影响,建议今年用第一种(第二种换个编译器可能就是个BUG)

使用特权

评论回复
11
HotPower| | 2009-3-15 11:23 | 只看该作者

要注意51特殊寄存器的用法~~~

使用特权

评论回复
12
computer00| | 2009-3-15 11:24 | 只看该作者

由于楼住的是long int,还要将高两字节置0,因此要4条语句

     ((unsigned char *)&val)[3]=TL0;
     ((unsigned char *)&val)[2]=TH0;
     ((unsigned char *)&val)[1]=0;
     ((unsigned char *)&val)[0]=0;


    10:   while(1) 
    11:     { 
    12:      ((unsigned char *)&val)[3]=TL0; 
C:0x0008    858A0B   MOV      0x0B,TL0(0x8A)
    13:      ((unsigned char *)&val)[2]=TH0; 
C:0x000B    858C0A   MOV      0x0A,TH0(0x8C)
    14:      ((unsigned char *)&val)[1]=0; 
C:0x000E    E4       CLR      A
C:0x000F    F509     MOV      0x09,A
    15:      ((unsigned char *)&val)[0]=0; 
C:0x0011    F508     MOV      val(0x08),A
    16:     } 

使用特权

评论回复
13
ATMEGA32L| | 2009-3-15 11:48 | 只看该作者

简单,高效,可移植。

简单,高效,可移植。

val=hight_byte<<8+low_byte;
或者
val=hight_byte*256+low_byte;

使用特权

评论回复
14
xwj| | 2009-3-15 11:50 | 只看该作者

呵呵,LS和我10楼的意思是一样的

使用特权

评论回复
15
computer00| | 2009-3-15 12:03 | 只看该作者

还是直接给指定的地址赋值最直接,就是可移植性不够好

下面这个是直接写乘法编译的结果

    10:   while(1) 
    11:     { 
    12:      val=TH0*256+TL0; 
C:0x0008    AF8C     MOV      R7,TH0(0x8C)
C:0x000A    EF       MOV      A,R7
C:0x000B    FE       MOV      R6,A
C:0x000C    AD8A     MOV      R5,TL0(0x8A)
C:0x000E    7C00     MOV      R4,#0x00
C:0x0010    E4       CLR      A
C:0x0011    2D       ADD      A,R5
C:0x0012    FF       MOV      R7,A
C:0x0013    EC       MOV      A,R4
C:0x0014    3E       ADDC     A,R6
C:0x0015    FE       MOV      R6,A
C:0x0016    E4       CLR      A
C:0x0017    8F0B     MOV      0x0B,R7
C:0x0019    8E0A     MOV      0x0A,R6
C:0x001B    F509     MOV      0x09,A
C:0x001D    F508     MOV      val(0x08),A
    13:     } 


比起12楼的要长了一些。

使用特权

评论回复
16
程疗匠人|  楼主 | 2009-3-15 15:42 | 只看该作者

惊动高人无数~~

很感谢各位大虾的回帖,晚上慢慢学习再写心得体会了。
大虾的水平太高,有些语句不怎么看得懂。

使用特权

评论回复
17
Etual| | 2009-3-15 23:36 | 只看该作者

你的名字太无敌了

也难怪这么多高手进来的 ......

使用特权

评论回复
18
xwj| | 2009-3-16 01:01 | 只看该作者

回帖不是因为他的名字

如果是程序匠人问这样的问题,我都懒得答

使用特权

评论回复
19
akcw007| | 2009-3-16 15:03 | 只看该作者

用联合体

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

29

主题

224

帖子

0

粉丝