[APM32F4] 基于APM32F411 IQmath模板移植及IQmath相关知识简介

[复制链接]
7981|2
 楼主| lzh12a3nf 发表于 2023-11-18 17:18 | 显示全部楼层 |阅读模式
本帖最后由 lzh12a3nf 于 2023-11-27 09:39 编辑

#申请原创#@21小跑堂
1、前言
    最近在学习DSP库,有去关注到Ti的DSP库,从中又了解到了Ti的IQmath。IQmath定点库适用于M0,M0+,M3这些不带FPU的硬件FPU的内核上,但最近手头入手了一块极海的APM32F411的M4内核开发板,因此基于APM32F411开发板,进行一个IQmath库的移植操作记录,

2、相关知识介绍
2.1 定点数
      定点数通常由固定的位数来表示整数和小数。定点数的小数位置是固定的,因此它们的精度也是固定的。例如,IQ24可以表示-128-128之间的实数,但它的小数位有24位,且它的小数精度为1/2^24=0.000000060,所以,IQ24可以表示的精度范围为-128-127.999999940。在实际使用中,为了提高计算精度,在把实际变量转换成IQ前,需要搞定IQ1-30的实际范围,如果不提前查看,存在数据溢出的风险。
2.2 相应函数的简单介绍
  1. _IQN 将输入的浮点数进行IQ格式数转换
  2. _IQtoF 将IQ格式数进行浮点数转换
  3. long _IQmpyI32(A, B) //N*long IQ乘long
  4. long _IQmpyI32int(A, B) //N*long IQ乘long 返回整数部分
  5. long _IQmpyI32frac(A, B)//N*long IQ乘long 返回小数部分
  6. _IQmpy(A, B)            //N*N乘法
  7. _IQrmpy(A, B)           //N*N四舍五入的乘法最后保存结果前(四舍五入)
  8. _IQrsmpy(A, B)          //N*N四舍五入的饱和处理乘法(如果结果超过IQ范围也会限制计算结果值到这个范围)
  9. _IQmpyIQX(A, A1, B, B1) //N1*N2两个不同的Q格式乘法,返回全局Q格式
  10. _IQdiv(A, B)            // N/N iq除法
  11. _IQsin(A)                //正弦值
  12. _IQasin(A)              //反正弦值,输入范围在-Π到Π
  13. _IQsinPU(A)             //正弦函数(标幺值),你占这个圆周的几分之几为单位如果sin((0.25*PI)/(2*PI)),输入范围在0-2Π
  14. _IQcos(A)                //余弦值
  15. _IQacos(A)              //反余弦值,输入范围在-Π到Π
  16. _IQcosPU(A)             //余弦函数(标幺值),输入范围在0-2Π
  17. _IQatan(A)                  //反正切值
  18. _IQatan2(A, B)           //第四象限反正切 tan-1(sin, cos)
  19. _IQatan2PU(A, B)         //第四象限反正切 tan-1(sin, cos)
  20. _IQatan(A, B)           //定点反正切    tan-1(1),,1=sin/cos
  21. _IQNsqrt(A)             //平方根        a^0.5
  22. _IQNisqrt(A)            //平方根倒数    1/a^0.5
  23. _IQNmag(A, B)           //求模运算(sqrt(A^2 + B^2)
  24. _IQsqrt(A)              //平方根        a^0.5
  25. _IQisqrt(A)             //平方根倒数    1/a^0.5
  26. _IQmag(A, B)            //求模运算(sqrt(A^2 + B^2)
  27. _IQsat(A, long P, long N)//IQ数值的限幅函数 把A限制到[N P]之间
  28. _IQNabs(A)              //IQ数据的绝对值    |A|
  29. _IQabs(A)               //IQ数据的绝对值    |A|
  30. _IQmpy2,4,8,16,32,64 //将输入数进行左移操作,即相乘多少倍
  31. _IQdiv2,4,8,16,32,64 //将输入数进行右移操作,即相除多少倍



3、基于APM32F411 DSP IQmath移植
3.1、必备资料
1.IQmathLib-cm3.lib(IQ运算程序方法)
2.IQmathLib.h(各函数实现文件)

3.2 移植操作
1.将对应的文件加到路径上,如下图:
1.png

2.调用IQmath库函数进行操作,如下图代码
  1. int main(void)
  2. {
  3.         
  4.     /* Init LED */
  5.     APM_MINI_LEDInit(LED2);
  6.     APM_MINI_LEDInit(LED3);
  7.         
  8.     USART_Config_T usartConfigStruct;

  9.     /* USART1 configuration */
  10.     usartConfigStruct.baudRate = 115200;
  11.     usartConfigStruct.hardwareFlow = USART_HARDWARE_FLOW_NONE;
  12.     usartConfigStruct.mode = USART_MODE_TX_RX;
  13.     usartConfigStruct.parity = USART_PARITY_NONE;
  14.     usartConfigStruct.stopBits = USART_STOP_BIT_1;
  15.     usartConfigStruct.wordLength = USART_WORD_LEN_8B;
  16.     APM_MINI_COMInit(COM1, &usartConfigStruct);
  17.         
  18.      _iq X,Y,Z;
  19.      X = _IQ(5);
  20.      Y = _IQ(6);
  21.      Z = _IQmpy(X,Y);
  22.      printf("X = 0x%lX\r\n", X);
  23.      printf("Y = 0x%lX\r\n", Y);
  24.      printf("Z = 0x%lX\r\n", Z);
  25.         
  26.     while (1)
  27.     {
  28.       APM_MINI_LEDToggle(LED2);
  29.       APM_MINI_LEDToggle(LED3);
  30.       Delay(0XFFFFFF);
  31.     }
  32. }
3.输出结果,如下图:
结果输出图.png



其中,IQ函数:
  1. #define _IQ30(A)                ((_iq30)((A) * (1 << 30)))
  2. #define _IQ29(A)                ((_iq29)((A) * (1 << 29)))
  3. #define _IQ28(A)                ((_iq28)((A) * (1 << 28)))
  4. #define _IQ27(A)                ((_iq27)((A) * (1 << 27)))
  5. #define _IQ26(A)                ((_iq26)((A) * (1 << 26)))
  6. #define _IQ25(A)                ((_iq25)((A) * (1 << 25)))
  7. #define _IQ24(A)                ((_iq24)((A) * (1 << 24)))
  8. #define _IQ23(A)                ((_iq23)((A) * (1 << 23)))
  9. #define _IQ22(A)                ((_iq22)((A) * (1 << 22)))
  10. #define _IQ21(A)                ((_iq21)((A) * (1 << 21)))
  11. #define _IQ20(A)                ((_iq20)((A) * (1 << 20)))
  12. #define _IQ19(A)                ((_iq19)((A) * (1 << 19)))
  13. #define _IQ18(A)                ((_iq18)((A) * (1 << 18)))
  14. #define _IQ17(A)                ((_iq17)((A) * (1 << 17)))
  15. #define _IQ16(A)                ((_iq16)((A) * (1 << 16)))
  16. #define _IQ15(A)                ((_iq15)((A) * (1 << 15)))
  17. #define _IQ14(A)                ((_iq14)((A) * (1 << 14)))
  18. #define _IQ13(A)                ((_iq13)((A) * (1 << 13)))
  19. #define _IQ12(A)                ((_iq12)((A) * (1 << 12)))
  20. #define _IQ11(A)                ((_iq11)((A) * (1 << 11)))
  21. #define _IQ10(A)                ((_iq10)((A) * (1 << 10)))
  22. #define _IQ9(A)                 ((_iq9)((A) * (1 << 9)))
  23. #define _IQ8(A)                 ((_iq8)((A) * (1 << 8)))
  24. #define _IQ7(A)                 ((_iq7)((A) * (1 << 7)))
  25. #define _IQ6(A)                 ((_iq6)((A) * (1 << 6)))
  26. #define _IQ5(A)                 ((_iq5)((A) * (1 << 5)))
  27. #define _IQ4(A)                 ((_iq4)((A) * (1 << 4)))
  28. #define _IQ3(A)                 ((_iq3)((A) * (1 << 3)))
  29. #define _IQ2(A)                 ((_iq2)((A) * (1 << 2)))
  30. #define _IQ1(A)                 ((_iq1)((A) * (1 << 1)))
相应的输入数会进行一个相乘的操作,此处采用IQ2,即5*4=20,用16进制表达为0x14,6*4=24,用16进制表达为0x18。

其次,_IQmpy函数
2.png

将输入的两个IQ数进行相乘操作,根据计算结果可知,还会对相应的IQ数进行除法操作。如0x14*0x18=0x1E0,0x1E0/4=0x78。


4、基于APM32F411 IQmath移植Demo

IQmath Demo.rar (7.85 MB, 下载次数: 10)


此次分享到这,如有问题,大家评论区一起讨论,谢谢!







评论

感谢分享!奖励500家园币(可在家园币商城兑换物品)  发表于 2023-11-28 10:09
 楼主| lzh12a3nf 发表于 2023-11-27 09:39 | 显示全部楼层
修改其中部分文字表述
您需要登录后才可以回帖 登录 | 注册

本版积分规则

8

主题

37

帖子

0

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