打印

《中颖MCU专用8-32位混合运算》定点运算程序库

[复制链接]
5220|24
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Cortex-M0|  楼主 | 2011-9-14 08:32 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
使用中颖SH88F2051/4051 的《史上最“烂”两轮平衡小车》DIY开源活动在火爆进行中,因Keil自带的C51浮点运算库,太占内存和运行时间,原计划是用定点运算库来进行PID运算。

只是Keil自带的C51定点运算库,在乘除相关指令方面,没能充分运用中颖SH79/88/89/F51系列自带的 16位X8位硬件乘法器 和 16位/8位硬件除法器,网上搜了一下,中颖SH79/88/89/F51系列有个 16bit的定点运算库,编的很不理想,并没有充分发挥中颖SH79/88/89/F51系列自带的 16位X8位硬件乘法运算 和 16位/8位硬件除法运算很多方面的天才性能,特抽了点时间,改写了中颖SH79/88/89/F51系列那个定点运算库,并且扩展到任意 8-32位混合乘除运算及取模(求余数)运算,加入了 8-32位 HEX--->BCD 数制转换和 8-32位 BCD--->HEX 数制转换,其中 32位乘法运算 和 32位 HEX--->BCD 数制转换 由于优化算法,执行速度比 Keil常规程序运行速度增加 N倍,32位乘法运算 充分利用了 中颖SH79/88/89/F51系列自带的 16位X8位硬件乘法器,采用快速算法,执行时间快,而更有特色的是 32位 HEX--->BCD 数制转换,充分利用了 中颖SH79/88/89/F51系列自带的 16位/8位硬件除法器,采用优化的快速算法,执行时间更快。

8-32位 HEX--->BCD 数制转换 输出的 BCD码,均采用压缩的 BCD码,比常规 HEX--->BCD 数制转换 输出的单字节 BCD码,更节省RAM及压缩合并时间。

在做8-32位混合除法运算时,在除数为0时,输出为被除数,不是原16bit那个定点运算库,输出为0,以做到和原C51定点运算库除法运算结果全兼容。

其他程序都不同程度的熔入了中颖SH79/88/89/F51系列自带的 16位X8位硬件乘法器 和 16位/8位硬件除法器,其中16位运算及 8-32位混合运算优化速度增加最多。


中颖《8-32位混合运算》定点运算程序库 清单如下:

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

extern  Byte bcd8_hex(Byte value1);     //  8位 BCD --> 8位 HEX
extern Word  bcd16_hex(Word value1);        // 16位 BCD -->16位 HEX
extern Dword  bcd32_hex(Dword value1);    // 32位 BCD -->32位 HEX      
extern  Word hex8_bcd(Byte value1);     //  8位 HEX -->16位 BCD
extern Dword  hex16_bcd(Word value1);        // 16位 HEX -->32位 BCD
extern Dword  hex32_bcd(Dword value1);    // 32位 HEX -->32位 BCD      
extern  Dword  mul8_16(Byte value1,Word value2);  //  8位*16位-->32位(HEX乘法)  
extern  Dword  mul8_32(Byte value1,Dword value2);  //  8位*32位-->32位(HEX乘法)  
extern  Dword  mul16(Word value1,Word value2);   // 16位*16位-->32位(HEX乘法)
extern  Dword  mul16_32(Word value1,Dword value2);  // 16位*32位-->32位(HEX乘法)
extern  Dword  mul32(Dword value1,Dword value2);  // 32位*32位-->32位(HEX乘法)  
extern Word  div16_8(Word value1,Byte value2);   // 16位/ 8位-->16位(HEX除法)
extern  Word   div16(Word value1,Word value2);   // 16位/16位-->16位(HEX除法)
extern  Dword  div32_8(Dword value1,Byte value2);  // 32位/ 8位-->32位(HEX除法)
extern  Dword  div32_16(Dword value1,Word value2);  // 32位/16位-->32位(HEX除法)
extern  Dword  div32(Dword value1,Dword value2);  // 32位/32位-->32位(HEX除法)
extern Byte  mod8(Byte value1,Byte value2);   //  8位% 8位--> 8位(取余数)
extern Byte  mod16_8(Word value1,Byte value2);  // 16位% 8位--> 8位(取余数)
extern Word  mod16(Word value1,Word value2);   // 16位%16位-->16位(取余数)  
extern Byte   mod32_8(Dword value1,Byte value2);   // 32位% 8位--> 8位(取余数)
extern Word mod32_16(Dword value1,Word value2);  // 32位%16位-->16位(取余数)  
extern Dword mod32(Dword value1,Dword value2);  // 32位%32位-->32位(取余数)  

#endif


中颖定点运算补充库.rar (41.83 KB)
沙发
Cortex-M0|  楼主 | 2011-9-14 08:34 | 只看该作者
为了更好的推广 中颖MCU,请neyo.zhong斑竹在百忙当中,抽空帮忙测试,谢谢~~~

使用特权

评论回复
板凳
neyo.zhong| | 2011-9-14 09:33 | 只看该作者
2# Cortex-M0

呵呵,居然被前辈你点名了,太惊讶了,我代表中颖电子感谢前辈为推广中颖8051所作出的努力。

其实我是管理员啦,不是版主,在技术方面不是很在行,只是偶尔帮忙几个版主回答一下自己懂的问题,想帮忙也帮不上,我将帖子内容转给几个版主,看看他们是否能够挤出时间来测试一下。

使用特权

评论回复
地板
冰清玉洁| | 2011-9-14 14:52 | 只看该作者
2# Cortex-M0

呵呵,居然被前辈你点名了,太惊讶了,我代表中颖电子感谢前辈为推广中颖8051所作出的努力。

其实我是管理员啦,不是版主,在技术方面不是很在行,只是偶尔帮忙几个版主回答一下自己懂的问题,想帮 ...
neyo.zhong 发表于 2011-9-14 09:33
您还技术不行啊:L

使用特权

评论回复
5
neyo.zhong| | 2011-9-14 17:46 | 只看该作者
4# 冰清玉洁

呵呵,绝非自谦,和各位前辈比,差很多。
已通过邮件告知几位版主了,他们应该会在近期给出答复的。

使用特权

评论回复
6
Cortex-M0|  楼主 | 2011-9-15 07:56 | 只看该作者
谢谢 neyo.zhong弟 ~~~ :D

使用特权

评论回复
7
laicq| | 2011-9-15 11:14 | 只看该作者
很好,很强大,不过我向来不用库文件的.

使用特权

评论回复
8
neyo.zhong| | 2011-9-15 13:22 | 只看该作者
6# Cortex-M0

是谢谢您才对,呵呵

使用特权

评论回复
9
monkeypony| | 2011-9-15 13:50 | 只看该作者
很强!

使用特权

评论回复
10
gongche| | 2011-9-19 09:24 | 只看该作者
真是个宝库,得顶

使用特权

评论回复
11
bananarer| | 2011-9-19 11:31 | 只看该作者
本帖最后由 bananarer 于 2011-9-20 10:53 编辑

正确性稍微验证了一下没有仔细验证,应该OK, 主要测试了一下运行时间,运行的是12M 晶振
bcd8_hex(0x99)            4.2us
bcd32_hex(0x98765432)        29us
hex8_bcd(249)            5.6us
hex16_bcd(32249)        13.6us
hex32_bcd(12345678)        45.6us
mul8_16(123,45678)        6.1us
mul8_32(123,4567890)        10.1us
mul16(12345,45678)        9.5us
mul16_32(1234,567890)        15.4us
mul32(36789,98765)        21.4us
div16_8(54321,123)        5.6us
div16(54321,12345)        22us
div32_8(987654321,234)        11us
div32_16(987654321,12345)    88.8us
div32(987654321,123456)        73us
mod8(45,78)            3.4us
mod16_8(54321,123)        7us
mod16(45678,12345)        24.2us
mod32_8(987654321,234)        12.4us
mod32_16(987654321,12345)    89us
mod32(987654321,123456)        75us

使用特权

评论回复
12
Cortex-M0|  楼主 | 2011-9-20 05:58 | 只看该作者
呵呵!

斑竹速席挺快的,中颖速度更快~~~  :P

乘除法运算速度比普通51快多啦~~~

使用特权

评论回复
13
Cortex-M0|  楼主 | 2011-10-6 06:31 | 只看该作者
最后更新~~~

本《中颖MCU专用8-32位混合运算》库,增加了若干非常实用的,无符号、有符号定点多字节乘法、除法子程序库,还有一个特色就是,增加了无符号、有符号定点多字节除法同时取商和余数子程序库,对同时需要用到这两个参数的场合,极大地提高了运行速度,使用时只需在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

使用特权

评论回复
14
Cortex-M0|  楼主 | 2011-10-6 06:34 | 只看该作者
还有一个特色是:

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

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

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

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

三、友情提示
本《中颖专用乘除库》,仅适用于中颖SH79/88/89系列单片机,其他51单片机并不适用,由于Keil C51不支持中颖51单片机的软件仿真,所以必须要用中颖51单片机的硬件仿真或依靠中颖51单片机的实时运行,运算结果才能正确。

使用特权

评论回复
15
Cortex-M0|  楼主 | 2011-10-6 06:38 | 只看该作者
欢迎下载试用~~~



global.rar (2.27 KB)


math_sh88f51.rar (10.02 KB)

使用特权

评论回复
16
huwr| | 2011-10-13 09:07 | 只看该作者
这个太强大了,赞一个

使用特权

评论回复
17
xh2008| | 2011-10-17 07:53 | 只看该作者
好好学习一下

使用特权

评论回复
18
neyo.zhong| | 2011-11-23 10:55 | 只看该作者
15# Cortex-M0

忍不住再起顶起,呵呵~~~;P

使用特权

评论回复
19
zhu51231| | 2011-12-8 15:20 | 只看该作者
mark

使用特权

评论回复
20
liuhongyu_2408| | 2012-10-27 13:24 | 只看该作者
感谢楼主的奉献,在你其他的帖子中看到你贴出的源码。
相拥浮点数的运算,但是你又乘法、出发、返回,这几个怎么用呢???

使用特权

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

本版积分规则

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

7

主题

4820

帖子

12

粉丝