[APM32F4]

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

[复制链接]
6698|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 相应函数的简单介绍
_IQN 将输入的浮点数进行IQ格式数转换
_IQtoF 将IQ格式数进行浮点数转换
long _IQmpyI32(A, B) //N*long IQ乘long
long _IQmpyI32int(A, B) //N*long IQ乘long 返回整数部分
long _IQmpyI32frac(A, B)//N*long IQ乘long 返回小数部分
_IQmpy(A, B)            //N*N乘法
_IQrmpy(A, B)           //N*N四舍五入的乘法最后保存结果前(四舍五入)
_IQrsmpy(A, B)          //N*N四舍五入的饱和处理乘法(如果结果超过IQ范围也会限制计算结果值到这个范围)
_IQmpyIQX(A, A1, B, B1) //N1*N2两个不同的Q格式乘法,返回全局Q格式
_IQdiv(A, B)            // N/N iq除法
_IQsin(A)                //正弦值
_IQasin(A)              //反正弦值,输入范围在-Π到Π
_IQsinPU(A)             //正弦函数(标幺值),你占这个圆周的几分之几为单位如果sin((0.25*PI)/(2*PI)),输入范围在0-2Π
_IQcos(A)                //余弦值
_IQacos(A)              //反余弦值,输入范围在-Π到Π
_IQcosPU(A)             //余弦函数(标幺值),输入范围在0-2Π
_IQatan(A)                  //反正切值
_IQatan2(A, B)           //第四象限反正切 tan-1(sin, cos)
_IQatan2PU(A, B)         //第四象限反正切 tan-1(sin, cos)
_IQatan(A, B)           //定点反正切    tan-1(1),,1=sin/cos
_IQNsqrt(A)             //平方根        a^0.5
_IQNisqrt(A)            //平方根倒数    1/a^0.5
_IQNmag(A, B)           //求模运算(sqrt(A^2 + B^2)
_IQsqrt(A)              //平方根        a^0.5
_IQisqrt(A)             //平方根倒数    1/a^0.5
_IQmag(A, B)            //求模运算(sqrt(A^2 + B^2)
_IQsat(A, long P, long N)//IQ数值的限幅函数 把A限制到[N P]之间
_IQNabs(A)              //IQ数据的绝对值    |A|
_IQabs(A)               //IQ数据的绝对值    |A|
_IQmpy2,4,8,16,32,64 //将输入数进行左移操作,即相乘多少倍
_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库函数进行操作,如下图代码
int main(void)
{
        
    /* Init LED */
    APM_MINI_LEDInit(LED2);
    APM_MINI_LEDInit(LED3);
        
    USART_Config_T usartConfigStruct;

    /* USART1 configuration */
    usartConfigStruct.baudRate = 115200;
    usartConfigStruct.hardwareFlow = USART_HARDWARE_FLOW_NONE;
    usartConfigStruct.mode = USART_MODE_TX_RX;
    usartConfigStruct.parity = USART_PARITY_NONE;
    usartConfigStruct.stopBits = USART_STOP_BIT_1;
    usartConfigStruct.wordLength = USART_WORD_LEN_8B;
    APM_MINI_COMInit(COM1, &usartConfigStruct);
        
     _iq X,Y,Z;
     X = _IQ(5);
     Y = _IQ(6);
     Z = _IQmpy(X,Y);
     printf("X = 0x%lX\r\n", X);
     printf("Y = 0x%lX\r\n", Y);
     printf("Z = 0x%lX\r\n", Z);
        
    while (1)
    {
      APM_MINI_LEDToggle(LED2);
      APM_MINI_LEDToggle(LED3);
      Delay(0XFFFFFF);
    }
}
3.输出结果,如下图:
结果输出图.png



其中,IQ函数:
#define _IQ30(A)                ((_iq30)((A) * (1 << 30)))
#define _IQ29(A)                ((_iq29)((A) * (1 << 29)))
#define _IQ28(A)                ((_iq28)((A) * (1 << 28)))
#define _IQ27(A)                ((_iq27)((A) * (1 << 27)))
#define _IQ26(A)                ((_iq26)((A) * (1 << 26)))
#define _IQ25(A)                ((_iq25)((A) * (1 << 25)))
#define _IQ24(A)                ((_iq24)((A) * (1 << 24)))
#define _IQ23(A)                ((_iq23)((A) * (1 << 23)))
#define _IQ22(A)                ((_iq22)((A) * (1 << 22)))
#define _IQ21(A)                ((_iq21)((A) * (1 << 21)))
#define _IQ20(A)                ((_iq20)((A) * (1 << 20)))
#define _IQ19(A)                ((_iq19)((A) * (1 << 19)))
#define _IQ18(A)                ((_iq18)((A) * (1 << 18)))
#define _IQ17(A)                ((_iq17)((A) * (1 << 17)))
#define _IQ16(A)                ((_iq16)((A) * (1 << 16)))
#define _IQ15(A)                ((_iq15)((A) * (1 << 15)))
#define _IQ14(A)                ((_iq14)((A) * (1 << 14)))
#define _IQ13(A)                ((_iq13)((A) * (1 << 13)))
#define _IQ12(A)                ((_iq12)((A) * (1 << 12)))
#define _IQ11(A)                ((_iq11)((A) * (1 << 11)))
#define _IQ10(A)                ((_iq10)((A) * (1 << 10)))
#define _IQ9(A)                 ((_iq9)((A) * (1 << 9)))
#define _IQ8(A)                 ((_iq8)((A) * (1 << 8)))
#define _IQ7(A)                 ((_iq7)((A) * (1 << 7)))
#define _IQ6(A)                 ((_iq6)((A) * (1 << 6)))
#define _IQ5(A)                 ((_iq5)((A) * (1 << 5)))
#define _IQ4(A)                 ((_iq4)((A) * (1 << 4)))
#define _IQ3(A)                 ((_iq3)((A) * (1 << 3)))
#define _IQ2(A)                 ((_iq2)((A) * (1 << 2)))
#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)

使用特权

评论回复
评论
21小跑堂 2023-11-28 10:09 回复TA
感谢分享!奖励500家园币(可在家园币商城兑换物品) 
lzh12a3nf|  楼主 | 2023-11-27 09:39 | 显示全部楼层
修改其中部分文字表述

使用特权

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

本版积分规则

8

主题

35

帖子

0

粉丝