找回密码
 立即注册

关于硬件乘除法的问题。

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:5
  • 最近打卡:2025-09-08 10:24:44

6

主题

37

回帖

134

积分

注册会员

积分
134
发表于 2025-9-3 10:43:05 | 显示全部楼层

没有用库。我用库试一下。

点评

官网下载最新版本: https://www.stcaimcu.com/data/download/Library/STC8_MDU16.LIB  详情 回复 发表于 2025-9-3 10:46
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:297
  • 最近打卡:2025-09-13 09:56:50
已绑定手机

82

主题

3111

回帖

6879

积分

荣誉版主

无情的代码机器

积分
6879
发表于 2025-9-3 10:46:22 | 显示全部楼层
水水水*** 发表于 2025-9-3 10:43
没有用库。我用库试一下。

官网下载最新版本:

https://www.stcaimcu.com/data/download/Library/STC8_MDU16.LIB
三天不学习,赶不上刘少奇~
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:5
  • 最近打卡:2025-09-08 10:24:44

6

主题

37

回帖

134

积分

注册会员

积分
134
发表于 2025-9-3 10:58:16 | 显示全部楼层
示例中少了下面的三个定义。
#define     MD1U16                  (*(unsigned int  volatile xdata *)0xfcf2)
#define     MD5U16                  (*(unsigned int  volatile xdata *)0xfcf4)
#define     MD3U32                  (*(unsigned long volatile xdata *)0xfcf0)
但是就算这样,实际用示波器测量,和软件直接算没区别。总中断函数执行时间是13us左右,去掉这个乘法是3.5us左右。也就是乘法用了10us左右。硬件和软件需要的时间是差不多的。
代码如下:
                        MD1U16 = SWING_HW;
                        MD5U16 = M_q15;
                        ARCON = 4 << 5;
                        OPCON = 1;        //启动硬件乘法器
                        while((OPCON & 1) != 0);
                        half_cmd = MD3U32 >> 15;
其中SWING_HW和M_q15都是uint16。实测确实是需要10us的时间。
我再用库试一下,看看咋样。
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:5
  • 最近打卡:2025-09-08 10:24:44

6

主题

37

回帖

134

积分

注册会员

积分
134
发表于 2025-9-3 11:07:37 | 显示全部楼层
添加了MDU16的硬件库后,再执行这个代码,没效果啊。和软件算是一样的时间。
half_cmd = ((int32_t)SWING_HW * (uint16_t)M_q15) >> 15;
是不是因为运算过程中保留了32位的数据长度,而标准的运算是16*16只保留16位的长度?
上面这个运算,应该是32位*16位,所以没用调用内部的硬件乘法?那如果我想保留16*16的结果,不要截断为16位。应该怎么操作呢?
上面这种运算需要的时间比用寄存器操作慢1us左右。实测是15us左右。
如果16*16位变量运算的话,运算结果溢出就被截断了。正常做法就是添加uint32,表示按照32位长度保存结果。那是不是就不会触发内部硬件MDU16乘法操作了?还是说需要其他配置?
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:5
  • 最近打卡:2025-09-08 10:24:44

6

主题

37

回帖

134

积分

注册会员

积分
134
发表于 2025-9-3 11:20:15 | 显示全部楼层
erci*** 发表于 2025-9-3 10:46
官网下载最新版本:

https://www.stcaimcu.com/data/download/Library/STC8_MDU16.LIB

实测了。还是10us多。可能是因为需要保留32位数据长度导致没有使用硬件乘法。比寄存器操作还慢1us。是不是要换成AI8051U?或者您有时间也可以测试一下,直接用这个语句测试就行。

点评

我测试手册例程16位乘以16位取32位结果只需要3.75us,可以发下您的测试程序吗? [attachimg]113821[/attachimg]  详情 回复 发表于 2025-9-3 11:36
收到,我试下  发表于 2025-9-3 11:21
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:5
  • 最近打卡:2025-09-08 10:24:44

6

主题

37

回帖

134

积分

注册会员

积分
134
发表于 2025-9-3 11:36:33 | 显示全部楼层
erci*** 发表于 2025-9-3 10:46
官网下载最新版本:

https://www.stcaimcu.com/data/download/Library/STC8_MDU16.LIB

我将int32去掉了,实测是4.5us。确实快了很多。代码如下。
half_cmd = (SWING_HW * M_q15) >> 15;
我再将int32加上看看。下面这个语句的执行时间就是15us左右。这里的时间是我整个中断的时间,还有其他语句。单独这个语句的时间应该在10us左右。上面16*16位运算单语句估计只要1us左右。16*16速度快很多。这是添加了硬件库后的结果。
half_cmd = ((int32_t)SWING_HW * M_q15) >> 15;

点评

注意keil选项里编译等级也会影响这个速度 [attachimg]113822[/attachimg]  详情 回复 发表于 2025-9-3 11:38
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:297
  • 最近打卡:2025-09-13 09:56:50
已绑定手机

82

主题

3111

回帖

6879

积分

荣誉版主

无情的代码机器

积分
6879
发表于 2025-9-3 11:36:54 | 显示全部楼层
水水水*** 发表于 2025-9-3 11:20
实测了。还是10us多。可能是因为需要保留32位数据长度导致没有使用硬件乘法。比寄存器操作还慢1us。是不 ...

我测试手册例程16位乘以16位取32位结果只需要3.75us@11.0592MHz,可以发下您的测试程序吗?

截图202509031136477646.jpg
  1. #include <STC8H.H>
  2. #include <def.H>
  3. #include <stdio.H>
  4. void Delay10us(void)        //@11.0592MHz
  5. {
  6.         unsigned char data i;
  7.         i = 35;
  8.         while (--i);
  9. }
  10. void main()
  11. {
  12. ////////////////////////////////////////////////////////////////////////////////
  13. //16 位乘 16 位
  14. ////////////////////////////////////////////////////////////////////////////////
  15. unsigned long res;
  16. unsigned int dat1, dat2;
  17. P_SW2 |= 0x80;
  18. P2M1 = 0;   P2M0 = 0;   //设置为准双向口
  19. P20 = 1;
  20. Delay10us();
  21. P20 = 0;
  22. Delay10us();
  23. P20 = 1;
  24. //访问扩展寄存器 xsfr
  25. MD1 = dat1;
  26. //dat1 用户给定
  27. MD5 = dat2;
  28. //dat2 用户给定
  29. ARCON = 4 << 5;
  30. //16 位*16 位,乘法模式
  31. OPCON = 1;
  32. //启动计算
  33. while((OPCON & 1) != 0);
  34. //等待计算完成
  35. res = MD3;
  36. P20 = 0;
  37. //32 位结果
  38. //////////////////////////////////////////////////////////////////////////////////
  39. ////32 位除以 16 位
  40. //////////////////////////////////////////////////////////////////////////////////
  41. //unsigned long res;
  42. //unsigned long dat1;
  43. //unsigned int dat2;
  44. ////访问扩展寄存器 xsfr
  45. //MD3U32 = dat1;
  46. ////dat1 用户给定
  47. //MD5U16 = data2;
  48. ////dat2 用户给定
  49. //ARCON = 6 << 5;
  50. ////32 位/16 位,除法模式
  51. //OPCON = 1;
  52. ////启动计算
  53. //while((OPCON & 1) != 0);
  54. ////等待计算完成
  55. //res = MD3U32;
  56. ////32 位商,16 位余数在 MD5U16 中
  57. //////////////////////////////////////////////////////////////////////////////////
  58. ////左移或右移:
  59. //////////////////////////////////////////////////////////////////////////////////
  60. //unsigned long res;
  61. //unsigned long dat1;
  62. //unsigned char num;
  63. ////移位的位数, 用户给定
  64. //MD3U32 = dat1;
  65. ////dat1 用户给定
  66. //ARCON = (2 << 5) + num;
  67. ////32 位左移模式
  68. ////ARCON = (1 << 5) + num;
  69. ////32 位右移模式
  70. //OPCON = 1;
  71. ////启动计算
  72. //while((OPCON & 1) != 0);
  73. ////等待计算完成
  74. //res = MD3U32;
  75. ////32 位结果
  76.         while(1);
  77.         
  78. }
复制代码


三天不学习,赶不上刘少奇~
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:297
  • 最近打卡:2025-09-13 09:56:50
已绑定手机

82

主题

3111

回帖

6879

积分

荣誉版主

无情的代码机器

积分
6879
发表于 2025-9-3 11:38:59 | 显示全部楼层
水水水*** 发表于 2025-9-3 11:36
我将int32去掉了,实测是4.5us。确实快了很多。代码如下。
half_cmd = (SWING_HW * M_q15) >> 15;
我再将 ...

注意keil选项里编译等级也会影响这个速度

截图202509031138479217.jpg
三天不学习,赶不上刘少奇~
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:5
  • 最近打卡:2025-09-08 10:24:44

6

主题

37

回帖

134

积分

注册会员

积分
134
发表于 2025-9-3 11:41:50 | 显示全部楼层
erci*** 发表于 2025-9-3 10:46
官网下载最新版本:

https://www.stcaimcu.com/data/download/Library/STC8_MDU16.LIB

所以是不是要换支持MDU32的单片机?支持MDU32的单片机型号不多,最强大的应该是STC32G和AI8051U了吧?为了兼容32位和8位,显然AI8051U最好?

点评

提升主频到44.2368,可以测到875ns。需求是多少呢?Ai8051U系列是可以兼容8bit和32bit,且支持MDU32  详情 回复 发表于 2025-9-3 11:46
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:5
  • 最近打卡:2025-09-08 10:24:44

6

主题

37

回帖

134

积分

注册会员

积分
134
发表于 2025-9-3 11:45:00 | 显示全部楼层
erci*** 发表于 2025-9-3 11:38
注意keil选项里编译等级也会影响这个速度

8051还能优化啊。这我第一次知道。这个等级一般建议多少?7级吗?我是默认的0级测试的。你用我的语句测试,用硬件库这种。
half_cmd = ((int32_t)SWING_HW * (uint16_t)M_q15) >> 15;

点评

我是在7级测试。 //7.62us@44.2368MHz //half_cmd = ((int32_t)SWING_HW * (uint16_t)M_q15) >> 15; //875ns@44.2368MHz half_cmd = ((uint16_t)SWING_HW * (uint16_t)M_q15) >> 15;  详情 回复 发表于 2025-9-3 11:50
回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-9-14 11:14 , Processed in 0.158588 second(s), 102 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表