想做一个接口函数,完成功能也很简单,把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;
}
这下子编译器编译出来一大堆代码,但是结果还不是正确的。这个问题困扰了我两天,一直没有好的解决方法,实在不行我都准备嵌入汇编了。版主能不能帮忙给指点一下,找出能解决问题的办法。谢过了!
欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) | Powered by Discuz! 7.0.0 |