首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

[求助]版主帮忙看一下CDDEWARRIOR汇编出的奇怪问题

[求助]版主帮忙看一下CDDEWARRIOR汇编出的奇怪问题

  想做一个接口函数,完成功能也很简单,把8位的控制量(0~255)转换为2300 ~ 3300之间的控制量,先是想这样完成


  #define        MAXANGLE      3300
  #define        MINANGLE      2300 
   
  void SetDirection(unsigned char direction) {
                     
  PWMDTY01  = MINANGLE + (direction * (MAXANGLE - MINANGLE)) / 0XFF;
  }
  起初以为编译器在处理(direction * (MAXANGLE - MINANGLE))的时候会直接做成32位的乘法


direction * 1000,然后除于0XFF舍弃低8位就转换为16位数据相加后就变为16位数据。
  但是编译器汇编后的代码为
 CLRA
 TFR D,Y
 LDD #1000
 EMUL
 LDX #255
 IDIVS
 LEAX 2300,X
 STX 0XBC
 RTC
  显然编译器使用EMUL指令后乘积(direction * (MAXANGLE - MINANGLE))存在Y,D中,但接下来令人奇怪的是它居然使用符号除法IDIVS指令把D除了255,高位Y舍弃。这样一来,结果肯定不对。
  分析了一下原因,觉得可能是类型转换的问题,就加上了强制转换。
PWMDTY01  = MINANGLE + ((unsigned long)((unsigned int)direction * (unsigned int)(MAXANGLE - MINANGLE))) / (unsigned int)0XFF;


编译器汇编后的代码为
 CLRA
 TFR D,Y
 LDD #1000
 EMUL
 LDX #255
 IDIV
 LEAX 2300,X
 STX 0XBC
 RTC
  编译器仅仅把IDIVS换成了IDIV,前边的确是我搞错了,(MAXANGLE - MINANGLE)默认是有符号数。但很遗憾的是编译器还没有搞清楚我的意思,仍然忽略了乘法的高位。再次修改,加上一个变量。
 volatile unsigned long           emul;
  emul      = (unsigned long)((unsigned int)direction * (unsigned int)(MAXANGLE -


MINANGLE));
  PWMDTY01  = MINANGLE + (unsigned int)(emul / (unsigned int)0XFF);

unsigned long           emul;
  emul      = (unsigned long)((unsigned int)direction * (unsigned int)(MAXANGLE -


MINANGLE));
  emul      >>= 8;
  PWMDTY01  = (unsigned int)MINANGLE + (unsigned int)emul;
  }
  这下子编译器编译出来一大堆代码,但是结果还不是正确的。这个问题困扰了我两天,一直没有好的解决方法,实在不行我都准备嵌入汇编了。版主能不能帮忙给指点一下,找出能解决问题的办法。谢过了!


 


问题解决了!自己想了一个歪招,先缩小10倍,除法后再放大,总算能干活了!
PWMDTY01 = (unsigned int)MINANGLE + ((((unsigned int)(MAXANGLE - MINANGLE) / 10) * direction) / 255) * 10;
返回列表