最据山寨特色的《中颖快速浮点乘、除法程库》!!!

[复制链接]
 楼主| Cortex-M0 发表于 2011-10-1 19:56 | 显示全部楼层 |阅读模式
一、简介
浮点数的运算,一贯比定点数慢很多,在C51中,浮点数乘除法,由于缺少相适应指令,运算速度超级慢,比浮点数加减法,慢不是一个等级,极大的影响了51单片机的实时运算速度,本文中,依靠中颖SH79/88/89系列的特色----准16位乘除指令,对所有关联到的无符号、有符号int型,无符号、有符号long型 和 float型变量的乘除运算,均作了运算速度大幅度提升,为方便使用,以外挂库形式加入,实行对C51内库自动替换,无缝嵌入。

其中最具有山寨特色的是float型的除法运算,便用中颖SH79/88/89系列的准16位乘除指令,经过简单的组合运算,代替原Keil C51的加减法模拟除法程序,大幅度地提升了原float型的除法的运算速度,解决了原51浮点除法特慢的通病。


二、中颖专用乘除库清单
/*
extern uint16   imul(uint16 value1,uint16 value2);          // 16位*16位-->16位(无符号二进制乘法)   
extern uint16  uidiv(uint32 value1,uint16 value2);       // 16位/16位-->16位(无符号二进制除法)   
extern uint32   lmul(uint32 value1,uint32 value2);          // 32位*32位-->32位(无符号二进制乘法)   
extern uint32  uldiv(uint32 value1,uint32 value2);       // 32位/32位-->32位(无符号二进制除法)   
extern float   fpmul(float value1, float value2);           // 二进制浮点数快速乘法  
extern float   fpdiv(float value1, float value2);           // 二进制浮点数快速除法  
*/


三、便用说明
只需要在编译程序过程中国,加入《中颖专用乘除库》----MATH_SH88F51.LIB,其他什么事都不用干!在编译过程中实现自动替换原C51库函数,无缝嵌入。


四、友情提示
本《中颖专用乘除库》,仅适用于中颖SH79/88/89系列单片机,其他51单片机并不适用,由于Keil C51不支持中颖51单片机的软件仿真,所以必须要用中颖51单片机的硬件仿真或依靠中颖51单片机的实时运行,运算结果才能正确。
 楼主| Cortex-M0 发表于 2011-10-1 19:57 | 显示全部楼层
《中颖专用乘除库》

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
goodboy3021 发表于 2011-10-1 20:08 | 显示全部楼层
有用,占位支持!下载使用!
 楼主| Cortex-M0 发表于 2011-10-1 20:16 | 显示全部楼层
本《中颖专用乘除库》,增加了若干非常实用的,无符号、有符号定点多字节乘法、除法子程序库,还有一个特色就是,增加了无符号、有符号定点多字节除法同时取商和余数子程序库,对同时需要用到这两个参数的场合,极大地提高了运行速度,使用时只需在C程序中,插入如下头本件 global.h 即可。

/***************************************************************************************
Model  : global.h
Description : Head file of defining global variable.
Author  : CLR
Create Time : 2011-09-29
Version ID  : 1.3
用  途      :中颖SH79/88/89F51系列MCU
作  者      :许意义
21ic  ID    :LAOXU
中颖论坛    : bbs.21ic.com   
****************************************************************************************/
#ifndef  _GLOBAL_H
#define  _GLOBAL_H

#pragma  MODDP2     // 打开中颖单片机双DPTR功能,加速数据传送
//#pragma  NOMODDP2    // 关闭中颖单片机双DPTR功能

/*--------------------------------------------------------------------------------------*/
/*      Resource - math.asm            */
/*--------------------------------------------------------------------------------------*/
extern  uint8 ascii_hex(uint8 value1);     //  1位 ASCII        --> 1位 HEX(低半字节)
extern  uint8 hex_ascii(uint8 value1);     //  1位 HEX(低半字节)--> 1位 ASCII
extern  uint8 bcd8_hex(uint8 value1);         //  8位 BCD --> 8位 HEX
extern uint16  bcd16_hex(uint16 value1);        // 16位 BCD -->16位 HEX
extern uint32  bcd32_hex(uint32 value1);        // 32位 BCD -->32位 HEX      
extern  uint16 hex8_bcd(uint8 value1);         //  8位 HEX -->16位 BCD
extern uint32  hex16_bcd(uint16 value1);        // 16位 HEX -->32位 BCD
extern uint32  hex32_bcd(uint32 value1);        // 32位 HEX -->32位 BCD      
extern  uint32  mul16_8(uint16 value1,uint8 value2);  // 16位* 8位-->32位(无符号二进制乘法)  
extern  uint32  mul16(uint16 value1,uint16 value2);   // 16位*16位-->32位(无符号二进制乘法)
extern  uint32  mul32_8(uint32 value1,uint8 value2);  // 32位* 8位-->32位(无符号二进制乘法)  
extern  uint32  mul32_16(uint32 value1,uint16 value2);  // 32位*16位-->32位(无符号二进制乘法)  
extern  uint32  mul32(uint32 value1,uint32 value2);      // 32位*32位-->32位(无符号二进制乘法)  
extern uint16  div16_8(uint16 value1,uint8 value2);   // 16位/ 8位-->16位(无符号二进制除法)
extern  uint16  div16(uint16 value1,uint16 value2);   // 16位/16位-->16位(无符号二进制除法)
extern  uint32  div32_8(uint32 value1,uint8 value2);  // 32位/ 8位-->32位(无符号二进制除法)
extern  uint32  div32_16(uint32 value1,uint16 value2);  // 32位/16位-->32位(无符号二进制除法)
extern  uint32  div32(uint32 value1,uint32 value2);      // 32位/32位-->32位(无符号二进制除法)
extern uint8  mod16_8(uint16 value1,uint8 value2);  // 16位% 8位--> 8位(无符号二进制取余数)
extern uint16  mod16(uint16 value1,uint16 value2);   // 16位%16位-->16位(无符号二进制取余数)  
extern uint8   mod32_8(uint32 value1,uint8 value2);   // 32位% 8位--> 8位(无符号二进制取余数)
extern uint16 mod32_16(uint32 value1,uint16 value2);   // 32位%16位-->16位(无符号二进制取余数)  
extern uint32 mod32(uint32 value1,uint32 value2);      // 32位%32位-->32位(无符号二进制取余数)   
extern uint16  div16_8m(uint16 value1,uint8 value2,uint8 data *p);    // 16位/ 8位-->16位(无符号二进制除法及取余数,8位余数存*p)
extern uint16  div16m(uint16 value1,uint16 value2,uint16 data *p);    // 16位/16位-->16位(无符号二进制除法及取余数,16位余数存*p)
extern uint32  div32_8m(uint32 value1,uint8 value2,uint8 data *p);    // 32位/ 8位--> 8位(无符号二进制除法及取余数,8位余数存*p)
extern uint32 div32_16m(uint32 value1,uint16 value2,uint16 data *p); // 32位/16位-->16位(无符号二进制除法及取余数,16位余数存*p)
extern uint32 div32m(uint32 value1,uint32 value2,uint32 data *p);    // 32位/32位-->32位(无符号二进制除法及取余数,32位余数存*p)   
extern  int32  smul16_8(int16 value1,int8 value2);      // 16位* 8位-->32位(有符号二进制补码乘法)  
extern  int32  smul16(int16 value1,int16 value2);      // 16位*16位-->32位(有符号二进制补码乘法)
extern  int32  smul32_8(int32 value1,int8 value2);      // 32位* 8位-->32位(有符号二进制补码乘法)  
extern  int32  smul32_16(int32 value1,int16 value2);     // 32位*16位-->32位(有符号二进制补码乘法)  
extern  int32  smul32(int32 value1,int32 value2);      // 32位*32位-->32位(有符号二进制补码乘法)  
extern int16  sdiv16_8(int16 value1,int8 value2);       // 16位/ 8位-->16位(有符号二进制补码除法)
extern  int16  sdiv16(int16 value1,int16 value2);      // 16位/16位-->16位(有符号二进制补码除法)
extern  int32  sdiv32_8(int32 value1, int8 value2);      // 32位* 8位-->32位(有符号二进制补码乘法)   
extern  int32  sdiv32_16(int32 value1,int16 value2);     // 32位/16位-->32位(有符号二进制补码除法)
extern  int32  sdiv32(int32 value1,int32 value2);      // 32位/32位-->32位(有符号二进制补码除法)
extern int8   smod16_8(int16 value1,int8 value2);      // 16位% 8位--> 8位(有符号二进制补码取余数)
extern int16  smod16(int16 value1,int16 value2);      // 16位%16位-->16位(有符号二进制补码取余数)  
extern int8   smod32_8(int32 value1,int8 value2);       // 32位% 8位--> 8位(有符号二进制补码取余数)
extern int16  smod32_16(int32 value1,int16 value2);     // 32位%16位-->16位(有符号二进制补码取余数)  
extern int32  smod32(int32 value1,int32 value2);      // 32位%32位-->32位(有符号二进制补码取余数)   
extern int16  sdiv16_8m(int16 value1,int8 value2,int8 data *p); // 16位/ 8位-->16位(有符号二进制除法及取余数,8位余数存*p)
extern int16  sdiv16m(int16 value1,int16 value2,int16 data *p); // 16位/16位-->16位(有符号二进制除法及取余数,16位余数存*p)
extern int32  sdiv32_8m(int32 value1,int8 value2,int8 data *p);  // 32位/ 8位--> 8位(有符号二进制除法及取余数,8位余数存*p)
extern int32  sdiv32_16m(int32 value1,int16 value2,int16 data *p); // 32位/16位-->16位(有符号二进制除法及取余数,16位余数存*p)
extern int32  sdiv32m(int32 value1,int32 value2,int32 data *p); // 32位/32位-->32位(有符号二进制除法及取余数,32位余数存*p)   

extern  void  ld_pdata(int8 addr1, int8 addr2, int8 len);   //  @PDATA --> @IDATA(len字节PDATA读入片内IDATA RAM)
extern  void  st_pdata(int8 addr1, int8 addr2, int8 len);   //  @IDATA --> @PDATA(len字节片内IDATA RAM存入PDATA)

/*  中颖单片机C51定点库内部调用函数   
extern  int32 st_r03_r47(void);             //  R0R1R2R3 ---> R4R5R6R7
extern  int16 neg(void);                     //  -(R6R7)  ---> R6R7
*/

/*  中颖单片机C51定点库、浮点库自动调用专用运算库函数,合适有效地插入了中颖SH79/88/89系列的特色----准16位乘除指令,对所有
    关联到的无符号、有符号int型,无符号、有符号long型 和 float型变量的乘除运算,均作了运算速度大幅度提升,为方便使用,以外
挂库形式加入,实行对C51内库自动替换,无缝嵌入,其中最具有特色的是float型的除法运算,用中颖SH79/88/89系列的准16位乘除指
令,代替原Keil C51的加减法模拟除法程序,大幅度地提升了原float型的除法的运算速度,解决了原51浮点除法特慢的通病。

extern uint16   imul(uint16 value1,uint16 value2);          // 16位*16位-->16位(无符号二进制乘法)   
extern uint16  uidiv(uint32 value1,uint16 value2);       // 16位/16位-->16位(无符号二进制除法)   
extern uint32   lmul(uint32 value1,uint32 value2);          // 32位*32位-->32位(无符号二进制乘法)   
extern uint32  uldiv(uint32 value1,uint32 value2);       // 32位/32位-->32位(无符号二进制除法)   
extern float   fpmul(float value1, float value2);           // 二进制浮点数快速乘法  
extern float   fpdiv(float value1, float value2);           // 二进制浮点数快速除法  
*/

#endif


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| Cortex-M0 发表于 2011-10-1 20:19 | 显示全部楼层
欢迎各路盆友下载使用~~~
highgear 发表于 2011-10-1 22:10 | 显示全部楼层
我顶,这对于算术运算的程序员简直是福音。
不做的人不知道,做过的人都知道。
 楼主| Cortex-M0 发表于 2011-10-1 22:27 | 显示全部楼层
谢谢highgear老师支持~~~

这个程序库,最难的就是51的浮点数快速除法,今天花了大半天时间,来研究51的浮点数快速除法,充分使用了中颖SH79/88/89系列的特色----准16位乘除指令,对原Keil C51的加减法模拟除法库程序,进行改造,
经过简单的组合运算,成功替代原Keil C51的浮点除法库程序时,还是很兴奋的,程序编写其实很简单,关健是算法的从理论到实践的验证~~~

在8051上,要实现32位快速浮点数除法,并不容易,感谢中颖,感谢中颖51,感谢中颖51单片机的准16位乘除指令,让俺实现了用乘除组合运算,成功替代了原C51用加减法模拟除法的库函数,实际运算速度大幅度提升~~~
 楼主| Cortex-M0 发表于 2011-10-1 22:36 | 显示全部楼层
将改写的中颖51快速浮点数乘法、除法哂一晒,供有情人参考~~~


中颖51快速浮点数乘法程序FPMUL.A51

  1. $NOMOD51

  2. NAME ?C?FPMUL

  3. /**********************************************************************************************
  4. * float R4R5R6R7 fpmul(float R4R5R6R7, float R0R1R2R3);
  5. * result = value1 * value2
  6. * R4R5R6R7 = R4R5R6R7 * R0R1R2R3
  7. * 32位*32位-->32位(4字节浮点数快速乘法)

  8. 用 途 :中颖SH79/88/89F51系列MCU
  9. 作 者 :许意义
  10. 21ic ID :LAOXU
  11. 中颖论坛 : bbs.21ic.com
  12. 日 期 : 2011-09-29

  13. **********************************************************************************************/

  14. ?PR?_FPMUL?FPMUL SEGMENT CODE
  15. EXTRN CODE (_FPRET_1)
  16. EXTRN CODE (_FPRET_2)
  17. EXTRN CODE (_FPRET_3)
  18. EXTRN CODE (_FPRET_4)
  19. EXTRN CODE (_FPRET_5)
  20. EXTRN CODE (_FPRET_6)
  21. PUBLIC ?C?FPMUL
  22. RSEG ?PR?_FPMUL?FPMUL
  23. ?C?FPMUL: MOV A,R4
  24. ORL A,R5
  25. JZ FMUL01
  26. MOV A,R0
  27. ORL A,R1
  28. JNZ FMUL02
  29. MOV A,R5
  30. RLC A
  31. MOV A,R4
  32. RLC A
  33. INC A
  34. JZ FMUL03
  35. CLR A
  36. MOV R4,A
  37. MOV R7,A
  38. MOV R6,A
  39. MOV R5,A
  40. FMUL04: RET
  41. FMUL01: MOV A,R1
  42. RLC A
  43. MOV A,R0
  44. RLC A
  45. INC A
  46. JNZ FMUL04
  47. FMUL03: LJMP _FPRET_4
  48. FMUL02: LCALL _FPRET_1
  49. ANL A,R0
  50. INC A
  51. JZ FMUL07
  52. CLR A
  53. XCH A,R4
  54. ADD A,#81H
  55. JNC FMUL08
  56. ADD A,R0
  57. JNC FMUL09
  58. FMUL07: LJMP _FPRET_6
  59. FMUL08: ADD A,R0
  60. JC FMUL09
  61. LJMP _FPRET_5
  62. FMUL09: PUSH ACC
  63. ORL 0x86,#0x0c
  64. MOV A,R3
  65. ORL A,R2
  66. JNZ FMUL12
  67. CJNE R1,#0x80,FMUL19
  68. FMUL15: POP ACC
  69. MOV R3,A
  70. LJMP _FPRET_3
  71. FMUL19: MOV A,R7
  72. ORL A,R6
  73. JNZ FMUL14
  74. CJNE R5,#0x80,FMUL20
  75. FMUL21: MOV A,R3
  76. MOV R7,A
  77. MOV A,R2
  78. MOV R6,A
  79. MOV A,R1
  80. MOV R5,A
  81. SJMP FMUL15
  82. FMUL20: MOV 0xF1,#0
  83. MOV A,R1
  84. MOV B,R5
  85. MUL AB
  86. MOV R6,A
  87. MOV A,B
  88. LJMP FMUL16
  89. FMUL18: MOV A,R1
  90. XCH A,R5
  91. MOV R1,A
  92. MOV A,R2
  93. MOV R6,A
  94. MOV A,R3
  95. MOV R7,A
  96. FMUL14: MOV 0xF1,R6
  97. MOV A,R7
  98. MOV B,R1
  99. MUL AB
  100. MOV R4,A
  101. MOV R7,B
  102. MOV A,0xF1
  103. XCH A,R5
  104. MOV 0xF1,#0
  105. MOV B,R1
  106. MUL AB
  107. ADD A,R5
  108. MOV R6,A
  109. CLR A
  110. ADDC A,B
  111. SJMP FMUL16
  112. FMUL12: MOV A,R7
  113. ORL A,R6
  114. JNZ FMUL17
  115. CJNE R5,#0x80,FMUL18
  116. SJMP FMUL21
  117. FMUL17: MOV 0xF1,R6
  118. MOV A,R7
  119. MOV B,R3
  120. MUL AB
  121. MOV R4,B
  122. MOV R0,0xF1
  123. MOV 0xF1,R6
  124. MOV A,R7
  125. MOV B,R2
  126. MUL AB
  127. ADD A,R4
  128. MOV A,B
  129. ADDC A,R0
  130. MOV R4,A
  131. CLR A
  132. ADDC A,0xF1
  133. MOV R0,A
  134. MOV 0xF1,R6
  135. MOV A,R7
  136. MOV B,R1
  137. MUL AB
  138. ADD A,R4
  139. MOV R4,A
  140. MOV A,B
  141. ADDC A,R0
  142. MOV R7,A
  143. CLR A
  144. ADDC A,0xF1
  145. MOV R0,A
  146. MOV 0xF1,R2
  147. MOV A,R3
  148. MOV B,R5
  149. MUL AB
  150. ADD A,R4
  151. MOV R4,A
  152. MOV A,B
  153. ADDC A,R7
  154. MOV R7,A
  155. MOV A,0xF1
  156. ADDC A,R0
  157. MOV R6,A
  158. CLR A
  159. MOV 0xF1,A
  160. RLC A
  161. XCH A,R5
  162. MOV B,R1
  163. MUL AB
  164. ADD A,R6
  165. MOV R6,A
  166. MOV A,B
  167. ADDC A,R5
  168. FMUL16: MOV R5,A
  169. ANL 0x86,#0xf3
  170. RLC A
  171. POP ACC
  172. MOV R3,A
  173. JNC FMUL22
  174. INC R3
  175. CJNE R3,#0x00,FMUL23
  176. LJMP _FPRET_6
  177. FMUL22: MOV A,R4
  178. ADD A,R4
  179. MOV R4,A
  180. MOV A,R7
  181. RLC A
  182. MOV R7,A
  183. MOV A,R6
  184. RLC A
  185. MOV R6,A
  186. MOV A,R5
  187. RLC A
  188. MOV R5,A
  189. FMUL23: LJMP _FPRET_2

  190. END
 楼主| Cortex-M0 发表于 2011-10-1 22:39 | 显示全部楼层
中颖51快速浮点数除法程序FPDIV.A51

  1. $NOMOD51

  2. NAME ?C?FPDIV

  3. /**********************************************************************************************
  4. * float R4R5R6R7 fpmul(float R4R5R6R7, float R0R1R2R3);
  5. * result = value1 / value2
  6. * R4R5R6R7 = R4R5R6R7 / R0R1R2R3
  7. * 32位/32位-->32位(4字节浮点数快速除法)

  8. 用 途 :中颖SH79/88/89F51系列MCU
  9. 作 者 :许意义
  10. 21ic ID :LAOXU
  11. 中颖论坛 : bbs.21ic.com
  12. 日 期 : 2011-09-29

  13. **********************************************************************************************/

  14. ?PR?_FPDIV?FPDIV SEGMENT CODE
  15. EXTRN CODE (_FPRET_1)
  16. EXTRN CODE (_FPRET_2)
  17. EXTRN CODE (_FPRET_3)
  18. EXTRN CODE (_FPRET_4)
  19. EXTRN CODE (_FPRET_5)
  20. EXTRN CODE (_FPRET_6)
  21. PUBLIC ?C?FPDIV
  22. DPL1 EQU 0x84
  23. DPH1 EQU 0x85
  24. RSEG ?PR?_FPDIV?FPDIV
  25. FPDIV_4: LJMP _FPRET_6
  26. ?C?FPDIV: MOV A,R4
  27. ANL A,R5
  28. INC A
  29. JZ FPDIV_1
  30. MOV A,R0
  31. ANL A,R1
  32. INC A
  33. JNZ FPDIV_2
  34. FPDIV_1: LJMP _FPRET_4
  35. FPDIV_2: LCALL _FPRET_1
  36. ANL A,R0
  37. INC A
  38. JZ FPDIV_1
  39. MOV A,R4
  40. ORL A,R0
  41. JZ FPDIV_1
  42. MOV A,R4
  43. JNZ FPDIV_3
  44. MOV R5,A
  45. MOV R6,A
  46. MOV R7,A
  47. RET
  48. FPDIV_3: XCH A,R0
  49. JZ FPDIV_4
  50. ADD A,#0x81
  51. XCH A,R0
  52. JNC FPDIV_5
  53. CLR C
  54. SUBB A,R0
  55. JZ FPDIV_6
  56. JNC FPDIV_7
  57. FPDIV_6: LJMP _FPRET_5
  58. FPDIV_5: SUBB A,R0
  59. JNC FPDIV_4
  60. FPDIV_7: MOV DPL,A
  61. MOV A,R1
  62. ADD A,R1
  63. ORL A,R3
  64. ORL A,R2
  65. JNZ FPDIV_8
  66. MOV R3,DPL
  67. LJMP _FPRET_3
  68. FPDIV_8: CLR C
  69. MOV A,R7
  70. SUBB A,R3
  71. MOV A,R6
  72. SUBB A,R2
  73. MOV A,R5
  74. SUBB A,R1
  75. JC FPDIV_9
  76. CLR C
  77. MOV A,R5
  78. RRC A
  79. MOV R5,A
  80. MOV A,R6
  81. RRC A
  82. MOV R6,A
  83. MOV A,R7
  84. RRC A
  85. MOV R7,A
  86. INC DPL
  87. // H0(R0) = ffff / R1
  88. FPDIV_9: ORL 0x86,#0x0c
  89. MOV A,#0xff
  90. MOV 0xF1,A
  91. MOV B,R1
  92. DIV AB
  93. MOV R0,A
  94. PUSH DPL
  95. // N0(R5R6R7R4) = R5R6R7<<8 + (R5R6R7*H0) (放大1字节)
  96. MOV A,R7
  97. MOV 0xF1,R6
  98. MOV B,R0
  99. MUL AB
  100. MOV R4,A
  101. MOV DPL1,A
  102. MOV A,R7
  103. ADD A,B
  104. MOV R7,A
  105. MOV DPH1,A
  106. MOV A,R6
  107. ADDC A,0xF1
  108. MOV R6,A
  109. MOV A,R5
  110. MOV 0xF1,#0
  111. MOV B,R0
  112. MUL AB
  113. ADD A,R6
  114. MOV R6,A
  115. MOV DPL,A
  116. MOV A,B
  117. ADDC A,R5
  118. MOV R5,A
  119. MOV DPH,A // R5R6R7R4 ---> 双DPTR
  120. // D0(R2R3) = R1R2R3 + (R1R2R3*H0>>8)
  121. MOV A,R3
  122. MOV 0xF1,R2
  123. MOV B,R0
  124. MUL AB
  125. MOV A,B
  126. ADD A,R3
  127. MOV R3,A
  128. MOV A,0xF1
  129. ADDC A,R2
  130. MOV R2,A
  131. MOV A,R1
  132. MOV B,R0
  133. MUL AB
  134. ADD A,R2
  135. MOV R2,A
  136. // &(R2R3) = -D0 (2字节)
  137. CLR C
  138. CLR A
  139. SUBB A,R3
  140. MOV R3,A
  141. CLR A
  142. SUBB A,R2
  143. MOV R2,A
  144. // Q = N0 + A + B + C
  145. // A = N0*& (丢3字节) R5R6R7R4(N0) * R2R3 ---> R5R6R7R4(A) | R5=0
  146. LCALL NFPMUL32
  147. LCALL NFPADD32
  148. // B = A*& (丢3字节) R5R6R7R4(A) * R2R3 ---> R5R6R7R4(B) | R5R6=0
  149. LCALL NFPMUL32
  150. LCALL NFPADD32
  151. // C = B*& (丢3字节) R5R6R7R4(B) * R2R3 ---> R5R6R7R4(C) | R5R6R7=0
  152. LCALL NFPMUL32
  153. LCALL NFPADD32
  154. ANL 0x86,#0xf3
  155. POP ACC
  156. DEC A
  157. MOV R3,A
  158. MOV R5,DPH
  159. MOV R6,DPL
  160. MOV R7,DPH1
  161. MOV R4,DPL1
  162. LJMP _FPRET_2
  163. // R5R6R7R4 * R2R3 ---> R5R6R7R4
  164. NFPMUL32: MOV A,R3
  165. MOV 0xF1,R2
  166. MOV B,R4
  167. MUL AB
  168. MOV R1,B
  169. MOV R4,0xF1
  170. MOV A,R3
  171. MOV 0xF1,R2
  172. MOV B,R7
  173. MUL AB
  174. ADD A,R1
  175. MOV A,B
  176. ADDC A,R4
  177. MOV R1,A
  178. CLR A
  179. ADDC A,0xF1
  180. MOV R4,A
  181. MOV A,R5
  182. ORL A,R6
  183. JZ NFPML32_1
  184. MOV A,R3
  185. MOV 0xF1,R2
  186. MOV B,R6
  187. MUL AB
  188. ADD A,R1
  189. MOV A,B
  190. ADDC A,R4
  191. MOV R4,A
  192. CLR A
  193. ADDC A,0xF1
  194. MOV R7,A
  195. MOV A,R5
  196. JZ NFPML32_2
  197. MOV B,A
  198. MOV A,R3
  199. MOV 0xF1,R2
  200. MUL AB
  201. ADD A,R4
  202. MOV R4,A
  203. MOV A,B
  204. ADDC A,R7
  205. MOV R7,A
  206. CLR A
  207. MOV R5,A
  208. ADDC A,0xF1
  209. MOV R6,A
  210. RET
  211. NFPML32_1: MOV R7,#0
  212. NFPML32_2: MOV R6,#0
  213. MOV R5,#0
  214. RET
  215. // 双DPTR + R4R5R6R7 ---> 双DPTR
  216. NFPADD32: MOV A,DPL1
  217. ADD A,R4
  218. MOV DPL1,A
  219. MOV A,DPH1
  220. ADDC A,R7
  221. MOV DPH1,A
  222. MOV A,DPL
  223. ADD A,R6
  224. MOV DPL,A
  225. MOV A,DPH
  226. ADDC A,R5
  227. MOV DPH,A
  228. RET

  229. END
 楼主| Cortex-M0 发表于 2011-10-1 22:42 | 显示全部楼层
中颖51快速浮点数乘除法通用返回处理程序FPRET.A51


  1. $NOMOD51

  2. NAME _FPRET

  3. /**********************************************************************************************
  4. * float R4R5R6R7 fpret(float R4R5R6R7, float R0R1R2R3);
  5. * result = value1 *^/ value2
  6. * R4R5R6R7 = R4R5R6R7 *^/ R0R1R2R3
  7. * 32位*32位-->32位(4字节浮点数乘除法返回处理程序)

  8. 用 途 :中颖SH79/88/89F51系列MCU
  9. 作 者 :许意义
  10. 21ic ID :LAOXU
  11. 中颖论坛 : bbs.21ic.com
  12. 日 期 : 2011-09-29

  13. **********************************************************************************************/

  14. ?PR?_FPRET?FPRET SEGMENT CODE
  15. PUBLIC _FPRET_1
  16. PUBLIC _FPRET_2
  17. PUBLIC _FPRET_3
  18. PUBLIC _FPRET_4
  19. PUBLIC _FPRET_5
  20. PUBLIC _FPRET_6

  21. RSEG ?PR?_FPRET?FPRET
  22. _FPRET_1: MOV A,R1
  23. SETB ACC.7
  24. XCH A,R1
  25. RLC A
  26. MOV A,R0
  27. RLC A
  28. MOV R0,A
  29. MOV PSW.5,C
  30. MOV A,R5
  31. SETB ACC.7
  32. XCH A,R5
  33. RLC A
  34. MOV A,R4
  35. RLC A
  36. MOV R4,A
  37. JNC FPT_01
  38. CPL PSW.5
  39. FPT_01: RET
  40. _FPRET_2: MOV A,R4
  41. JNB ACC.7,_FPRET_3
  42. INC R7
  43. CJNE R7,#0x00,_FPRET_3
  44. INC R6
  45. CJNE R6,#0x00,_FPRET_3
  46. INC R5
  47. CJNE R5,#0x00,_FPRET_3
  48. INC R3
  49. MOV A,R3
  50. JZ _FPRET_6
  51. _FPRET_3: MOV C,PSW.5
  52. MOV A,R3
  53. RRC A
  54. MOV R4,A
  55. MOV A,R5
  56. MOV ACC.7,C
  57. MOV R5,A
  58. RET
  59. _FPRET_4: MOV A,#0xFF
  60. FPT_02: MOV R4,A
  61. MOV R5,A
  62. FPT_03: MOV R6,A
  63. MOV R7,A
  64. RET
  65. _FPRET_5: CLR A
  66. SJMP FPT_02
  67. _FPRET_6: MOV C,PSW.5
  68. MOV A,#0xFF
  69. RRC A
  70. MOV R4,A
  71. MOV R5,#0x80
  72. CLR A
  73. SJMP FPT_03

  74. END
zoomone 发表于 2011-10-2 12:56 | 显示全部楼层
有时间了就钻研钻研
highgear 发表于 2011-10-5 08:23 | 显示全部楼层
顶出水面
zxcscm 发表于 2011-10-18 08:59 | 显示全部楼层
来顶,顶~顶!
xubx83 发表于 2011-10-18 16:38 | 显示全部楼层
顶个先
zoomone 发表于 2011-10-20 12:57 | 显示全部楼层
能不能介绍一下怎么设置和使用的,我添加后编译老是出错
 楼主| Cortex-M0 发表于 2011-10-20 16:42 | 显示全部楼层
关键这几点设置。







打包给个带工程的DEMO测试文件

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
zoomone 发表于 2011-10-20 17:57 | 显示全部楼层
extern uint16   imul(uint16 value1,uint16 value2);          // 16位*16位-->16位(无符号二进制乘法)   
extern uint16  uidiv(uint32 value1,uint16 value2);       // 16位/16位-->16位(无符号二进制除法)   
extern uint32   lmul(uint32 value1,uint32 value2);          // 32位*32位-->32位(无符号二进制乘法)   
extern uint32  uldiv(uint32 value1,uint32 value2);       // 32位/32位-->32位(无符号二进制除法)   
extern float   fpmul(float value1, float value2);           // 二进制浮点数快速乘法  
extern float   fpdiv(float value1, float value2);           // 二进制浮点数快速除法  

为什么这几个函数不能用?
 楼主| Cortex-M0 发表于 2011-10-20 18:58 | 显示全部楼层
不是这几个函数不能用,这几个函数和 Keil C51内部库函数重名,也就是说,只要在编译时加入 math_sh88f51.lib ,  将自动替代原 Keil C51内部库函数,实现无缝嵌入,在实际使用中,你根本不需要管这些库函数的存在。
例如:  int  a,b,c;
         float  x,y,z;
         c = a * b / c;
         z = x * y / z;
Keil C51将自动调用上述SH88F51专用库函数,替代原 Keil C51内部库函数,实现无缝嵌入。
zoomone 发表于 2011-10-20 19:07 | 显示全部楼层
噢 看来不会的还很多:L
 楼主| Cortex-M0 发表于 2011-10-20 19:52 | 显示全部楼层
友情提示:
假如你调用上述库函数,脱离SH88F51的真实运行环境,如用Keil C51软件仿真,或将程序装载到其他厂家的51单片机中运行,将出错,无法得到预期的结果~~~

本库只有在特定的环境中,即在SH88F51的硬件支持下,运行结果才会正确。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:学习chunyang和maychang两位老师,努力练好基本功。 学习HOT大叔,学好“Cortex-M0”,做“Cortex-M0”之菜鸟。

7

主题

4820

帖子

12

粉丝
快速回复 在线客服 返回列表 返回顶部